在前一篇文章中,已经讨论了如何根据重合指数求解密钥。现在讨论如何在已知密钥长度的情况下求解密钥。

拟重合指数:
qi 表示字母 i 在维吉尼亚密文分布中发生的概率, pi 表示字母 i 在正常英语文本分布中发生的概率,则拟重合指数可以定义为

R = ∑ pi * qi (‘a’<= i <=‘z’)

当两个频率分布类似时,R 的值相对要高。

求解:

也就是说,当明文在某个字母加密下的内积最大时,该字母极有可能是密钥中的字母。

将密文按密钥长度分组,按列进行划分,每列所组成的密文就相当于进行了凯撒加密,因为密钥字符在字母表中,所以每列进行循环26次,并统计在该字符下的内积R,最后挑选出内积最大的作为该列的密钥字符。

按列循环完后得到的字符组成的可能是密钥。(根据所用到的正常英语文本中字母概率不同而有所差错,并不能保证完全正确,可以根据明文的大致内容修改密钥)

要是实在不行的话,用网站解密吧:
vigenere-solver

大致代码:

key_len = 23def getkey(c,cnt):alp_rate1 =[0.08167,0.01492,0.02782,0.04253,0.12705,0.02228,0.02015,0.06094,0.06996,0.00153,0.00772,0.04025,0.02406,0.06749,0.07507,0.01929,0.0009,0.05987,0.06327,0.09056,0.02758,0.00978,0.02360,0.0015,0.01974,0.00074]len_c = len(c)temp = 'abcdefghijklmnopqrstuvwxyz'alp_rate2 = []for i in temp:#统计字母在该列密文中的出现频率alp_rate2.append(c.count(i)/len_c)inner = []#统计内积for i in range(26):#将26个字母作为该列密文sum_inner = 0#位移量i时的内积for j in range(26):sum_inner += alp_rate1[j]*alp_rate2[j]inner.append(sum_inner)alp_rate2 = alp_rate2[1:] + alp_rate2[:1] #对密文进行位移后再统计频率,等价于将字母频率列表向左移位#根据内积筛选合适的字母return temp[inner.index(max(inner))]
#求解密钥内容
key = ''
for i in range(23):c = ''for j in range(i,cipher_len,key_len):c += cipher[j]key += getkey(c,i)print(key)

例题:[NCTF2019]Sore

根据给出的代码可以看出这是类似维吉尼亚密码,只不过这里的密钥字符在ascii_letters里面选。既不知道密钥长度也不知道密钥的具体内容。

第一步:求解密钥长度

cipher = open(r'ciphertext.txt', 'r').read()
cipher_len = len(cipher)#求解密钥长度
for n in range(1,38):#枚举密钥长度CI = 0#CI为所有列数的重合指数的总和for i in range(0,n):#枚举每列的重合指数c = ''for j in range(i,cipher_len,n):#按列组成字符串c += cipher[j]L = len(c)c_elem = set(c)#取不重复的字符CIi = 0 #该列的重合指数for litter in c_elem:num = c.count(litter)#统计该字符的个数CIi += num/L*(num-1)/(L-1)CI += CIiCI /= n#求每列的平均重合指数if 0.06 < CI < 0.07:print('密钥长度:',n,'重合指数:',CI)

求出密钥长度为23。那么接下来就是破解密钥的具体内容了。

第二步:求解密钥的具体内容

key_len = 23def getkey(c,cnt):alp_rate1 =[0.08167,0.01492,0.02782,0.04253,0.12705,0.02228,0.02015,0.06094,0.06996,0.00153,0.00772,0.04025,0.02406,0.06749,0.07507,0.01929,0.0009,0.05987,0.06327,0.09056,0.02758,0.00978,0.02360,0.0015,0.01974,0.00074]#alp_rate1 = [0.0856,0.0139,0.0297,0.0378,0.1304,0.0289,0.0199,0.0528,0.0627,0.0013,0.0042,0.0339,0.0249,0.0707,0.0797,0.0199,0.0012,0.0677,0.0607,0.1045,0.0249,0.0092,0.0149,0.0017,0.0199,0.0008]len_c = len(c)temp = 'abcdefghijklmnopqrstuvwxyz'alp_rate2 = []for i in temp:#统计字母在该列密文中的出现频率alp_rate2.append(c.count(i)/len_c)inner = []#统计内积for i in range(26):#将26个字母作为该列密文sum_inner = 0#位移量i时的内积for j in range(26):sum_inner += alp_rate1[j]*alp_rate2[j]inner.append(sum_inner)alp_rate2 = alp_rate2[1:] + alp_rate2[:1] #对密文进行位移后再统计频率,等价于将字母频率列表向左移位#根据内积筛选合适的字母cha = 100alp = ''inner_i = 0'''for i in range(26):if abs(inner[i]-0.065546) < cha:alp = temp[i]inner_i = inner[i]cha = abs(inner[i]-0.065546)return alp    '''return temp[inner.index(max(inner))]
#求解密钥内容
key = ''
for i in range(23):c = ''for j in range(i,cipher_len,key_len):c += cipher[j]key += getkey(c,i)print(key)

得到密钥为 :
vlbeunuovbpucklsjxlfpaq
然后根据加密推算出解密代码:

第三步:恢复明文

#求解明文
from string import ascii_letters
ctoi = lambda x: ascii_letters.index(x)
itoc = lambda x: ascii_letters[x]
#cipher = ''.join( itoc( ( ctoi(p) + ctoi( key[i % len_key] ) ) % 52 )  for i,p in enumerate(plain) )
m = ''.join( itoc( ( ctoi(p) - ctoi( key[i % key_len] ) ) % 52 )  for i,p in enumerate(cipher) )
print(m)

这里截取了部分明文:

密钥:
vlbeunuovbpucklsjxlfpaq
明文:
ShewouldrtwelkrigHtnext
tomewhenAelifttheSealio
nsbutshehidrtwalkToofar

第四步:根据明文修改密钥

显然,这个密钥有些地方是不对的。所以要根据内容大致意思进行推测正确的明文,在计算出密文。
明文中第三行butshehidrtwalkToofar,根据多年的英语学习经历,可以推测正确的明文时butshedidntwalkToofar.

于是
明文: h --> d ,多移4位,r --> n,多移4位。
根据公式
(密文 - 密钥)%52 = 明文
密文不能修改,那么对应密钥字母应该多移4位。
得到正确密钥:
vlbeunuozbpycklsjxlfpaq

from string import ascii_lettersm = 'nsbutshedidntwalkToofar'
c = 'IDcyNFBsCjsLvGlDtqztuaH'
ctoi = lambda x: ascii_letters.index(x)
itoc = lambda x: ascii_letters[x]
key = ''.join(itoc( ( ctoi(c[i]) - ctoi( m[i] ) ) % 52 )  for i in range(len(c)))
print(key)

要想知道更巧妙地方法吗?
当然是网站解密vigenere-solver,直接给出密钥长度和密钥内容以及明文。

刚提交上去,居然不对。淦!再次看别人的wp才发现x要大写。
根据矫正后的明文来看

ShewouldntwalkrigHtnext
tomewhenwelefttheSealio
nsbutshedidntwalkToofar

会发现突兀的地方,就是所得出的明文在不该大写的地方进行了大写:rigHt , Sea , Too。

再次矫正密钥

from string import ascii_lettersm = 'Shewouldntwalkrightnext'
c = 'nsfAIHFrMuLynuCApeEstxJ'
ctoi = lambda x: ascii_letters.index(x)
itoc = lambda x: ascii_letters[x]
key = ''.join(itoc( ( ctoi(c[i]) - ctoi( m[i] ) ) % 52 )  for i in range(len(c)))
print(key)

真真正正的密钥:vlbeunuozbpycklsjXlfpaq

参考:
Virginia无密钥解密
古典密码之维吉尼亚密码无密钥破解

