初学Python,想把常规的古典密码和现代密码都手写一遍,今天学到普莱费尔密码了,不得不说,还挺费劲的,加密解密搞完了,至于无密钥暴力破解需要爬山算法等内容,先不写,下面直接贴代码,做个纪念
'''
普莱费尔密码加解密
密文和密钥都是25位的
注意输入的内容不能有空格
'''
import string
import math
def keyProcessing(key):
#处理密钥
mydict = {}
mylist = []
mylist2 = []
for i in key:
if i not in mydict:
mydict[i] = 0
if mydict[i] == 0:
mylist.append(i)
else:
mydict[i] += 1
for j in string.ascii_lowercase:
if j not in mydict and j != 'j':
mylist.append(j)
# print(mylist,len(mylist))
for k in range(5):
mylist2.append(mylist[0+5*k:5+5*k])
#p1,p2
# print(mylist2)
p_list = []
return mylist2
def encryption(plaintext):
p_list = []
#明文预处理
for i in plaintext:
if i == 'j':
p_list.append('i')
else:
p_list.append(i)
tmp_str_list = []
for i in range(math.ceil(len(p_list)/2)+1):
try:
tmp_list = p_list[0+2*i:2+2*i]
if tmp_list[0] == tmp_list[1] and tmp_list[0] != 'z':
tmp_str = tmp_list[0] + 'z' + tmp_list[1]
tmp_str_list.append(tmp_str)
elif tmp_list[0] == tmp_list[1] and tmp_list[0] == 'z':
tmp_str = tmp_list[0] + 'q' + tmp_list[1]
tmp_str_list.append(tmp_str)
else:
tmp_str = tmp_list[0] + tmp_list[1]
tmp_str_list.append(tmp_str)
except:
tmp_str_list.append(p_list[-1])
break
len_str = ''.join(tmp_str_list)
if len(len_str) % 2 != 0:
if tmp_str_list[-1] != 'z':
tmp_str_list.append('z')
else:
tmp_str_list.append('q')
len_str = ''.join(tmp_str_list)
tmp_len_list = []
for i in range(int(len(len_str)/2)):
tmp_len_str = len_str[0+2*i:2+2*i]
tmp_len_list.append(tmp_len_str)
# print(tmp_len_list)
#加密过程
# kp = ''.join(tmp_len_list)
mylist2 = keyProcessing(plaintext)
mylist3 = keyProcessing(key)
mylist5 = []
for i in mylist3:
v = ''.join(i)
mylist5.append(v)
mylist5 = ''.join(mylist5)
mylist4 = []
for i in mylist2:
v = ''.join(i)
mylist4.append(v)
mylist4 = ''.join(mylist4)
print(f'mylist5为{mylist5}')
print(f'mylist3为{mylist3}')
print(f'mylist4为{mylist4}')
print(f'tmp_len_list为{tmp_len_list}')
#在同一列 mylist3里面是Key,tmp_len_list里面是明文
final_list = []
for i,x,m in zip(tmp_len_list,mylist4,range(len(tmp_len_list))):
for j,y in zip(mylist3,range(5)):
#同行
if i[0] in j and i[1] in j:
if mylist5.index(i[0]) % 5 != 4:
c1 = mylist5[mylist5.index(i[0])+1]
else:
c1 = mylist3[y][0]
final_list.append(c1)
if mylist5.index(i[1]) % 5 != 4:
c2 = mylist5[mylist5.index(i[1]) + 1]
else:
c2 = mylist3[y][0]
final_list.append(c2)
print(f'第{m}次{i[0], i[1]} 同行被加密为{c1, c2}')
#同列
elif mylist5.index(i[0]) % 5 == mylist5.index(i[1]) % 5 :
c1 = mylist5[(mylist5.index(i[0])+5)%25]
c2 = mylist5[(mylist5.index(i[1])+5)%25]
final_list.append(c1)
final_list.append(c2)
print(f'第{m}次{i[0],i[1]} 同列被加密为{c1,c2}')
break
#对角
elif mylist5.index(i[0]) % 5 != mylist5.index(i[1]) % 5 and (i[0] not in j and i[1] in j):
w1 = mylist5.index(i[0])
w2 = mylist5.index(i[1])
#废弃的代码
# if abs(w1 % 5 - w2 % 5) != 1:
# p1 = w1 + 2 * (int((w1 % 5 + w2 % 5) / 2) - w1 % 5)
# p2 = w2 + 2 * (int((w1 % 5 + w2 % 5) / 2) - w2 % 5)
# else:
# p1 = w1 + w2 % 5 - w1 % 5
# p2 = w2 + w1 % 5 - w2 % 5
# if w1 % 5 > w2 % 5:
p1 = w1 - (w1 % 5 - w2 % 5)
p2 = w2 + (w1 % 5 - w2 % 5)
# else:
# p1 = w1 - (w1 % 5 - w2 % 5)
# p2 = w2 + w1 % 5 - w2 % 5
final_list.append(mylist5[p1])
final_list.append(mylist5[p2])
print(f'第{m}次{i[0],i[1]} 对角被加密为{mylist5[p1],mylist5[p2]}')
else:
continue
#输出密文
print('密文为 ' + ''.join(final_list))
def decryption(key,ciphertext):
w_list = []
for c,i in zip(ciphertext,range(int(len(ciphertext)/2))):
w = ciphertext[0 + 2 * i: 2 + 2 * i]
w_list.append(w)
k_list = keyProcessing(key)
print(f'k_list为{k_list}')
k2_list = []
for i in k_list:
v = ''.join(i)
k2_list.append(v)
k2_list = ''.join(k2_list)
print(f'k2_list为{k2_list}')
p_list = []
print(f'w_list为{w_list}')
for i in w_list:
for j in k_list:
#同行
if i[0] in j and i[1] in j:
if (k2_list.index(i[0])) % 5 == 0:
p1 = k2_list[(k2_list.index(i[0]) + 4)]
else:
p1 = k2_list[(k2_list.index(i[0]) - 1)]
p_list.append(p1)
if (k2_list.index(i[1])) % 5 == 0:
p2 = k2_list[(k2_list.index(i[1]) + 4)]
else:
p2 = k2_list[(k2_list.index(i[1]) - 1)]
p_list.append(p2)
print(f'通过密钥把{i[0]},{i[1]}同行解密恢复为{p1},{p2}')
break
# 同列
elif k2_list.index(i[0]) % 5 == k2_list.index(i[1]) % 5 :
p1 = k2_list[(k2_list.index(i[0]) - 5) % 25]
p2 = k2_list[(k2_list.index(i[1]) - 5) % 25]
p_list.append(p1)
p_list.append(p2)
print(f'通过密钥把{i[0]},{i[1]}同列解密恢复为{p1},{p2}')
break
# 对角
elif k2_list.index(i[0]) % 5 != k2_list.index(i[1]) % 5 and (i[0] not in j and i[1] in j):
w1 = k2_list.index(i[0])
w2 = k2_list.index(i[1])
# if abs(w1%5 - w2%5) != 1:
# p1 = w1 + 2*(int((w1%5 + w2%5)/2) - w1%5)
# p2 = w2 + 2*(int((w1%5 + w2%5)/2) - w2%5)
# else:
# p1 = w1 + w2%5 - w1%5
# p2 = w2 + w1%5 - w2%5
# p_list.append(k2_list[p1])
# p_list.append(k2_list[p2])
# if w1 % 5 > w2 % 5:
p1 = w1 - (w1 % 5 - w2 % 5)
p2 = w2 + (w1 % 5 - w2 % 5)
# else:
# p1 = w1 + (w2 % 5 - w1 % 5)
# p2 = w2 - (w2 % 5 - w1 % 5)
# print(p1,p2)
p_list.append(k2_list[p1])
p_list.append(k2_list[p2])
print(f'通过密钥把{i[0]},{i[1]}对角解密恢复为{k2_list[p1]},{k2_list[p2]}')
break
print(f'明文预处理之后为: ' + ''.join(p_list))
#最终结果可能为
p_list.pop(-1)
print('最终结果可能为[1]: ' + ''.join(p_list))
p_list.pop(-2)
print('最终结果可能为[2]: '+''.join(p_list))
if __name__ == '__main__':
enter = int(input('加密输入0\n解密输入1\n:'))
#加密
if enter == 0:
# plaintext = 'qingyuzhenshuai'
# key = 'wuyahandsome'
plaintext = input('请输入明文: ').lower()
key = input('请输入密钥: ').lower()
key = key.replace('j','i')
keyProcessing(key)
encryption(plaintext)
#解密
if enter == 1:
# key = 'playfair'
# ciphertext = 'rpvlniayfppbbrrvuglayfpyrbrpvlniayfppbcv'
ciphertext = input('请输入密文: ').lower()
key = input('请输入密钥: ').lower()
key = key.replace('j', 'i')
decryption(key,ciphertext)