DES算法
原理
1.64位密钥(56位有效位与8位奇偶校验位)与64位明文
2.64位明文进行初始置换(初始置换表与终止置换互逆)
3.进行16轮
1)将64位明文分为左右各32位,L0与R0
2) R0通过一次E盒扩展置换变为48位
3)扩展后的右48位与key1异或
4)异或后的48位分为8组,一组6位,进行(S盒压缩)换字盒6进4出变为32位
5)32位进行直接换位P盒
6)换位后再与L0异或作为R1
7)R0直接作为L1进入下一轮
4.终止置换得到64位密文
有关Key的16轮运算
1.64位Key进行置换表1,去除了奇偶校验位
2.64key分为前后32位
3.前后各进行向左循环移位,其中1,2,9,16轮移动一位,其余移动两位
4.移动后将合成的56位密钥进行压缩置换(换位盒)得到48位,作为key1
5.将上一轮的前后28位继续移位,并进行压缩置换,得到Key2
6.后面的轮都和上述相同
S盒压缩
即换字盒
1.48位分为8组,每组六位
2.第一位和后一位组成一个二进制数,转为十进制即为行数
3.中间四位组成一个二进制数,转为十进制即为列数
4.在对应的S盒置换表中找到行列对应的十进制数,转化为二进制(4位)
5.把8个4位二进制数合并即转化为32位进行后续运算
相关模块代码
代码学习来源:https://blog.csdn.net/ytlxl/article/details/79822601
1.置换
tab=[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]#用明文的初始置换为例
M="0000000100100011010001010110011110001001101010111100110111101111"
def zhihuan(s,tab):
lista=[]
for i in range(0,len(tab)):
** lista.append(s[tab[i]-1])**
s1="".join(lista)
return s1
def main():
s1=zhihuan(M,tab)
print(s1)
if __name__=='__main__':
main()
1)此处遇到的问题
加重处本来写的是lista[i]=s[tab[i]-1]
报错list assignment index out of range
学习到之前定义的lista=[]为空数组,空数组不能直接指定位置,如直接给lista[i]赋值
需要使用append方法
2)疑惑
原文处的代码在ista.append(s[tab[i]-1])中
写的是 list1.extend(str(s[j-1]))
使用了str(),不知道为什么要使用这个函数
2.按位异或
def yihuo(s1,s2):
strlen=len(s1)
s3=[]
for i in range(0,strlen):
s3.append(str(int(s1[i])^int(s2[i])))
s4="".join(s3)
return s4
def main():
s1="10"
s2="100"
print(yihuo(s1,s2))
if __name__=='__main__':
main()
1)遇到的问题
1.字符串s1,s2一开始写的abc,efg,报错ValueError: invalid literal for int() with base 10: 'abc'
原来int()只能转化由纯数字组成的字符串,非纯数字组成的字符串强转为整型会报错
而des的明文字母或数字8字节最后都变为64位二进制数
所以输入s1与s2是等长的二进制字符串,输出s4是s1于s2异或后的二进制字符串
由于python中不能向字符串动态添加元素,这里将异或后的元素存在一个列表(s3)里,之后将列表转换回字符串(s4)
2.关于.join()
之前的代码是s3.append(int(s1[i])^int(s2[i]))
也就是说直接在列表里添加了整型
报错TypeError: sequence item 0: expected str instance, int found
学习到list包含数字,不能直接转化成字符串
所以更改为 s3.append(str(int(s1[i])^int(s2[i])))
2)疑惑
1.关于明文字符串(包括大小写字母、数字)是如何进行转换为二进制还不是很懂
2.s1,s2字符串中的数字被强制转化后只能是十进制,关于如何转换成二进制字符串
我jio得可以bin(int("100"))再去异或(此处与int("100",2)区分)