维吉尼亚密码暴力破解c++实现

来源:互联网 发布:github源码在微信上 编辑:程序博客网 时间:2024/05/21 12:50

  维吉尼亚密码是一种多表替换密码,暴力破解相对来说比单表置换密码难一些。在网上找基于重合互指数法的破解代码,java、python都有,本菜鸟只有c++用的相对熟练一点,就用c++写了暴力破解过程。代码耗时提高效率什么的暂没考虑。

  维吉尼亚方阵是26*26的方阵,第一行代表明文字母,第一列代表密钥字母,每一行都是一个凯撒加密。


  

在只知道密文的情况下想要破解维吉尼亚加密,首先要确定密钥的长度。

确定密钥长度有两种方式:

1.Kasiski测试法

  搜索长度至少为2的相邻的一对对相同的密文段,记下它们之间的距离。而密钥长度d可能就是这些距离的最大公因子。

2.重合指数法

 公式:

  

代码:

void Miyaolenth(char c[]) {  int klen=1;   //密钥长度  int clen=strlen(c);   //密文的长度        while(1)  {        float IC[klen]; //重合指数float avgIC=0;  //平均重合指数for(int i=0;i<klen;i++)    //统计分组字母个数 {    int out[26]={ 0 };   //盛放字母个数的数组for(int j=0;i+j*klen<clen;j++)   out[(int)(c[i+j*klen]-'A')]++;          float e=0.000f;        int L=0;        for(int k=0;k<26;k++)    //子串密文长度             L+=out[k];        L*=(L-1);    for(int k=0;k<26;k++)        //分组计算重合指数IC        if(out[k]!=0)           e=e+((float)out[k]*(float)(out[k]-1))/(float)L;IC[i]=e;    }for(int i=0;i<klen;i++)   avgIC+=IC[i];avgIC/=klen;          //求IC的平均值      if (avgIC >= 0.06)  break;    //判断退出条件,重合指数的平均值是否大于0.06     else  klen++;  }  cout<<"密钥长度为:"<<klen<<endl; }


确定好密钥长度之后开始求密钥。

重合互指数法求密钥:

  根据密钥的长度对密文进行分组,每一组都是一个凯撒加密。计算拟重合指数,通过拟重合指数可以确定每组的移位密钥,从而求出整个的密钥。

公式:


代码:

float p[] = {0.082, 0.015, 0.028, 0.043, 0.127, 0.022, 0.02, 0.061, 0.07, 0.002, 0.008, 0.04, 0.024, 0.067, 0.075, 0.019, 0.001, 0.06, 0.063, 0.091, 0.028, 0.01, 0.023, 0.001, 0.02, 0.001};int key[100]={ 0 };    //存放密钥 for(int i=0;i<klen;i++)    //统计分组字母个数 {  int g=0;   //密文移动g个位置   for(int t=0;t<26;t++)  { float x=0.000f;    //拟重合指数     int out[26]={ 0 };   //盛放字母个数的数组for(int j=0;i+j*klen<clen;j++)   out[(int)(c[i+j*klen]-'A')]++;          int L=0;        for(int k=0;k<26;k++)      //子串密文长度             L+=out[k];        for(int k=0;k<26;k++)            x=x+p[k]*out[(k+g)%26];        if(x/L>0.055)        {        key[i]=g;        break;}        else g++;   }    }   cout<<"加密密钥为:";    for(int i=0;i<klen;i++)    //输出密钥字 cout<<char ('a'+key[i]);   cout<<endl;



求出密钥之后解密就很容易啦,查表即可。




原创粉丝点击