加密模块
key =input("请输入密钥:")
#储存密钥
ls = []
for i in key:
ls.append(ord(i)-97)
length = len(ls)
#打开明文并处理,将明文存入text
file = open('plaintext.txt','rt')
text=''
for line in file: #读取每行明文
line = line.strip("\n") #去除每行的换行符
for j in line:
if j in ['!','~','`','@','#','$','%','^','&',' ',\
'*','(',')','_','+','=','?','.',',',';',':']: #去除标点符号
line = line.replace(j,'')
text +=line.lower()
file.close()
#对明文加密
k=0
outpath = 'cipher.txt' #密文输出路径
output = open(outpath,'wt')
for char in text:
char = ord(char)-97
char = (char + ls[k]) %26
k = (k+1)%length #每次将k加1并模密钥的长度,实现对全文加密
char = chr(char+97)
output.write(char)
print('加密成功,输出文件{}'.format(outpath))
output.close()
input("输入回车关闭窗口")
将要加密的内容存放在plaintext.txt文件钟,运行后首先输入密钥,然后会生成加密后的文件cipher.txt。
解密模块
key =input("请输入密钥:")
#储存密钥
ls = []
for i in key:
ls.append(ord(i)-97)
length = len(ls)
#打开密文并处理,将明文存入text
file = open('cipher.txt','rt')
text=''
for line in file: #读取每行密文
line = line.strip(" \n") #去除每行的换行符
text +=line
file.close()
#对密文解密
k=0
outpath = 'decode.txt' #密文输出路径
output = open(outpath,'wt')
for char in text:
char = ord(char)-97
char = (char - ls[k]) %26
k = (k+1)%length #每次将k加1并模密钥的长度,实现对全文加密
char = chr(char+97)
output.write(char)
print('解密成功,输出文件{}'.format(outpath))
output.close()
input("输入回车关闭窗口")
运行后输入密钥,将密文解密后的明文存在decode.txt中。
破解密钥
import math
f = open('cipher.txt','rt') #读取密文
ciphertext = f.read()
f.close()
length = len(ciphertext)
#字母出现频率
Beker_Piper = {'a':0.0804,'b':0.0148,'c':0.0334,'d':0.0382,'e':0.1249,'f':0.0240,'g':0.0187,'h':0.0505,'i':0.0757,'j':0.0016,'k':0.0054,'l':0.0407,'m':0.0251,'n':0.0723,'o':0.0764,'p':0.0214,'q':0.0012,'r':0.0628,'s':0.0651,'t':0.0928,'u':0.0273,'v':0.0105,'w':0.0168,'x':0.0023,'y':0.0166,'z':0.0009}
#储存重复子串及其出现的位置
dic = {}
sublen = 3 #子串的长度
for i in range(len(ciphertext)-(sublen-1)): #寻找重复子串
substring = ciphertext[i:i+sublen] #substring为片段
if substring in ciphertext[i+sublen:]:
dic[substring] = dic.get(substring,str(ciphertext.index(substring))+',') + str(ciphertext[i+sublen:].index(substring)+sublen+ i) + ","
else:
dic[substring] = dic.get(substring,str(ciphertext.index(substring))+',')
frequent = 8 #子串出现次数
KEY = {} #密钥的集合
for substring in dic.values(): #遍历重复子串
if len(substring) > frequent:
#print("子串---------------------------------------------------------")
index=substring.split(',')[:-1] #计算子串间隔
gap = []
for i in range(1,len(index)):
gap.append(int(index[i])-int(index[0]))
#计算最大公约数
gcd = gap[0]
for num in gap[1:]:
gcd = math.gcd(gcd, num)
#print(gcd)
sectionlen = length // gcd #分段
Iclist = []
if gcd > 1:
M = []
for j in range(gcd):
s='' #储存每一段的字符串
for i in range(j,len(ciphertext),gcd):
s +=ciphertext[i]
sum1 = 0
for p in range(26):
sum1 += ( s.count(chr(p+97)) * (s.count(chr(p+97))-1) )
Iclist.append(sum1/(len(s) * (len(s)-1))) #计算重合指数
if sum1/(len(s) * (len(s)-1)) <0.05: #重合指数小于0.05的排除
break
#如果符合条件,计算密钥
#猜测g
for g in range(25):
sum2 = 0
for a in range(25):
sum2 +=Beker_Piper[str(chr(a+97))]*s.count(chr((a+g)%26+97))
if sum2/len(s) > 0.055:
M.append(chr(g + 97))
key = ''.join(M)
if key != '':
KEY[key] = KEY.get(key,0) + 1 #将可能的密钥添加到字典
#对所有可能的密钥进行排序
items = list(KEY.items())
items.sort(key=lambda x:x[1], reverse=True)
print('密钥按概率从大到小可能为:')
for i in range(5):
print('{}、'.format(i),items[i][0])
input("输入回车关闭窗口")
运行该程序后会将概率最高的5个密钥打印出来。