帮人写的代码,应该是经典结构。
输入明文 X X X和密钥 K K K后,输出加密后的结果,以及每轮的 L 、 R 、 K L、R、K L、R、K。
代码标注了每个函数的用作,可放心食用。
code:
import copy
class DES:
# 定义初始置换IP
IP = [
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7
]
# 定义逆置换IP-1
IP_1 = [
40, 8, 48, 16, 56, 24, 64, 32,
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25
]
# S-Box
S_BOXES = [
# S1
[[14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7],
[0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8],
[4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0],
[15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13]],
# S2
[[15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10],
[3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5],
[0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15],
[13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9]],
# S3
[[10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8],
[13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1],
[13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7],
[1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12]],
# S4
[[7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15],
[12, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9],
[10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4],
[3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14]],
# S5
[[2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9],
[14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6],
[4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14],
[11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3]],
# S6
[[12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11],
[10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8],
[9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6],
[4, 11, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13]],
# S7
[[4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1],
[13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6],
[1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2],
[6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12]],
# S8
[[13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7],
[1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2],
[7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8],
[2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11]]
]
# P-置换
P = [
16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
5, 18, 31, 10,
2, 8, 24, 14,
32, 27, 3, 9,
19, 13, 30, 6,
22, 11, 4, 25
]
PC1 = [
57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15,
7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 4
]
PC2 = [
14, 17, 11, 24, 1, 5,
3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55,
30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32
]
E = [
32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13,
12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21,
20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29,
28, 29, 30, 31, 32, 1
]
def __init__(self, X, K):
"""
:param X: 2进制明文 list
:param K: 2进制密钥 list
"""
self.X = X
self.K = K
self.k_list = []
self.c_list = []
self.d_list = []
self.l_list = []
self.r_list = []
self.init_K()
self.init_P()
# 结果
self.C = self.substitution(self.r_list[-1] + self.l_list[-1], self.IP_1)
def substitution(self, s, p):
"""
置换
:param s: 需要置换的序列,list
:param p: 置换规则,list
:return: s 根据 p 置换后的结果,list
"""
if len(s) < max(p) - 1:
raise IndexError('max(p) > len(s)')
res = [s[i - 1] for i in p]
return res
def init_K(self):
"""
得到每一轮的 K
:return: None
"""
k0 = self.substitution(self.K, self.PC1)
self.c_list.append(k0[0:28])
self.d_list.append(k0[28:56])
self.k_list.append(self.substitution(k0, self.PC2))
for i in range(1, 17):
c, d = [], []
if i in [1, 2, 9, 16]:
c = self.c_list[i - 1][1:] + self.c_list[i - 1][0:1]
d = self.d_list[i - 1][1:] + self.d_list[i - 1][0:1]
else:
c = self.c_list[i - 1][2:] + self.c_list[i - 1][0:2]
d = self.d_list[i - 1][2:] + self.d_list[i - 1][0:2]
self.c_list.append(c)
self.d_list.append(d)
self.k_list.append(self.substitution(c + d, self.PC2))
def func(self, R, key):
"""
:param R: 每一轮的R,list
:param key: 每一轮的K,list
:return: 每一轮 f(R, key)
"""
E_R = self.substitution(R, self.E)
tmp = [(E_R[i] ^ key[i]) for i in range(0, 48)]
C = []
for i in range(0, 8):
B = tmp[i * 6: (i + 1) * 6]
row = B[0] * 2 + B[5] * 1
column = B[1] * 8 + B[2] * 4 + B[3] * 2 + B[4] * 1
num = self.S_BOXES[i][row][column]
lst = []
for j in range(4):
lst.append(int(num % 2 != 0))
num = num // 2
C = C + lst[::-1]
P = self.substitution(C, self.P)
return P
def init_P(self):
"""
16次迭代
"""
ip = self.substitution(self.X, self.IP)
self.l_list.append(copy.deepcopy(ip[0:32]))
self.r_list.append(copy.deepcopy(ip[32:64]))
for i in range(1, 17):
l = copy.deepcopy(self.l_list[-1])
r = copy.deepcopy(self.r_list[-1])
new_l = r
new_r = self.func(r, self.k_list[i])
for j in range(0, 32):
new_r[j] = new_r[j] ^ l[j]
self.l_list.append(new_l)
self.r_list.append(new_r)
def to_16(self, C=None):
"""
:param C: 二进制序列转化为十六进制,list
:return: C的十六进制表示,str
"""
if C is None:
C = self.C
num_list = ''
for i in range(0, len(C) // 4):
s = i * 4
num = C[s] * 8 + C[s + 1] * 4 + C[s + 2] * 2 + C[s + 3] * 1
num_list += hex(num)[2:].upper()
return num_list
def pri_all(self):
"""
输出每一轮的L,R,K 和最后的结果
:return: None
"""
print('-' * 100)
for i in range(0, 17):
print(f'第{i}轮:')
print(f'L = {"".join([str(_) for _ in self.l_list[i]])}')
print(f'R = {"".join([str(_) for _ in self.r_list[i]])}')
print(f'K = {"".join([str(_) for _ in self.k_list[i]])}')
print('-' * 100)
print(f'X = {self.to_16(self.X)}, K = {self.to_16(self.K)}')
print(f'RES = {self.to_16()}')
def str16_to_list2(hex_string):
"""
16进制字符串转化为2进制list
:param hex_string: 16进制字符串
:return: 转化后的2进制list
"""
binary_list = [bin(int(hex_digit, 16))[2:].zfill(4) for hex_digit in hex_string]
res = []
for item in binary_list:
for bit in item:
res.append(int(bit))
return res
if __name__ == '__main__':
X_16 = '0123456789ABCDEF'
K_16 = '133457799BBCDFF1'
X_2 = str16_to_list2(X_16)
K_2 = str16_to_list2(K_16)
d = DES(X=X_2, K=K_2)
d.pri_all()