利用拟重合指数求解密钥具体内容相关推荐

  1. 多表古典密码统计分析之Vigenere算法保姆级教学(含Kasiski测试法和重合指数法)

     该算法参考于现代密码学第二版2.3.2多表古典密码统计分析 由于书上内容的介绍难以理解,下面我将把我个人对Kasiski测试法和重合指数法这两种方法的理解用文字和代码表示 参考文章 维吉尼亚密码的破 ...

  2. 6.5 【加密和安全】- 重合指数 无线网络

    专栏:牛客网刷题 1.重合指数法对下面哪种密码算法的破解最有效() 置换密码 单表代换密码 多表代换密码 序列密码 重合指数 重合指数(IC,Index of Coincidence)是指数学上的一种 ...

  3. 利用Matlab优化工具箱求解旅行商最短路径问题

    前面介绍了利用Matlab二元整数规划求解数独问题,对于另一个问题-旅行商问题也可以用它来求解. 旅行商问题就是找到经过所有站点的最短闭合路径,如下图为在美国地图框架内产生的200个旅行站点,而旅行商 ...

  4. [转载] python bp神经网络 mnist_Python利用全连接神经网络求解MNIST问题详解

    参考链接: Python中的单个神经元神经网络 本文实例讲述了Python利用全连接神经网络求解MNIST问题.分享给大家供大家参考,具体如下: 1.单隐藏层神经网络 人类的神经元在树突接受刺激信息后 ...

  5. 利用特征值与特征向量求解弹性力学中的主应力与主平面问题

    利用特征值与特征向量求解弹性力学中的主应力与主平面问题 前言 一.二向应力状态 1. 莫尔圆图解法 2. 特征值与特征向量解法 二.三向应力状态 前言 已知物体在任意一点的六个应力分量(σx,σy,σ ...

  6. linux在指定行添加内容,linux下利用shell在指定的行添加内容的方法

    linux下利用shell在指定的行添加内容的方法 在linux的一些配置中总会要进行某个文件中的某行的操作,进行增加,修改,删除等操作. 而这里主要是进行的是指定的行添加数据的操作: 脚本如下: s ...

  7. 1.已知本原多项式,利用Matlb中的simulink构成m序列产生器。2.已知任意本原多项式,利用matlb软件编程求解其对应的m序列以及m序列产生过程。

    1. 已知本原多项式,利用Matlb中的simulink构成m序列产生器.2.已知任意本原多项式,利用matlb软件编程求解其对应的m序列以及m序列产生过程. m序列是最长线性反馈移位寄存器的简称,他 ...

  8. 二次曲线指数平滑怎么用计算机运行,利用Excel进行指数平滑解析(2).doc

    利用Excel进行指数平滑分析与预测(2) [例]连续10年的灌溉面积. 第一步,录入数据(图1). 图1 原始数据 第二步,选项设置. 沿着主菜单的"工具(T)→数据分析(D)" ...

  9. 如何利用 DITA 实现高效的跨部门内容共享?

    19 世纪,达尔文说:"适者生存":21 世纪,达尔文信息分类架构 (Darwin Information Typing Architecture, DITA) 主张对信息进行模块 ...

最新文章

  1. java float内存结构_Java后端开发岗必备技能:Java并发中的内存模型
  2. python3.5安装-Linux:Python3.5安装和配置
  3. Azure Backup和Azure Site Recovery的区别是什么
  4. 453. Minimum Moves to Equal Array Elements (python)
  5. 创作共用协议创始人-Lawrence Lessig(2)
  6. 三元运算符和if else_PHP If-Else,Switch Case和速记三元运算符示例
  7. python条形图的间距_Matplotlib有间隙条形图
  8. 09-Mysql数据库----外键的变种
  9. 小红伞的WAF一个绕过方法
  10. 学习Java技术Eclipse版本的选择
  11. 单片机应用系统设计技术——串行口方式0 拓展并行输出端口 02 74LS164芯片
  12. ucloud的弹性计算
  13. android航拍效果,足不出户看遍大好河山!超震撼的航拍全景APP
  14. PREEMPT_RT 高精度定时器
  15. 每秒订单数25倍提升,蘑菇街怎样跨过海量服务架构的技术藩篱?
  16. Nature综述:农业生态系统中的土壤结构和微生物组功能
  17. Linux-日志管理篇
  18. Windows操作系统常见故障
  19. Python多线程结合队列下载百度音乐的方法
  20. Hulu推荐 | 传奇嘻哈音乐组合的美国梦:《武当帮成名录》

热门文章

  1. 网页不能复制文本的解决办法
  2. 端午抗疫宣传公益小游戏-用Python为粽子宝宝戴口罩
  3. 巴斯夫Basonat_HI100ap固化剂TDS产品说明书
  4. postgresql 的 base64 解密、解码
  5. 不要放过那个装X的阿里,android游戏开发大全第二版PDF
  6. 树莓派显示屏的休眠和唤醒
  7. 中国如何应对非传统网络安全风险?
  8. caged系统pdf_介孔二氧化硅纳米粒子药物递送系统研究进展-中国药科大学学报!.PDF...
  9. Docekr风暴:负载均衡那点事儿
  10. python源代码怎么变成软件_python程序怎么变成软件