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

仿射密码加解密及暴力破解c++实现

2017-12-19 23:13 537 查看
  仿射密码是属于单表置换密码,是加法密码和乘法密码的组合。

  加密函数 e(x)= ax+b (mod 26),且要求gcd(a,26)=1

     解密函数 x = a^(-1)(e(x)-b)
 
加解密代码如下:
#include <iostream>
#include <string.h>
using namespace std;
char m[100];
char c[100];
int gcd(int a,int b)  //辗转相除法求a,b的最大公约数
{
int k=0;
do
{
k=a%b;
a=b;
b=k;
}while(k!=0);
return a;
}
int Ni(int a,int b)  //求a相对b的逆元
{
int i=0;
while(a*(++i)%b!=1);  //a*i=1 mod b
return i;
}
void Jiami(char m[],int k1,int k2)  //加密
{
int len=strlen(m);
for(int i=0;i<len;i++)
{
c[i]=(k1*(m[i]-97)+k2)%26+65;    //加密公式 e(x)=k1*x+k2 (mod 26)
}
cout<<"加密后的密文为:";
for(int i=0;i<len;i++)
cout<<c[i];
cout<<endl;
}
void Jiemi(char c[],int k1,int k2)   //解密
{
int len=strlen(c);
char mm[100];
for(int i=0;i<len;i++)
{
int t=c[i]-65-k2;
if(t<0) t+=26;
mm[i]=k1*t%26+97;    //解密公式 x=k1^-1*(e(x)-k2)(mod26)
}
cout<<"解密后的明文为:";
for(int i=0;i<len;i++)
cout<<mm[i];
cout<<endl;
}
int main()
{
char m[100];
int k1,k2;
cout<<"输入明文:";
cin>>m;
cout<<"密钥k1和k2:";
cin>>k1>>k2;
while(gcd(k1,26)!=1)   //判断输入的密钥是否合法
{
cout<<"输入的密钥不合法,请重新输入!"<<endl;
cin>>k1>>k2;
}
Jiami(m,k1,k2);
int k3=Ni(k1,26);
cout<<"解密密钥为:";
cout<<k3<<" "<<k2<<endl;
Jiemi(c,k3,k2);
return 0;
}


  对仿射密码来说,加密函数里面有两个参数a和b,a要求26互素,因而只有12个选择,b的选择有26种,因此密钥空间大小只有12*26=312。计算量并不算大,暴力破解时直接穷举出来找有意义的字符串即可。

代码如下:
#include <iostream>
#include <fstream>
#include <string.h>
using namespace std;
int l[]={9,21,15,3,19,7,23,11,5,17,25};
int r[]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25};
char c[100];
char m[100];
void Jiemi(char c[],int k1,int k2)   //解密
{

int len=strlen(c);
for(int i=0;i<len;i++)
{
int t=c[i]-65-k2;
if(t<0) t+=26;
m[i]=k1*t%26+97;    //解密公式 x=k1^-1*(e(x)-k2)(mod26)
}
ofstream outfile,fout;
outfile.open("file.txt",ios::app);
for(int i=0;i<len;i++)
outfile<<m[i];
outfile<<endl;
}
int main()
{
cout<<"请输入要破解的密文:";
cin>>c;
for(int i=0;i<11;i++)
{
for(int j=0;j<25;j++)
Jiemi(c,l[i],r[j]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: