您的位置:首页 > 编程语言 > C语言/C++

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

2017-12-19 23:39 281 查看
  维吉尼亚密码是一种多表替换密码,暴力破解相对来说比单表置换密码难一些。在网上找基于重合互指数法的破解代码,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;


求出密钥之后解密就很容易啦,查表即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: