deffrequency_attack_Vigenere(c:str):
m=''#明文
k_len=0#破解出的密钥长度
k_len_max=10#破解时密钥长度的最大值
offset=0.01#密文概率平方和与标准概率平方和的最大差值接受度
target=0#标准概率平方和
standard_frequency=[0.08167,0.01492,0.02782,0.04253,0.12702,0.02228,0.02015,0.06094,0.06966,0.00153,0.00772,0.04025,0.02406,0.06749,0.07507,0.01929,0.00095,0.05987,0.06327,0.09056,0.02758,0.00978,0.02360,0.00150,0.01974,0.00074]# 计算英语字母标准频率的平方和for i in standard_frequency:
target+=i**2# 找到加密密钥K的长度for i inrange(k_len_max):
sample=c[::i+1]sum=0
frequency=frequency_finding(sample)for f in frequency:sum+=f**2ifabs(sum-target)<offset:# 找到符合偏移量的密钥长度后终止循环
k_len=i+1breakif k_len:
m_list=['']*k_len
# 将密文按照密钥长度分组for i inrange(k_len):
sample=c[i::k_len]# 分别对每一组进行移位密码的概率攻击
m_list[i]=frequency_attack_shift_cipher(sample)# 将破解的明文段整合for i inrange(len(c)):
m+=m_list[i%k_len][i//k_len]return m
else:return'attack fialed'
完整程序
deffrequency_finding(letters:str):
frequency=[0]*26
cnt=0
ord_a=ord('a')# 计算每个字母的频数for letter in letters:
frequency[ord(letter)-ord_a]+=1
cnt+=1# 计算每个字母的频率for i inrange(26):
frequency[i]/=cnt
return frequency
defVigenere_encryption(m:str, k:str):
c =''
m_len =len(m)
k_len =len(k)
ord_a =ord('a')for i inrange(m_len):
c +=chr((ord(m[i])-ord_a+ord(k[i % k_len])-ord_a)%26+ord_a)return c
deffrequency_attack_shift_cipher(c:str):
target=0
best=0
margin=1
best_k=0
standard_frequency=[0.08167,0.01492,0.02782,0.04253,0.12702,0.02228,0.02015,0.06094,0.06966,0.00153,0.00772,0.04025,0.02406,0.06749,0.07507,0.01929,0.00095,0.05987,0.06327,0.09056,0.02758,0.00978,0.02360,0.00150,0.01974,0.00074]# 计算英语字母标准频率的平方和for i in standard_frequency:
target+=i**2
frequency=frequency_finding(c)# 找到使密文字母频率*标准字母频率最接近标准频率平方和的Kfor k inrange(26):sum=0for f inrange(26):sum+=frequency[f]*standard_frequency[(f-k)%26]ifabs(sum-target)<margin:
margin=abs(sum-target)
best_k=k
best=sum
m=shift_cipher_decryption(c,best_k)return m
defshift_cipher_encryption(m:str,k:int):
cipher=""for letter in m:
cipher+=chr(((ord(letter)-ord('a')+ k)%26)+ord('a'))return cipher
defshift_cipher_decryption(c:str,k:int):return shift_cipher_encryption(c,-k)deffrequency_attack_Vigenere(c:str):
m=''#明文
k_len=0#破解出的密钥长度
k_len_max=10#破解时密钥长度的最大值
offset=0.01#密文概率平方和与标准概率平方和的最大差值接受度
target=0#标准概率平方和
standard_frequency=[0.08167,0.01492,0.02782,0.04253,0.12702,0.02228,0.02015,0.06094,0.06966,0.00153,0.00772,0.04025,0.02406,0.06749,0.07507,0.01929,0.00095,0.05987,0.06327,0.09056,0.02758,0.00978,0.02360,0.00150,0.01974,0.00074]# 计算英语字母标准频率的平方和for i in standard_frequency:
target+=i**2# 找到加密密钥K的长度for i inrange(k_len_max):
sample=c[::i+1]sum=0
frequency=frequency_finding(sample)for f in frequency:sum+=f**2ifabs(sum-target)<offset:# 找到符合偏移量的密钥长度后终止循环
k_len=i+1breakif k_len:
m_list=['']*k_len
# 将密文按照密钥长度分组for i inrange(k_len):
sample=c[i::k_len]# 分别对每一组进行移位密码的概率攻击
m_list[i]=frequency_attack_shift_cipher(sample)# 将破解的明文段整合for i inrange(len(c)):
m+=m_list[i%k_len][i//k_len]return m
else:return'attack failed'