Vigenere多表加法加密分析

Vigenere介绍

设明文 m=m1m2m3mn ,密钥 k=k1k2k3kn ,则密文
c=Ek(m)=c1c2c3cn .
其中 ci=(mi+ki)mod26

统计分析

参考密码如下

ktbueluegvitnthuexmonveggmrcgxptlyhhjaogchoemqchpdnetxupbqntietiabpsmaoncnwvoutiugtagmmqsxtvxaoniiogtagmbpsmtuvvihpstpdvcrxhokvhxotawswquunewcgxptlcrxtevtubvewcnwwsxfsnptswtagakvoyyak

Kasiski test

如果密文中出现两个相同的密文片段,那么它们对应的明文片段极有可能是相同的,则密码片段很可能是这些距离的最大公因子。

以下C++代码输出相同长度为3的代码片段之间距离。

/* birdy&C 17.3.11 多表加密 */

#include <iostream>
#include <algorithm>
#include <functional>
#include <set>
#include <iterator>
#include <vector>
#include<string>
using namespace std;

int main(void) 
{
    string code;
    code = "ktbueluegvitnthuexmonveggmrcgxptlyhhjaogchoemqchpdnetxupbqntietiabpsmaoncnwvoutiugtagmmqsxtvxaoniiogtagmbpsmtuvvihpstpdvcrxhokvhxotawswquunewcgxptlcrxtevtubvewcnwwsxfsnptswtagakvoyyak";

    //Kasiski test
    for (int i = 0; i <= code.size() - 4; i++)
    {
        string temp = code.substr(i, 3);
         int t=code.find(temp, i+1);//找下一个片段
        if (t != string::npos)
        {
            cout <<  t-i << endl;//输出位置差
        }

    }

    system("pause");
    return 0;
}

得到输出:

114
114
114
114
39
39
24
87
18
18
18
72
27
18

求最大公约数,猜测密码片段长度为3

index of coincidence

重合指数是字母串中两个随机元素相同的概率。
随机英文文本的IC总是大约为0.038。
而一段有意义的英文文本的IC总是大约为0.065。
可以用这个进一步确认密钥字的长度。
公式如下:
26i=1p2i0.065

交互重合指数是在两个字符串中分别取两字符,它们相同的概率。
可以以此来判断两个字符串的相对位移。
相对位移为0时,交互重合指数接近0.065,其他情况下在0.0031到
0.0045之间。

以下为计数

const int step = 3;//密钥长度
    int count[step][26] = { 0 };
    for (int i = 0; i < code.size(); i++) 
    {
        count[i%step]

- 'a']++;
}

以下函数返回相对位移

int shift(int *a,int *t ) 
{
    int sum_a = 0, sum_t = 0;
    for (int i = 0; i < 26; i++)
    {
        sum_a += a[i];
        sum_t += t[i];
    }

int index = -1;
int sum_max = 0;
    for (int i = 0; i < 26; i++) 
    {
        int sum = 0;
        for (int j = 0;  j < 26; j++)
        {
            sum += a[j] * t[(j + i) % 26];

        }
        if (sum > sum_a * sum_t * 0.05)//Ic>0.05,实际应该在0.065附近
        {
            cout << "index" << i << endl;
            if (sum > sum_max) //如果有多个值大于0.05返回最大的
            {
                index = i;
                sum_max = sum;
            }
        }
    }
    return index;
}

如果是简单的加法密码的话,可以直接和字母出现的统计概率表进行比较

其他

前两种分析比较侧重于多表加密,在解决简单的密码的时候单表加密的统计分析会显得比较直接。
类似于index of coincidence的分析
像mod3=1的那一个部分,
《Vigenere多表加法加密分析》
5,20概率特别大,根据两者之间的差猜测为e和t;
mod3=0的部分语法猜测最开始是it的可能性比较大,那么移动为24,移动之后的概率类似。
mod3=2直接全部输出挑了一下……反正也才26种?

结果

《Vigenere多表加法加密分析》

没有空格……本来英语就不好……QAQ
蛮好玩的233除了……经常感觉自己在加密而不是解码……

    原文作者:维吉尼亚加密问题
    原文地址: https://blog.csdn.net/birdy_/article/details/61618322
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