先上代码吧:
代码语言:javascript复制import re
def my_read(filename,row,col):
# 读取各种矩阵----参数为文件名和目标矩阵的行列数
sz = [[0 for i in range(col)]for i in range(row)]
with open(filename,"r") as s1:
lists = s1.readlines()
for i in range(len(sz)):
lists[i] = lists[i].split(',')
# 以 , 将字符串分开
for j in range(len(sz[0])):
sz[i][j] = lists[i][j]
return sz
# 返回一个该矩阵的二维数组
def ord_bin(str1):
str1_hex = ''
for i in str1:
str1_hex = str1_hex bin(ord(i))[:1] bin(ord(i))[2:]
return str1_hex
def create_L0R0():
#生成L0,R0
mingwen= [[0 for i in range(8)]for i in range(8)]
MW="abcdefgh"
str1_hex=ord_bin(MW)
for i in range (8):
for j in range(8):
mingwen[i][j]=str1_hex[i*8 j]
rep = my_read("IP.txt",8,8)
#读取置换矩阵
rep_mingwen = replace(mingwen,rep,8,8)
#进行初始置换
L0 = []
R0 = []
for i in range(4):
#得到c0
for j in range(8):
x,y = get_xy(int(rep[i][j]),8,8)
#检查坐标
L0.extend(rep_mingwen[x][y])
for i in range(4,8):
#得到d0
for j in range(8):
x,y = get_xy(int(rep[i][j]),8,8)
#检查坐标
R0.extend(rep_mingwen[x][y])
return [L0,R0]
def get_xy(n,row,col):
# n为要转化为坐标的数值
if n % col == 0:
x = int(n/col) -1
y = col - 1
else:
x = int(n/col)
y = n%col - 1
return [x,y]
def replace(temp,rep,row,col):
# 定义一个置换函数,参数temp为要替换的矩阵,file为替换矩阵,row列,col行
new_temp = [[0 for i in range(col)]for i in range(row)]
# 用来保存置换后的矩阵并作为返回值
for i in range(len(temp)):
for j in range(len(temp[0])):
x,y = get_xy(int(rep[i][j]),row,col)
if int(rep[i][j])%8 == 0:
new_temp[i][j] = temp[x-1][7]
# print(temp[x-1][7],end = ' ')
else:
new_temp[i][j] = temp[x][y]
return new_temp[:]
def child_key():
# 生成k1~k16的子密钥
key = [[0 for i in range(8)] for i in range(8)]
KEY = "abcdefgh"
str1_hex = ord_bin(KEY)
for i in range(8):
for j in range(8):
key[i][j] = str1_hex[i * 8 j]
# 读取64位key
c = []
d = []
k = []
c0,d0 = create_L0R0()
# 得到c0,d0
num = [1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1]
# 设置第n次循环左移位数
for i in range(16):
# 将生成k1~k16的子密钥存放在列表k中
c0 = my_move(c0,num[i])
d0 = my_move(d0,num[i])
k1 = []
k1.extend(c0)
k1.extend(d0)
pc_2 = my_read("PC-2.txt",8,6)
temp = []
# 暂时存放56位子密钥
for m in range(8):
for n in range(6):
temp.append(k1[int(pc_2[m][n])-1])
k.append(temp)
return k[:]
# k位16x48的子密钥二维数组
def my_move(list,n):
#循环移位,n为移位数
for i in range(n):##左移
list.insert(len(list),list[0])
list.remove(list[0])
return list
def E_extend(R0):
#将32位Ri扩展位48位
Ri = []
e = my_read("E_extend.txt",8,6)
for m in range(len(e)):
for n in range(len(e[0])):
Ri.append(R0[int(e[m][n])-1])
#print(Ri)
return Ri
def yihuo(a,c):
#进行异或运算
B = []
for n in range(len(a)):
b = []
if int(a[n]) == int(c[n]):
b.append(0)
else:
b.append(1)
B.extend(b)
return B
def create_B(K,ERi,num):
#进行异或运算,K为48位子密钥列表,ERi为48位扩展的Ri,num是轮数
B = []
for m in range(len(K)):
b = []
for n in range(len(K[0])):
if K[m][n] == ERi[n]:
b.append(0)
else:
b.append(1)
B.append(b)
return B[num]
#返回值为B0~B7的集合列表B
def get_bi(B):
b0 = ''
b1 = ''
b2 = ''
b3 = ''
b4 = ''
b5 = ''
b6 = ''
b7 = ''
for i in range(6):
b0 = b0 str(B[i])
for i in range(6,12):
b1 = b1 str(B[i])
for i in range(12,18):
b2 = b2 str(B[i])
for i in range(18,24):
b3 = b3 str(B[i])
for i in range(24,30):
b4 = b4 str(B[i])
for i in range(30,36):
b5 = b5 str(B[i])
for i in range(36,42):
b6 = b6 str(B[i])
for i in range(42,48):
b7 = b7 str(B[i])
return [b0,b1,b2,b3,b4,b5,b6,b7]
def get_lastR(K,R0,num):
#num为轮数
ERi = E_extend(R0)
#E扩展
B = create_B(K,ERi,num)
#num轮数用来控制Ki
b0,b1,b2,b3,b4,b5,b6,b7 = get_bi(B)
b0 = cut_bi(b0,0)
b1 = cut_bi(b1,1)
b2 = cut_bi(b2,2)
b3 = cut_bi(b3,3)
b4 = cut_bi(b4,4)
b5 = cut_bi(b5,5)
b6 = cut_bi(b6,6)
b7 = cut_bi(b7,7)
last_R = []
last_R.extend(b0)
last_R.extend(b1)
last_R.extend(b2)
last_R.extend(b3)
last_R.extend(b4)
last_R.extend(b5)
last_R.extend(b6)
last_R.extend(b7)
return last_R
def read_s(num):
if num 1 == 1:
s = my_read("S_box1.txt",4,16)
elif num 1 == 2:
s = my_read("S_box2.txt",4,16)
elif num 1 == 3:
s = my_read("S_box3.txt",4,16)
elif num 1 == 4:
s = my_read("S_box4.txt",4,16)
elif num 1 == 5:
s = my_read("S_box5.txt",4,16)
elif num 1 == 6:
s = my_read("S_box6.txt",4,16)
elif num 1 == 7:
s = my_read("S_box7.txt",4,16)
else:
s = my_read("S_box8.txt",4,16)
return s
def cut_bi(b,n):
x = my_int2(b[0],b[5])
y = my_int4(b[1],b[2],b[3],b[4])
s = read_s(n 1)
s =[]
temp = read_s(n)
s.append(my_bin(int(temp[x][y])))
return s
def my_int2(a1,a2):
a = a1 a2
if a == '00':
a = int(0)
elif a == '01':
a = int(1)
elif a == '10':
a = int(2)
else:
a = int(3)
return a
def my_int4(a1,a2,a3,a4):
a = a1 a2 a3 a4
if a == '0000':
a = int(0)
elif a == '0001':
a = int(1)
elif a == '0010':
a = int(2)
elif a == '0011':
a = int(3)
elif a == '0100':
a = int(4)
elif a == '0101':
a = int(5)
elif a == '0110':
a = int(6)
elif a == '0111':
a = int(7)
elif a == '1000':
a = int(8)
elif a == '1001':
a = int(9)
elif a == '1010':
a = int(10)
elif a == '1011':
a = int(11)
elif a == '1100':
a = int(12)
elif a == '1101':
a = int(13)
elif a == '1110':
a = int(14)
else:
a = int(15)
return a
def my_bin(a):
if a == 0:
a = '0000'
elif a == 1:
a = '0001'
elif a == 2:
a = '0010'
elif a == 3:
a = '0011'
elif a == 4:
a = '0100'
elif a == 5:
a = '0101'
elif a == 6:
a = '0110'
elif a == 7:
a = '0111'
elif a == 8:
a = '1000'
elif a == 9:
a = '1001'
elif a == 10:
a = '1010'
elif a == 11:
a = '1011'
elif a == 12:
a = '1100'
elif a == 13:
a = '1101'
elif a == 14:
a = '1110'
else:
a = '1111'
return a
def change(temp):
list = []
for m in range(len(temp)):
for n in range(len(temp[0])):
list.append(temp[m][n])
return list
K = child_key()
#获取k1~k16的子密钥存依次放在列表K中
L0,R0 = create_L0R0()
#获取L0,R0
for num in range(16):
#16轮循环
L = R0
temp = get_lastR(K,R0,num)
temp = change(temp)
#改变一下格式,使temp和L0格式一样,方便实现异或运算
R = yihuo(L0,temp)
L0 = L
R0 = R
mw = []
#存放最终的L,R
mw.extend(L)
mw.extend(R)
rep = my_read("IP-1.txt",8,8)
#进行最后一步逆置换并输出密文
miwen = []
linshi = ''
new_miwen=''
new_miwen2=''
for m in range(len(rep)):
for n in range(len(rep[0])):
linshi=linshi str(mw[int(rep[m][n])-1])
print(linshi)
new_miwen = re.findall(r'.{8}', linshi)
str_1 = ""
for b in new_miwen:
str_1 = chr(int(b, 2))
print(str_1)
最后的结果实际上也是存在一些问题,在个人后面的验证中也没有找清楚问题出在了哪里?但是大致思路应该没问题
文件读写操作:
代码语言:javascript复制def my_read(filename,row,col):
# 读取各种矩阵----参数为文件名和目标矩阵的行列数
sz = [[0 for i in range(col)]for i in range(row)]
with open(filename,"r") as s1:
lists = s1.readlines()
for i in range(len(sz)):
lists[i] = lists[i].split(',')
# 以 , 将字符串分开
for j in range(len(sz[0])):
sz[i][j] = lists[i][j]
return sz
# 返回一个该矩阵的二维数组