IDEA加解密基础实现

IDEA加解密基础实现

第3章 分组密码.ppt 下载

idea加密过程非常很清晰,码字人表示很喜欢,就是解密有点折腾。

解密是在加密的K上进行变动的,按理说可以直接由k序列生成de_k,我懒。

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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
Message = "1010101011100110010101010000111111001100001100111001100101100110"  # 64
Key = "00000000111111110000000011111111111111110000111111110000111111110000111111110000111111110000000000001111111111111111000000001111" # 128
ADDMOD = 65536 # 加法模
MULMOD = 65537 # 乘法模


def bin2dec(bin):
"""二进制转十进制,输入二进制位数应该为16位"""
return int(bin, 2)


def int2bin(Int):
"""二进制转十进制输出二进制位数应该为16位"""
return bin(Int)[2:].zfill(16)


def xor(bit1, bit2):
"""异或运算 输入参数str16"""
xor_result = ['' for i in range(len(bit1))]
for i in range(len(bit1)):
xor_result[i] = str(int(bit1[i]) ^ int(bit2[i]))
return ''.join(xor_result)


def addmod(bit1, bit2):
"""加模运算16位 输入参数str16 str16"""
return int2bin((bin2dec(bit1) + bin2dec(bit2)) % ADDMOD)


def mulmod(bit1, bit2):
"""乘模运算16位 输入参数str16 str16"""
if bin2dec(bit1) == 0:
bit1 = int2bin(ADDMOD)
if bin2dec(bit2) == 0:
bit2 = int2bin(ADDMOD)
result = ((bin2dec(bit1) * bin2dec(bit2)) % MULMOD) % ADDMOD
return int2bin(result) if result != mulmod else int2bin(0)


def get_X(x):
"""将输入的64位 分解压缩成16*4 返回{X[3][16]"""
X = []
for i in range(0, len(x), 16):
X.append(x[i:i + 16])
return X


def left_move(key):
"""循环左移"""
return key[25:] + key[:25]


def get_Z(key):
"""获取Z1-Z52 返回{Z[0][6]-Z[7][6]} + Z[8][4]"""
num, z_all, Z = 0, [], [] # z_all未进行6,6,6...4分类的Z列表;Z进行6,6,6...4分类的Z列表
for time in range(8):
if (num >= 51):
break
for i in range(0, 128, 16):
z_all.append(Key[i:(i + 16)])
if (num >= 51):
break
num += 1
key = left_move(key)
for i in range(0, len(z_all), 6): # z为52位
Z.append(z_all[i:(i + 6)])
return Z


def one_circle(x, z):
"""一轮的算法,输入X[3],Z[5],返回{W[0]-W[3]} result的值每部计算从左往右,从上到下命名"""
result = ['' for i in range(14)]
result[0] = mulmod(x[0], z[0])
result[1] = addmod(x[2], z[2])
result[2] = addmod(x[1], z[1])
result[3] = mulmod(x[3], z[3])
result[4] = xor(result[0], result[1])
result[5] = xor(result[2], result[3])
result[6] = mulmod(result[4], z[4])
result[7] = addmod(result[5], result[6])
result[8] = mulmod(result[7], z[5])
result[9] = addmod(result[8], result[6])
result[10] = xor(result[0], result[8])
result[11] = xor(result[9], result[3])
result[12] = xor(result[2], result[9])
result[13] = xor(result[8], result[1])
return result[10], result[13], result[12], result[11]


def last_circle(w, z):
"""最后一轮"""
return mulmod(w[0], z[0]), addmod(w[2], z[1]), addmod(w[1], z[2]), mulmod(w[3], z[3])


def encode(message, key):
"""加密"""
Z = get_Z(key)
X = get_X(message)
for i in range(8):
X = one_circle(X, Z[i])
# if i == 0 or i == 1:
# print("第一轮和第二轮的值为", X) # 作业
return "".join(last_circle(X, Z[8]))

print("原文",Message)
secret = encode(Message, Key)
print("加密结果为:", secret)


def get_niyuan_mul(a):
a = bin2dec(a)
niyuan = 1
while (a * niyuan) % MULMOD != 1:
niyuan += 1
return int2bin(niyuan)


def get_niyuan_add(a):
return int2bin(ADDMOD - bin2dec(a))


def get_de_Z(key):
"""获取Z1-Z52 返回{Z[0][6]-Z[7][6]} + Z[8][4]"""
num, z_all, Z = 0, [], [] # z_all未进行6,6,6...4分类的Z列表;Z进行6,6,6...4分类的Z列表
for time in range(8):
if (num >= 51):
break
for i in range(0, 128, 16):
z_all.append(Key[i:(i + 16)])
if (num >= 51):
break
num += 1
key = left_move(key)
# print(z_all)
# 解密过程中的变换
z=z_all[:] # 深拷贝
for i in range(0, len(z_all), 6):
z_all[i] = get_niyuan_mul(z[48 - i])
z_all[1], z_all[49] = get_niyuan_add(z[49]), get_niyuan_add(z[1])
z_all[2], z_all[50] = get_niyuan_add(z[50]), get_niyuan_add(z[2])
for i in range(7, 45, 6):
z_all[i], z_all[i + 1], z_all[50 - i], z_all[50 - i + 1] = get_niyuan_add(z[50 - i + 1]), get_niyuan_add(
z[50 - i]), get_niyuan_add(z[i+1]), get_niyuan_add(z[i])
# 7 8 43 44 = 44 43 8 7
for i in range(3, len(z_all), 6):
z_all[i] = get_niyuan_mul(z[54 - i])
for i in range(4, len(z_all), 6):
z_all[i] = z[50 - i]
for i in range(5, len(z_all), 6):
z_all[i] = z[52 - i]
for i in range(0, len(z_all), 6): # z为52位
Z.append(z_all[i:(i + 6)])
# print(Z)
return Z


def decode(message, key):
"""加密"""
Z = get_de_Z(key)
X = get_X(secret)
for i in range(8):
X = one_circle(X, Z[i])
# if i == 0 or i == 1:
# print("第一轮和第二轮的值为", X) # 作业
return "".join(last_circle(X, Z[8]))


print("解密结果为", decode(secret,Key))