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

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

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

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

  

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

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

1.Kasiski测试法

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

2.重合指数法

 公式:

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

代码:

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; 
}

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

重合互指数法求密钥:

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

公式:

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

代码:

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;

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


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