DES加密、解密
欢迎大家访问我的GitHub博客
https://lunan0320.github.io/
1、写在前面
希望大家弄明白原理,不要只要代码
这里因为latex写的报告不能直接复制粘贴,就把我们实验报告中的原理部分以图片形式分享出来,供大家学习。
因为不希望大部分前来看博客的是为了代码而来,因此此处更新后删除了源代码,希望读者能够根据下述的详细原理看懂后完成。
如果理解了原理不懂如何写代码,那我觉得您应该移步Python Documentation contents
此处保留了部分不完整核心代码,仅用于参考,读者可以参考此部分或者自行完成
2、DES原理
translation = lambda s, t: ''.join(s[i - 1] for i in t) # 矩阵转换lambda表达式
#获取轮秘钥
def get_Kn(Key):# 生成Ki(共16轮密钥)
K64 = ''.join(hex_bin[i] for i in Key) #转bit串
# Step1 64bits Key -> 56bits Key:
K64_56 = [
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,
]
K56 = translation(K64, K64_56)
# print(K56)
# Step2 circulate left draft
Kleft_shift = [1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1]
Cn = [K56[:28]]
Dn = [K56[28:]]
for i in range(16):
Cn.append(Cn[-1][Kleft_shift[i]:] + Cn[-1][:Kleft_shift[i]])
for i in range(16):
Dn.append(Dn[-1][Kleft_shift[i]:] + Dn[-1][:Kleft_shift[i]])
K56_48 = [
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
]
Kn = [translation(Cn[i] + Dn[i], K56_48) for i in range(1, 17)]
return Kn
##处理输入,输入的字符串转ascii(0x),再分组,每16位0x一组,不足用0补齐
def divide(P):
l = len(P)
Pn = []
while not l % 16 == 0:
P = P + '0'
l = len(P)
else:
for i in range(0, l, 16):
Pn.append(P[i:i + 16])
return Pn
#F函数
def F(R,Ki): #R是32bits,Ki是48bits,
#print(len(R))
R = translation(R, E) #对R进行E拓展
R = ''.join('0' if R[i]==Ki[i] else '1' for i in range(48)) #对R和Ki进行异或
# 确定过S盒的坐标
ij = [R[i:i+6] for i in range(0,48,6)] # 按6bit分组
#print(ij)
#print(ij[0][1:-1]) #出错位置,取中间四位应该是[1:-1]
S_box_loca = [int(ij[n][0]+ij[n][-1],2) * 16 + int(ij[n][1:-1],2) for n in range(8)] # 首尾拼接做行,中间四位做列,这里的行列不用减1,因为4行16列,已经包括0的可能性了
R = ''.join(hex_bin[hex((S_box[n][S_box_loca[n]]))[-1]] for n in range(8))
# 过P盒
R = translation(R,P_box)
return R
def festial(l,r,Ki):
l_n = r
r_n = F(l_n,Ki)
r_n = ''.join('0'if l[i] ==r_n[i] else '1' for i in range(32))
return l_n,r_n
def Enc_Dec(P,Key,choice):
Pn = divide(P)
result=''
Kn = get_Kn(Key)
if choice=='2':
Kn.reverse()
for p in Pn:
p = ''.join(hex_bin[i] for i in p) #转为二进制
p = translation(p, IP) #IP置
l = p[0:32]
r = p[32:]
for i in range(16):
l,r = festial(l,r,Kn[i])
l,r = r,l
result = result + l+r
result = translation(result,IP_1) #IP_1 置换
return result