欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

老街腾龙娱乐_17665445111

程序员文章站 2022-05-10 17:39:52
...

www.TL3090.com大家好,本篇文章主要讲的是用Python复现二战德军enigma密码机,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
目录
前言
代码
总结

前言
我们知道,enigma机是德军二战中重要的情报加密机器,其有许多特点。

首先,它是一台加解密一体机

其次,它有排己性,虽然多次输入同一明文可能得到不同的密文,但明文a永远不可能加密为其本身。这样完美掩盖本身明文的性质是由反射板造成的,但也最终在图灵的利用下给了enigma机致命一击。

enigma机先后有多种不同的型号,如3转轮型,5转轮型,5转轮选3转轮型等等。本人对三转轮enigma机进行的程序复现。需要说明的是,由于enigma机的精华部分是转子和反射板,所以代码中也着重复现了这一过程,而对接线板进行了省略。毕竟,enigma机的厉害之处在于其疯狂到近乎变态的做到了几乎“一字一换表”,而接线板只是做简单的字母替换,本身并无新意。

代码
话不多说,直接上代码:(一些使用说明见文末)

  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on Tue Jan 4 09:40:42 2022
  4. @author: burger
  5. """
  6. from numpy import random
  7. import numpy as np
  8. import time
  9. 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'])
  10. #输入一个批次号
  11. num = input('请输入您要使用的enigma机批次号XXX-XXX-XXX(示例:123-456-789)\n')
  12. filename = 'enigma_code_book.txt'
  13. with open(filename) as file_object:
  14. context = file_object.read()
  15. if num in context:
  16. number = context.find(num)
  17. arr_a=context[(number+12):(number+38)] #一号转轮
  18. arr_b=context[(number+39):(number+65)] #二号转轮
  19. arr_c=context[(number+66):(number+92)] #三号转轮
  20. arr_d=context[(number+93):(number+119)] #反射板
  21. else:
  22. arr_a=random.permutation(arr)
  23. arr_b=random.permutation(arr)
  24. arr_c=random.permutation(arr)
  25. arr_d=random.permutation(arr)
  26. with open(filename,'a') as file_object:
  27. str_1='\n'
  28. str_1=str_1+num
  29. str_1+=' '
  30. for i in range(len(arr_a)):
  31. str_1+=arr_a[i]
  32. str_1+=' '
  33. for i in range(len(arr_b)):
  34. str_1+=arr_b[i]
  35. str_1+=' '
  36. for i in range(len(arr_c)):
  37. str_1+=arr_c[i]
  38. str_1+=' '
  39. for i in range(len(arr_d)):
  40. str_1+=arr_d[i]
  41. str_1+=' '
  42. file_object.write(str_1)
  43. zzwz=input('请输入初始转子位置(规范为三个英文字母中间加两个英文逗号)\n eg: a,b,c\n')#zzwz即转子位置
  44. zz_1=list(zzwz)[0]
  45. zz_2=list(zzwz)[2]
  46. zz_3=list(zzwz)[4]
  47. num_zz_1=ord(zz_1)-97
  48. num_zz_2=ord(zz_2)-97
  49. num_zz_3=ord(zz_3)-97
  50. def main():
  51. global num_zz_1
  52. global num_zz_2
  53. global num_zz_3
  54. text=input('请输入加密内容\n')
  55. for n in range(len(text)):
  56. string=list(text)[n]
  57. print(zhuanhuan(string),end='')
  58. num_zz_1+=1
  59. if num_zz_1 == 26:
  60. num_zz_1 = 0
  61. num_zz_2+=1
  62. if num_zz_2 == 26:
  63. num_zz_2=0
  64. num_zz_3+=1
  65. if num_zz_3 == 26:
  66. num_zz_3 = 0
  67. def zhuanhuan(letter):
  68. #a号转轮
  69. #右侧有26个触点
  70. #生成a轮的随机连线方式
  71. a_1_1=False
  72. a_1_2=False
  73. a_1_3=False
  74. a_1_4=False
  75. a_1_5=False
  76. a_1_6=False
  77. a_1_7=False
  78. a_1_8=False
  79. a_1_9=False
  80. a_1_10=False
  81. a_1_11=False
  82. a_1_12=False
  83. a_1_13=False
  84. a_1_14=False
  85. a_1_15=False
  86. a_1_16=False
  87. a_1_17=False
  88. a_1_18=False
  89. a_1_19=False
  90. a_1_20=False
  91. a_1_21=False
  92. a_1_22=False
  93. a_1_23=False
  94. a_1_24=False
  95. a_1_25=False
  96. a_1_26=False
  97. if letter == 'a':
  98. a_1_1 = True
  99. if letter == 'b':
  100. a_1_2 = True
  101. elif letter == 'c':
  102. a_1_3 = True
  103. elif letter == 'd':
  104. a_1_4 = True
  105. elif letter == 'e':
  106. a_1_5 = True
  107. elif letter == 'f':
  108. a_1_6 = True
  109. elif letter == 'g':
  110. a_1_7 = True
  111. elif letter == 'h':
  112. a_1_8 = True
  113. elif letter == 'i':
  114. a_1_9 = True
  115. elif letter == 'j':
  116. a_1_10 = True
  117. elif letter == 'k':
  118. a_1_11 = True
  119. elif letter == 'l':
  120. a_1_12 = True
  121. elif letter == 'm':
  122. a_1_13 = True
  123. elif letter == 'n':
  124. a_1_14 = True
  125. elif letter == 'o':
  126. a_1_15 = True
  127. elif letter == 'p':
  128. a_1_16 = True
  129. elif letter == 'q':
  130. a_1_17 = True
  131. elif letter == 'r':
  132. a_1_18 = True
  133. elif letter == 's':
  134. a_1_19 = True
  135. elif letter == 't':
  136. a_1_20 = True
  137. elif letter == 'u':
  138. a_1_21 = True
  139. elif letter == 'v':
  140. a_1_22 = True
  141. elif letter == 'w':
  142. a_1_23 = True
  143. elif letter == 'x':
  144. a_1_24 = True
  145. elif letter == 'y':
  146. a_1_25 = True
  147. elif letter == 'z':
  148. a_1_26 = True
  149. a_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]
  150. # print(a_1_first)
  151. 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]
  152. for i in range(26):
  153. global num_zz_1
  154. a_1[i]=a_1_first[(num_zz_1-26)+i]
  155. # print(a_1)
  156. #左侧有26个触点
  157. a_2_1=False
  158. a_2_2=False
  159. a_2_3=False
  160. a_2_4=False
  161. a_2_5=False
  162. a_2_6=False
  163. a_2_7=False
  164. a_2_8=False
  165. a_2_9=False
  166. a_2_10=False
  167. a_2_11=False
  168. a_2_12=False
  169. a_2_13=False
  170. a_2_14=False
  171. a_2_15=False
  172. a_2_16=False
  173. a_2_17=False
  174. a_2_18=False
  175. a_2_19=False
  176. a_2_20=False
  177. a_2_21=False
  178. a_2_22=False
  179. a_2_23=False
  180. a_2_24=False
  181. a_2_25=False
  182. a_2_26=False
  183. a_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]
  184. #构建a号转轮左右对应关系
  185. for i in range(26):
  186. a_2[i]=a_1[ord(arr_a[i])-97]
  187. # print(a_2)
  188. #此时,a号转轮建模成功
  189. #b号转轮
  190. #右侧有26个触点
  191. b_1_1=False
  192. b_1_2=False
  193. b_1_3=False
  194. b_1_4=False
  195. b_1_5=False
  196. b_1_6=False
  197. b_1_7=False
  198. b_1_8=False
  199. b_1_9=False
  200. b_1_10=False
  201. b_1_11=False
  202. b_1_12=False
  203. b_1_13=False
  204. b_1_14=False
  205. b_1_15=False
  206. b_1_16=False
  207. b_1_17=False
  208. b_1_18=False
  209. b_1_19=False
  210. b_1_20=False
  211. b_1_21=False
  212. b_1_22=False
  213. b_1_23=False
  214. b_1_24=False
  215. b_1_25=False
  216. b_1_26=False
  217. b_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]
  218. #a轮传给b
  219. for i in range(26):
  220. global num_zz_2
  221. b_1[i]=a_2[((num_zz_2)-26)+i]
  222. # print(b_1)
  223. #左侧有26个触点
  224. b_2_1=False
  225. b_2_2=False
  226. b_2_3=False
  227. b_2_4=False
  228. b_2_5=False
  229. b_2_6=False
  230. b_2_7=False
  231. b_2_8=False
  232. b_2_9=False
  233. b_2_10=False
  234. b_2_11=False
  235. b_2_12=False
  236. b_2_13=False
  237. b_2_14=False
  238. b_2_15=False
  239. b_2_16=False
  240. b_2_17=False
  241. b_2_18=False
  242. b_2_19=False
  243. b_2_20=False
  244. b_2_21=False
  245. b_2_22=False
  246. b_2_23=False
  247. b_2_24=False
  248. b_2_25=False
  249. b_2_26=False
  250. b_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]
  251. #构建b号转轮左右对应关系
  252. for i in range(26):
  253. b_2[i]=b_1[ord(arr_b[i])-97]
  254. # print(b_2)
  255. #此时,b号转轮建模成功
  256. #c号转轮
  257. #右侧有26个触点
  258. c_1_1=False
  259. c_1_2=False
  260. c_1_3=False
  261. c_1_4=False
  262. c_1_5=False
  263. c_1_6=False
  264. c_1_7=False
  265. c_1_8=False
  266. c_1_9=False
  267. c_1_10=False
  268. c_1_11=False
  269. c_1_12=False
  270. c_1_13=False
  271. c_1_14=False
  272. c_1_15=False
  273. c_1_16=False
  274. c_1_17=False
  275. c_1_18=False
  276. c_1_19=False
  277. c_1_20=False
  278. c_1_21=False
  279. c_1_22=False
  280. c_1_23=False
  281. c_1_24=False
  282. c_1_25=False
  283. c_1_26=False
  284. c_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]
  285. #b轮传给c
  286. for i in range(26):
  287. global num_zz_3
  288. c_1[i]=b_2[((num_zz_3)-26)+i]
  289. # print(c_1)
  290. #左侧有26个触点
  291. c_2_1=False
  292. c_2_2=False
  293. c_2_3=False
  294. c_2_4=False
  295. c_2_5=False
  296. c_2_6=False
  297. c_2_7=False
  298. c_2_8=False
  299. c_2_9=False
  300. c_2_10=False
  301. c_2_11=False
  302. c_2_12=False
  303. c_2_13=False
  304. c_2_14=False
  305. c_2_15=False
  306. c_2_16=False
  307. c_2_17=False
  308. c_2_18=False
  309. c_2_19=False
  310. c_2_20=False
  311. c_2_21=False
  312. c_2_22=False
  313. c_2_23=False
  314. c_2_24=False
  315. c_2_25=False
  316. c_2_26=False
  317. c_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]
  318. #构建c号转轮左右对应关系
  319. for i in range(26):
  320. c_2[i]=c_1[ord(arr_c[i])-97]
  321. # print(c_2)
  322. #此时,c号转轮建模成功
  323. #c号转轮反射板
  324. for i in range(0,26,2):
  325. 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]
  326. #反向传播
  327. arr_c_2=[]
  328. arr_b_2=[]
  329. arr_a_2=[]
  330. arr_c_1=[]
  331. arr_b_1=[]
  332. arr_a_1=[]
  333. for i in range(26):
  334. arr_c_2.append(ord(arr_c[i])-97)
  335. arr_b_2.append(ord(arr_b[i])-97)
  336. arr_a_2.append(ord(arr_a[i])-97)
  337. arr_c_0=sorted(arr_c_2)
  338. arr_b_0=sorted(arr_b_2)
  339. arr_a_0=sorted(arr_a_2)
  340. for i in range(26):
  341. arr_c_1.append(arr_c_2.index(arr_c_0[i]))
  342. arr_b_1.append(arr_b_2.index(arr_c_0[i]))
  343. arr_a_1.append(arr_a_2.index(arr_c_0[i]))
  344. #c号转轮反向传播
  345. c_3_1=False
  346. c_3_2=False
  347. c_3_3=False
  348. c_3_4=False
  349. c_3_5=False
  350. c_3_6=False
  351. c_3_7=False
  352. c_3_8=False
  353. c_3_9=False
  354. c_3_10=False
  355. c_3_11=False
  356. c_3_12=False
  357. c_3_13=False
  358. c_3_14=False
  359. c_3_15=False
  360. c_3_16=False
  361. c_3_17=False
  362. c_3_18=False
  363. c_3_19=False
  364. c_3_20=False
  365. c_3_21=False
  366. c_3_22=False
  367. c_3_23=False
  368. c_3_24=False
  369. c_3_25=False
  370. c_3_26=False
  371. c_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]
  372. for i in range(26):
  373. c_3[i]=c_2[arr_c_1[i]]
  374. # print(c_3)
  375. #c轮传给b
  376. b_3_1=False
  377. b_3_2=False
  378. b_3_3=False
  379. b_3_4=False
  380. b_3_5=False
  381. b_3_6=False
  382. b_3_7=False
  383. b_3_8=False
  384. b_3_9=False
  385. b_3_10=False
  386. b_3_11=False
  387. b_3_12=False
  388. b_3_13=False
  389. b_3_14=False
  390. b_3_15=False
  391. b_3_16=False
  392. b_3_17=False
  393. b_3_18=False
  394. b_3_19=False
  395. b_3_20=False
  396. b_3_21=False
  397. b_3_22=False
  398. b_3_23=False
  399. b_3_24=False
  400. b_3_25=False
  401. b_3_26=False
  402. b_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]
  403. for i in range(26):
  404. # global num_zz_3
  405. b_3[i]=c_3[-(num_zz_3)+i]#左侧有26个触点
  406. # print(b_3)
  407. #b号转轮反向传播
  408. b_4_1=False
  409. b_4_2=False
  410. b_4_3=False
  411. b_4_4=False
  412. b_4_5=False
  413. b_4_6=False
  414. b_4_7=False
  415. b_4_8=False
  416. b_4_9=False
  417. b_4_10=False
  418. b_4_11=False
  419. b_4_12=False
  420. b_4_13=False
  421. b_4_14=False
  422. b_4_15=False
  423. b_4_16=False
  424. b_4_17=False
  425. b_4_18=False
  426. b_4_19=False
  427. b_4_20=False
  428. b_4_21=False
  429. b_4_22=False
  430. b_4_23=False
  431. b_4_24=False
  432. b_4_25=False
  433. b_4_26=False
  434. b_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]
  435. for i in range(26):
  436. b_4[i]=b_3[arr_b_1[i]]
  437. # print(b_4)
  438. #b轮传给a
  439. a_3_1=False
  440. a_3_2=False
  441. a_3_3=False
  442. a_3_4=False
  443. a_3_5=False
  444. a_3_6=False
  445. a_3_7=False
  446. a_3_8=False
  447. a_3_9=False
  448. a_3_10=False
  449. a_3_11=False
  450. a_3_12=False
  451. a_3_13=False
  452. a_3_14=False
  453. a_3_15=False
  454. a_3_16=False
  455. a_3_17=False
  456. a_3_18=False
  457. a_3_19=False
  458. a_3_20=False
  459. a_3_21=False
  460. a_3_22=False
  461. a_3_23=False
  462. a_3_24=False
  463. a_3_25=False
  464. a_3_26=False
  465. a_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]
  466. for i in range(26):
  467. # global num_zz_2
  468. a_3[i]=b_4[-(num_zz_2)+i]#左侧有26个触点
  469. # print(a_3)
  470. #a号转轮反向传播
  471. a_4_1=False
  472. a_4_2=False
  473. a_4_3=False
  474. a_4_4=False
  475. a_4_5=False
  476. a_4_6=False
  477. a_4_7=False
  478. a_4_8=False
  479. a_4_9=False
  480. a_4_10=False
  481. a_4_11=False
  482. a_4_12=False
  483. a_4_13=False
  484. a_4_14=False
  485. a_4_15=False
  486. a_4_16=False
  487. a_4_17=False
  488. a_4_18=False
  489. a_4_19=False
  490. a_4_20=False
  491. a_4_21=False
  492. a_4_22=False
  493. a_4_23=False
  494. a_4_24=False
  495. a_4_25=False
  496. a_4_26=False
  497. a_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]
  498. for i in range(26):
  499. a_4[i]=a_3[arr_a_1[i]]
  500. # print(a_4)
  501. #a轮传回
  502. z_3_1=False
  503. z_3_2=False
  504. z_3_3=False
  505. z_3_4=False
  506. z_3_5=False
  507. z_3_6=False
  508. z_3_7=False
  509. z_3_8=False
  510. z_3_9=False
  511. z_3_10=False
  512. z_3_11=False
  513. z_3_12=False
  514. z_3_13=False
  515. z_3_14=False
  516. z_3_15=False
  517. z_3_16=False
  518. z_3_17=False
  519. z_3_18=False
  520. z_3_19=False
  521. z_3_20=False
  522. z_3_21=False
  523. z_3_22=False
  524. z_3_23=False
  525. z_3_24=False
  526. z_3_25=False
  527. z_3_26=False
  528. z_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]
  529. for i in range(26):
  530. # global num_zz_1
  531. z_3[i]=a_4[-(num_zz_1)+i]
  532. # print(z_3)
  533. for i in range(26):
  534. if z_3[i]==True:
  535. return(chr(i+97))
  536. if __name__ == '__main__':
  537. main()

简单解释一下代码,大体思路是用boolean类型的列表来表示每组26个触头的有电无电情况,在复现过程中用到了后来图灵在破解enigma机的时候用到的一种思想:将两个接线情况完全对称的enigma机并排放置。其中对True传递的处理方法和反射板的模拟方法是本人较为满意的地方。

反射过程中,有一个较有意思的东西。上图:
老街腾龙娱乐_17665445111
以四个触点为例,在正向传播时,我们以左面触点为基准,读取右面触点的序号为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密码机的文章就介绍到这了