enigma密码机的python实现

enigma密码机的python实现

按照下面的示意图写了个 enigma密码机,如果之后有空,会把这个整合到我用 rust 写的密码学工具箱里

source

基础工作

首先考虑到数字和字母的映射问题,写下如下代码

1
2
3
4
5
6
7
8
9
10
# fold\en_basic.py
# 通过数字找到对应的字母
def number_to_letter(number, mapping_dict):
# 将数字转换为字符串
number_str = str(number)
# 查找对应的字母
for letter, num in mapping_dict.items():
if num == number_str:
return letter
return None
1
2
3
4
5
6
7
# fold\en_rotate.py
# 初始化字母表和数字表
alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
numbers = [str(i) for i in range(0, 26)]

# 创建映射字典
mapping_dict = dict(zip(alphabet, numbers))

这样,就实现了数字和字母的互相对应

加密

做完基础工作,开始写加密部分,解密部分就是加密的逆过程

首先要清楚 enigma 密码机的原理。每一次输入,快轮都会转一格,当快轮转完一圈,中轮转一格,以此类推,类比时钟的时分秒。

所以首先要写的就是字母的轮换代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# fold\en_rotate.py
import numpy as np
import en_basic
def rotate_function(input_data, num):
"""
旋转数组,将 input_data 右移 num 位
:param input_data: 输入数组(列表或 NumPy 数组)
:param num: 旋转位数
:return: 旋转后的数组
"""
n = len(input_data)
output_data = np.zeros(n, dtype=int) # 预分配数组
for i in range(n):
output_data[i] = input_data[(i + num) % n] # 取模运算实现循环
return list(output_data)

接下来构建加密算法,其中的 L1,R1,L2,R2,L3,R3 可以根据需要自定义,这里的数组是因为已经给了固定值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# fold\en_rotate.py
def encrypt_function(input_data):
L1 = [24,25,26,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23]
R1 = [21,3,15,1,19,10,14,26,20,8,16,7,22,4,11,5,17,9,12,23,18,2,25,6,24,13]

L2 = [26,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25]
R2 = [20,1,6,4,15,3,14,12,23,5,16,2,22,19,11,18,25,24,13,7,10,8,21,9,26,17]

L3 = [26,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25]
R3 = [14,8,18,26,17,20,22,10,3,13,11,4,23,5,24,9,12,25,16,19,6,15,21,2,7,1]
# 字母对应位数
# 当输入字母时,每输入一个快轮加一
# 快轮转一圈后,中轮加一
# 中轮转一圈后,慢轮加一
# 一个轮子之间按数字匹配,不同轮子之间按位数匹配

input_data = input_data.replace(" ", "").upper()
length = len(input_data)
result = ""
quick_num = 1
mid_num = 1

for each_letter in range(length):
# 输入字母
# print("输入字母:",input_data[each_letter])
trans_letter = int(mapping_dict.get(input_data[each_letter]))
# print("输入字母对应数字:",trans_letter,"\n")
num_low_left = L1[trans_letter]

# 输入字母匹配快轮左位
# print("输入字母匹配快轮左位:")
# print("快左-值",num_low_left)
# print("快左-位",L1.index(num_low_left),"\n")
# 快轮左位匹配快轮右位
num_low_right = num_low_left
# print("快轮左位匹配快轮右位:")
# print("快右-值",num_low_right)
# print("快右-位",R1.index(num_low_right),"\n")

# 快轮右位匹配中轮左位
# print("快轮右位匹配中轮左位:")
pos_mid_left = R1.index(num_low_right)
# print("中左-值",L2[pos_mid_left])
# print("中左-位",pos_mid_left,"\n")
# 中轮左位匹配中轮右位
num_mid_right = L2[pos_mid_left]
# print("中轮左位匹配中轮右位:")
# print("中右-值",num_mid_right)
# print("中右-位",R2.index(num_mid_right),"\n")

# 中轮右位匹配慢轮左位
# print("中轮右位匹配慢轮左位:")
pos_high_left = R2.index(num_mid_right)
# print("慢左-值",L3[pos_high_left])
# print("慢左-位",pos_high_left,"\n")
# 慢轮左位匹配慢轮右位
num_high_right = L3[pos_high_left]
# print("慢轮左位匹配慢轮右位:")
# print("慢右-值",num_high_right)
# print("慢右-位",R3.index(num_high_right),"\n")

