用Python复现二战德军enigma密码机
目录
- 前言
- 代码
- 总结
前言 我们知道,enigma机是德军二战中重要的情报加密机器,其有许多特点。
首先,它是一台加解密一体机
其次,它有排己性,虽然多次输入同一明文可能得到不同的密文,但明文a永远不可能加密为其本身。这样完美掩盖本身明文的性质是由反射板造成的,但也最终在图灵的利用下给了enigma机致命一击。
enigma机先后有多种不同的型号,如3转轮型,5转轮型,5转轮选3转轮型等等。本人对三转轮enigma机进行的程序复现。需要说明的是,由于enigma机的精华部分是转子和反射板,所以代码中也着重复现了这一过程,而对接线板进行了省略。毕竟,enigma机的厉害之处在于其疯狂到近乎变态的做到了几乎“一字一换表”,而接线板只是做简单的字母替换,本身并无新意。
代码 话不多说,直接上代码:(一些使用说明见文末)
# -*- coding: utf-8 -*-"""Created on Tue Jan4 09:40:42 2022@author: burger""" from numpy import randomimport numpy as npimport time arr = np.array(['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']) #输入一个批次号num = input('请输入您要使用的enigma机批次号XXX-XXX-XXX(示例:123-456-789)\n')filename = 'enigma_code_book.txt'with open(filename) as file_object:context = file_object.read()if num in context:number = context.find(num)arr_a=context[(number+12):(number+38)]#一号转轮arr_b=context[(number+39):(number+65)]#二号转轮arr_c=context[(number+66):(number+92)]#三号转轮arr_d=context[(number+93):(number+119)]#反射板 else:arr_a=random.permutation(arr)arr_b=random.permutation(arr)arr_c=random.permutation(arr)arr_d=random.permutation(arr)with open(filename,'a') as file_object:str_1='\n'str_1=str_1+numstr_1+=' 'for i in range(len(arr_a)):str_1+=arr_a[i]str_1+=' 'for i in range(len(arr_b)):str_1+=arr_b[i]str_1+=' 'for i in range(len(arr_c)):str_1+=arr_c[i]str_1+=' 'for i in range(len(arr_d)):str_1+=arr_d[i]str_1+=' 'file_object.write(str_1)zzwz=input('请输入初始转子位置(规范为三个英文字母中间加两个英文逗号)\n eg: a,b,c\n')#zzwz即转子位置zz_1=list(zzwz)[0]zz_2=list(zzwz)[2]zz_3=list(zzwz)[4]num_zz_1=ord(zz_1)-97num_zz_2=ord(zz_2)-97num_zz_3=ord(zz_3)-97 def main():global num_zz_1global num_zz_2global num_zz_3text=input('请输入加密内容\n')for n in range(len(text)):string=list(text)[n]print(zhuanhuan(string),end='')num_zz_1+=1if num_zz_1 == 26:num_zz_1 = 0num_zz_2+=1if num_zz_2 == 26:num_zz_2=0num_zz_3+=1if num_zz_3 == 26:num_zz_3 = 0def zhuanhuan(letter):#a号转轮#右侧有26个触点#生成a轮的随机连线方式 a_1_1=Falsea_1_2=Falsea_1_3=Falsea_1_4=Falsea_1_5=Falsea_1_6=Falsea_1_7=Falsea_1_8=Falsea_1_9=Falsea_1_10=Falsea_1_11=Falsea_1_12=Falsea_1_13=Falsea_1_14=Falsea_1_15=Falsea_1_16=Falsea_1_17=Falsea_1_18=Falsea_1_19=Falsea_1_20=Falsea_1_21=Falsea_1_22=Falsea_1_23=Falsea_1_24=Falsea_1_25=Falsea_1_26=Falseif letter == 'a':a_1_1 = Trueif letter == 'b':a_1_2 = Trueelif letter == 'c':a_1_3 = Trueelif letter == 'd':a_1_4 = Trueelif letter == 'e':a_1_5 = Trueelif letter == 'f':a_1_6 = Trueelif letter == 'g':a_1_7 = Trueelif letter == 'h':a_1_8 = Trueelif letter == 'i':a_1_9 = Trueelif letter == 'j':a_1_10 = Trueelif letter == 'k':a_1_11 = Trueelif letter == 'l':a_1_12 = Trueelif letter == 'm':a_1_13 = Trueelif letter == 'n':a_1_14 = Trueelif letter == 'o':a_1_15 = Trueelif letter == 'p':a_1_16 = Trueelif letter == 'q':a_1_17 = Trueelif letter == 'r':a_1_18 = Trueelif letter == 's':a_1_19 = Trueelif letter == 't':a_1_20 = Trueelif letter == 'u':a_1_21 = Trueelif letter == 'v':a_1_22 = Trueelif letter == 'w':a_1_23 = Trueelif letter == 'x':a_1_24 = Trueelif letter == 'y':a_1_25 = Trueelif letter == 'z':a_1_26 = Truea_1_first=[a_1_1,a_1_2,a_1_3,a_1_4,a_1_5,a_1_6,a_1_7,a_1_8,a_1_9,a_1_10,a_1_11,a_1_12,a_1_13,a_1_14,a_1_15,a_1_16,a_1_17,a_1_18,a_1_19,a_1_20,a_1_21,a_1_22,a_1_23,a_1_24,a_1_25,a_1_26]#print(a_1_first)a_1=[False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False]for i in range(26):global num_zz_1a_1[i]=a_1_first[(num_zz_1-26)+i]#print(a_1)#左侧有26个触点a_2_1=Falsea_2_2=Falsea_2_3=Falsea_2_4=Falsea_2_5=Falsea_2_6=Falsea_2_7=Falsea_2_8=Falsea_2_9=Falsea_2_10=Falsea_2_11=Falsea_2_12=Falsea_2_13=Falsea_2_14=Falsea_2_15=Falsea_2_16=Falsea_2_17=Falsea_2_18=Falsea_2_19=Falsea_2_20=Falsea_2_21=Falsea_2_22=Falsea_2_23=Falsea_2_24=Falsea_2_25=Falsea_2_26=Falsea_2=[a_2_1,a_2_2,a_2_3,a_2_4,a_2_5,a_2_6,a_2_7,a_2_8,a_2_9,a_2_10,a_2_11,a_2_12,a_2_13,a_2_14,a_2_15,a_2_16,a_2_17,a_2_18,a_2_19,a_2_20,a_2_21,a_2_22,a_2_23,a_2_24,a_2_25,a_2_26]#构建a号转轮左右对应关系for i in range(26):a_2[i]=a_1[ord(arr_a[i])-97]#print(a_2)#此时,a号转轮建模成功#b号转轮#右侧有26个触点b_1_1=Falseb_1_2=Falseb_1_3=Falseb_1_4=Falseb_1_5=Falseb_1_6=Falseb_1_7=Falseb_1_8=Falseb_1_9=Falseb_1_10=Falseb_1_11=Falseb_1_12=Falseb_1_13=Falseb_1_14=Falseb_1_15=Falseb_1_16=Falseb_1_17=Falseb_1_18=Falseb_1_19=Falseb_1_20=Falseb_1_21=Falseb_1_22=Falseb_1_23=Falseb_1_24=Falseb_1_25=Falseb_1_26=Falseb_1=[b_1_1,b_1_2,b_1_3,b_1_4,b_1_5,b_1_6,b_1_7,b_1_8,b_1_9,b_1_10,b_1_11,b_1_12,b_1_13,b_1_14,b_1_15,b_1_16,b_1_17,b_1_18,b_1_19,b_1_20,b_1_21,b_1_22,b_1_23,b_1_24,b_1_25,b_1_26]#a轮传给b轮for i in range(26):global num_zz_2b_1[i]=a_2[((num_zz_2)-26)+i]#print(b_1)#左侧有26个触点b_2_1=Falseb_2_2=Falseb_2_3=Falseb_2_4=Falseb_2_5=Falseb_2_6=Falseb_2_7=Falseb_2_8=Falseb_2_9=Falseb_2_10=Falseb_2_11=Falseb_2_12=Falseb_2_13=Falseb_2_14=Falseb_2_15=Falseb_2_16=Falseb_2_17=Falseb_2_18=Falseb_2_19=Falseb_2_20=Falseb_2_21=Falseb_2_22=Falseb_2_23=Falseb_2_24=Falseb_2_25=Falseb_2_26=Falseb_2=[b_2_1,b_2_2,b_2_3,b_2_4,b_2_5,b_2_6,b_2_7,b_2_8,b_2_9,b_2_10,b_2_11,b_2_12,b_2_13,b_2_14,b_2_15,b_2_16,b_2_17,b_2_18,b_2_19,b_2_20,b_2_21,b_2_22,b_2_23,b_2_24,b_2_25,b_2_26]#构建b号转轮左右对应关系for i in range(26):b_2[i]=b_1[ord(arr_b[i])-97]#print(b_2)#此时,b号转轮建模成功 #c号转轮#右侧有26个触点c_1_1=Falsec_1_2=Falsec_1_3=Falsec_1_4=Falsec_1_5=Falsec_1_6=Falsec_1_7=Falsec_1_8=Falsec_1_9=Falsec_1_10=Falsec_1_11=Falsec_1_12=Falsec_1_13=Falsec_1_14=Falsec_1_15=Falsec_1_16=Falsec_1_17=Falsec_1_18=Falsec_1_19=Falsec_1_20=Falsec_1_21=Falsec_1_22=Falsec_1_23=Falsec_1_24=Falsec_1_25=Falsec_1_26=Falsec_1=[c_1_1,c_1_2,c_1_3,c_1_4,c_1_5,c_1_6,c_1_7,c_1_8,c_1_9,c_1_10,c_1_11,c_1_12,c_1_13,c_1_14,c_1_15,c_1_16,c_1_17,c_1_18,c_1_19,c_1_20,c_1_21,c_1_22,c_1_23,c_1_24,c_1_25,c_1_26]#b轮传给c轮for i in range(26):global num_zz_3c_1[i]=b_2[((num_zz_3)-26)+i]#print(c_1)#左侧有26个触点c_2_1=Falsec_2_2=Falsec_2_3=Falsec_2_4=Falsec_2_5=Falsec_2_6=Falsec_2_7=Falsec_2_8=Falsec_2_9=Falsec_2_10=Falsec_2_11=Falsec_2_12=Falsec_2_13=Falsec_2_14=Falsec_2_15=Falsec_2_16=Falsec_2_17=Falsec_2_18=Falsec_2_19=Falsec_2_20=Falsec_2_21=Falsec_2_22=Falsec_2_23=Falsec_2_24=Falsec_2_25=Falsec_2_26=Falsec_2=[c_2_1,c_2_2,c_2_3,c_2_4,c_2_5,c_2_6,c_2_7,c_2_8,c_2_9,c_2_10,c_2_11,c_2_12,c_2_13,c_2_14,c_2_15,c_2_16,c_2_17,c_2_18,c_2_19,c_2_20,c_2_21,c_2_22,c_2_23,c_2_24,c_2_25,c_2_26]#构建c号转轮左右对应关系for i in range(26):c_2[i]=c_1[ord(arr_c[i])-97]#print(c_2)#此时,c号转轮建模成功 #c号转轮反射板 for i in range(0,26,2):c_2[ord(arr_d[i])-97],c_2[ord(arr_d[i+1])-97]=c_2[ord(arr_d[i+1])-97],c_2[ord(arr_d[i])-97]#反向传播arr_c_2=[]arr_b_2=[]arr_a_2=[]arr_c_1=[]arr_b_1=[]arr_a_1=[] for i in range(26):arr_c_2.append(ord(arr_c[i])-97)arr_b_2.append(ord(arr_b[i])-97)arr_a_2.append(ord(arr_a[i])-97)arr_c_0=sorted(arr_c_2)arr_b_0=sorted(arr_b_2)arr_a_0=sorted(arr_a_2)for i in range(26):arr_c_1.append(arr_c_2.index(arr_c_0[i]))arr_b_1.append(arr_b_2.index(arr_c_0[i]))arr_a_1.append(arr_a_2.index(arr_c_0[i]))#c号转轮反向传播c_3_1=Falsec_3_2=Falsec_3_3=Falsec_3_4=Falsec_3_5=Falsec_3_6=Falsec_3_7=Falsec_3_8=Falsec_3_9=Falsec_3_10=Falsec_3_11=Falsec_3_12=Falsec_3_13=Falsec_3_14=Falsec_3_15=Falsec_3_16=Falsec_3_17=Falsec_3_18=Falsec_3_19=Falsec_3_20=Falsec_3_21=Falsec_3_22=Falsec_3_23=Falsec_3_24=Falsec_3_25=Falsec_3_26=Falsec_3=[c_3_1,c_3_2,c_3_3,c_3_4,c_3_5,c_3_6,c_3_7,c_3_8,c_3_9,c_3_10,c_3_11,c_3_12,c_3_13,c_3_14,c_3_15,c_3_16,c_3_17,c_3_18,c_3_19,c_3_20,c_3_21,c_3_22,c_3_23,c_3_24,c_3_25,c_3_26]for i in range(26):c_3[i]=c_2[arr_c_1[i]]#print(c_3)#c轮传给b轮b_3_1=Falseb_3_2=Falseb_3_3=Falseb_3_4=Falseb_3_5=Falseb_3_6=Falseb_3_7=Falseb_3_8=Falseb_3_9=Falseb_3_10=Falseb_3_11=Falseb_3_12=Falseb_3_13=Falseb_3_14=Falseb_3_15=Falseb_3_16=Falseb_3_17=Falseb_3_18=Falseb_3_19=Falseb_3_20=Falseb_3_21=Falseb_3_22=Falseb_3_23=Falseb_3_24=Falseb_3_25=Falseb_3_26=Falseb_3=[b_3_1,b_3_2,b_3_3,b_3_4,b_3_5,b_3_6,b_3_7,b_3_8,b_3_9,b_3_10,b_3_11,b_3_12,b_3_13,b_3_14,b_3_15,b_3_16,b_3_17,b_3_18,b_3_19,b_3_20,b_3_21,b_3_22,b_3_23,b_3_24,b_3_25,b_3_26]for i in range(26):#global num_zz_3b_3[i]=c_3[-(num_zz_3)+i]#左侧有26个触点 #print(b_3)#b号转轮反向传播b_4_1=Falseb_4_2=Falseb_4_3=Falseb_4_4=Falseb_4_5=Falseb_4_6=Falseb_4_7=Falseb_4_8=Falseb_4_9=Falseb_4_10=Falseb_4_11=Falseb_4_12=Falseb_4_13=Falseb_4_14=Falseb_4_15=Falseb_4_16=Falseb_4_17=Falseb_4_18=Falseb_4_19=Falseb_4_20=Falseb_4_21=Falseb_4_22=Falseb_4_23=Falseb_4_24=Falseb_4_25=Falseb_4_26=Falseb_4=[b_4_1,b_4_2,b_4_3,b_4_4,b_4_5,b_4_6,b_4_7,b_4_8,b_4_9,b_4_10,b_4_11,b_4_12,b_4_13,b_4_14,b_4_15,b_4_16,b_4_17,b_4_18,b_4_19,b_4_20,b_4_21,b_4_22,b_4_23,b_4_24,b_4_25,b_4_26]for i in range(26):b_4[i]=b_3[arr_b_1[i]]#print(b_4)#b轮传给a轮a_3_1=Falsea_3_2=Falsea_3_3=Falsea_3_4=Falsea_3_5=Falsea_3_6=Falsea_3_7=Falsea_3_8=Falsea_3_9=Falsea_3_10=Falsea_3_11=Falsea_3_12=Falsea_3_13=Falsea_3_14=Falsea_3_15=Falsea_3_16=Falsea_3_17=Falsea_3_18=Falsea_3_19=Falsea_3_20=Falsea_3_21=Falsea_3_22=Falsea_3_23=Falsea_3_24=Falsea_3_25=Falsea_3_26=Falsea_3=[a_3_1,a_3_2,a_3_3,a_3_4,a_3_5,a_3_6,a_3_7,a_3_8,a_3_9,a_3_10,a_3_11,a_3_12,a_3_13,a_3_14,a_3_15,a_3_16,a_3_17,a_3_18,a_3_19,a_3_20,a_3_21,a_3_22,a_3_23,a_3_24,a_3_25,a_3_26]for i in range(26):#global num_zz_2a_3[i]=b_4[-(num_zz_2)+i]#左侧有26个触点 #print(a_3)#a号转轮反向传播a_4_1=Falsea_4_2=Falsea_4_3=Falsea_4_4=Falsea_4_5=Falsea_4_6=Falsea_4_7=Falsea_4_8=Falsea_4_9=Falsea_4_10=Falsea_4_11=Falsea_4_12=Falsea_4_13=Falsea_4_14=Falsea_4_15=Falsea_4_16=Falsea_4_17=Falsea_4_18=Falsea_4_19=Falsea_4_20=Falsea_4_21=Falsea_4_22=Falsea_4_23=Falsea_4_24=Falsea_4_25=Falsea_4_26=Falsea_4=[a_4_1,a_4_2,a_4_3,a_4_4,a_4_5,a_4_6,a_4_7,a_4_8,a_4_9,a_4_10,a_4_11,a_4_12,a_4_13,a_4_14,a_4_15,a_4_16,a_4_17,a_4_18,a_4_19,a_4_20,a_4_21,a_4_22,a_4_23,a_4_24,a_4_25,a_4_26]for i in range(26):a_4[i]=a_3[arr_a_1[i]]#print(a_4)#a轮传回z_3_1=Falsez_3_2=Falsez_3_3=Falsez_3_4=Falsez_3_5=Falsez_3_6=Falsez_3_7=Falsez_3_8=Falsez_3_9=Falsez_3_10=Falsez_3_11=Falsez_3_12=Falsez_3_13=Falsez_3_14=Falsez_3_15=Falsez_3_16=Falsez_3_17=Falsez_3_18=Falsez_3_19=Falsez_3_20=Falsez_3_21=Falsez_3_22=Falsez_3_23=Falsez_3_24=Falsez_3_25=Falsez_3_26=Falsez_3=[z_3_1,z_3_2,z_3_3,z_3_4,z_3_5,z_3_6,z_3_7,z_3_8,z_3_9,z_3_10,z_3_11,z_3_12,z_3_13,z_3_14,z_3_15,z_3_16,z_3_17,z_3_18,z_3_19,z_3_20,z_3_21,z_3_22,z_3_23,z_3_24,z_3_25,z_3_26]for i in range(26):#global num_zz_1z_3[i]=a_4[-(num_zz_1)+i]#print(z_3)for i in range(26):if z_3[i]==True:return(chr(i+97))if __name__ == '__main__':main()
【用Python复现二战德军enigma密码机】 简单解释一下代码,大体思路是用boolean类型的列表来表示每组26个触头的有电无电情况,在复现过程中用到了后来图灵在破解enigma机的时候用到的一种思想:将两个接线情况完全对称的enigma机并排放置。其中对True传递的处理方法和反射板的模拟方法是本人较为满意的地方。
反射过程中,有一个较有意思的东西。上图:
文章图片
以四个触点为例,在正向传播时,我们以左面触点为基准,读取右面触点的序号为3 4 1 2,在反向传播时,我们以右面触点为基准,读取左面触点序号为2 4 1 3。如何根据3412来构建出2413是一个关键。笔者的一个朋友提供了一个很好的思路。假设3412储存在列表A中,对列表A进行从小到大的排序,储存在列表B中。将列表B中每一个元素在列表A中的下标记录到列表C中,列表C即为我们所求。
之后仿照正向传播,进行反向传播即可。
说一下代码的使用方法吧,在源码同一目录下建立一个名为enigma_code_book.txt文件,用于粗存enigma机型号,三个转轮和一个反射板的接线方式。
点击运行代码,随便输入由3组分别3个阿拉伯数字组成的enigma机批次号,如:123-456-789,点回车。此时程序会自动生成该批次号enigma机的接线方法。如果曾经使用过该批次enigma机,则在enigma_code_book中自动找到所需的接线方式。
再输入初始转轮位置,要求为三个小写英文字母,中间由逗号隔开,如:a,b,c。回车,再输入所需加密的明文内容,回车,即可生成密文。
如果想进行解密,则要求输入同一批次号,同一初始转子位置,输入密文,则可解密出明文。
需要注意的是,这里仿照历史中enigma机,只做了26个小写英文字母的加密,而没有数字,大写英文字母以及标点符号等的加密。因为这些只是在其基础上根据应用需求不同做的一些添砖加瓦的工作。笔者也同时考虑到,如果想加密汉语,可以首先将enigma机扩充进大写字母和阿拉伯数字,再结合base64的值即可。
总结 到此这篇关于用Python复现二战德军enigma密码机的文章就介绍到这了,更多相关Python enigma密码机内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- python进阶之魔术方法详解
- Python实现批量梯度下降法(BGD)拟合曲线
- 鸿蒙OS如何开发一个前端应用详解
- 企业需要使用网络损伤仪|企业需要使用网络损伤仪 WANsim 的帮助,以便更高效地迁移到云端
- React|React开发App中使用百度地图
- 如何用CSS实现左侧宽度固定,右侧自适应(两栏布局)(左右固定中间自适应(三栏布局)呢?)
- 数据分析在生活中的应用- 女人的衣柜里为什么总是少一件衣服
- python|人工智能初识
- 如何在Vue中使用protobuf
- 利用|利用 onnxruntime 库同时推理多个模型的效率研究