# 慢轮右位匹配输出位
# print("慢轮右位匹配输出位:")
output_letter = en_basic.number_to_letter(R3.index(num_high_right), mapping_dict)
# print("输出位-值",output_letter)
result += output_letter

# 轮子转动
L3 = rotate_function(L3, 1)
# print(L3)
R3 = rotate_function(R3, 1)
# print(R3,"\n")
quick_num = quick_num + 1
if quick_num > 26:
quick_num = 1
L2 = rotate_function(L2, 1)
# print(L2)
R2 = rotate_function(R2, 1)
# print(R2)
mid_num = mid_num + 1
if mid_num > 26:
L1 = rotate_function(L1, 1)
# print(L1)
R1 = rotate_function(R1, 1)
# print(R1)
mid_num = 1
return result,L1,R1,L2,R2,L3,R3

解密

解密算法就是加密算法的逆过程,但要注意这里的转轮算法要写在前面,因为在加密算法中写在了最后面,解密的时候应该先回滚一格快轮才是真正结束的地方

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# fold\en_rotate.py
def decrypt_function(input_data,L1,R1,L2,R2,L3,R3):
input_data = input_data.replace(" ", "").upper()
length = len(input_data)
result = ""

for each_letter in range(length):

# 轮子逆向旋转
L3 = rotate_function(L3, -1)
# print("逆向旋转:",L3)
R3 = rotate_function(R3, -1)
# print(R3,"\n")
if R3[1]==14:
L2 = rotate_function(L2, -1)
# print(L2)
R2 = rotate_function(R2, -1)
# print(R2)
if R2[1]==20:
L1 = rotate_function(L1, -1)
# print(L1)
R1 = rotate_function(R1, -1)
# print(R1)

# 输入加密字母
# print("输入加密字母:", input_data[each_letter])
trans_letter = int(mapping_dict.get(input_data[each_letter]))

# 输入字母
# print("输入字母:",input_data[each_letter])
trans_letter = int(mapping_dict.get(input_data[each_letter]))
# print("输入字母对应数字:",trans_letter,"\n")
pos_low_left = L1[trans_letter]

# 慢轮右位匹配慢轮左位
pos_high_right = trans_letter
# print("慢轮右位匹配慢轮左位:")
# print("慢右-值", R3[pos_high_right])
pos_high_left = L3.index(R3[pos_high_right])
# print("慢左-位", pos_high_left,"\n")

# 中轮右位匹配中轮左位
pos_mid_right = pos_high_left
# print("中轮右位匹配中轮左位:")
# print("中右-值", R2[pos_mid_right])
pos_mid_left = L2.index(R2[pos_mid_right])
# print("中左-位", pos_mid_left,"\n")

# 快轮右位匹配快轮左位(逆向)
pos_low_right = pos_mid_left
# print("快轮右位匹配快轮左位:")
# print("快右-值", R1[pos_low_right])
pos_low_left = L1.index(R1[pos_low_right])
# print("快左-位", pos_low_left,"\n")

# 快轮左位匹配输出位
# print("快轮左位匹配输出位:")
pos_output = L1.index(L1[pos_low_left])
output_letter = en_basic.number_to_letter(pos_output, mapping_dict)
# print("输出位-值",output_letter,"\n")
result += output_letter

return result

输出

简单的调用一下写好的函数就行。注意一点,加密后的内容需要倒置放入解密机里,解密后再次倒置就是明文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# fole\enigma_use
import en_rotate

str = "the state key laboratory of networking and switching technology belongs to beijing university of posts and telecommunication the laboratory was opened in nineteen ninety two in nineteen ninety five the laboratory passed acceptance inspection by government and an evaluation organized by ministry of science and technology in two thousand and two since two thousand and four the laboratory has been renamed as the state key laboratory of networking and switching technology by ministry of science and technology"
#str = "abc"

result,L1,R1,L2,R2,L3,R3 = en_rotate.encrypt_function(str)

print("Encrypted text:", result,"\n")

rev_result = result[::-1]

re = en_rotate.decrypt_function(rev_result,L1,R1,L2,R2,L3,R3)
re_final = re[::-1]

print("Decrypted text:", re_final)

enigma密码机的python实现
http://example.com/2025/03/06/enigma密码机的python实现/
作者
Tsglz
发布于
2025年3月6日
许可协议