密码学-1.仿射密码加解密(c++)
一.关键步骤:
(1) 加密:先将大小写转换成数字0-25,按照c=m*p+q%26进行加密
加密结果如图所示
(2) 解密:根据m=(c-q)*p-1,关键是求出密钥p的逆,代码如图
解密结果如图1.4所示.
(3)破解:密钥空间为311,可以进行暴力破解,关键破解代码
二.安全性分析:
仿射密码安全性较弱,抵抗不了穷举攻击
三.加密源码
#include<bits/stdc++.h>
using namespace std;
int main(){
//c=a*p+q;
int p,q,len,n,x;
char a[9999],c;
while(cin>>p){// 输入密钥p,q,明文a
cin>>q>>a;
if((p%2==0)||(p==1&&q==0)){//p!=1&&q!=0,p需与26互素
cout<<"密钥不合法";
break;
}
len=strlen(a);
for(int i=0;i<len;i++){//字母转成数字0-25
if(a[i]>=65&&a[i]<=90)
a[i]-=65;
else if(a[i]>=97&&a[i]<=122)
a[i]-=97;
x=a[i];
cout<<x<<" ";}//将转成数字的明文输出
cout<<"密文如下"<<endl;
for(int i=0;i<len;i++){//加密n=a*p+q
n=p*a[i]+q;
cout<<n<<" ";//输出加密后的数字
n=n%26+65;
a[i]=n;
}
cout<<endl;
for(int i=0;i<len;i++)
cout<<a[i]<<" ";//输出加密后的字母
}
return 0;
}
四.解密源码
#include<bits/stdc++.h>
using namespace std;
//n=a*p+q
int f(int p){// 求p的逆 ;
int m,k,r,d,i;
int a[8][4]={0};
a[0][0]=1,a[0][3]=1;
k=p;
m=26,r=1,d=0,i=0;
while(r){//列表法求出逆
r=m%k;
d=m/k;
i++;
a[i][0]=a[i-1][1];
a[i][2]=a[i-1][3];
a[i][1]=a[i-1][0]-a[i-1][1]*d;
a[i][3]=a[i-1][2]-a[i-1][3]*d;
m=k;
k=r;
}
if(a[i-1][3]<0)//如果逆小于0,加26
a[i-1][3]+=26;
p=a[i-1][3];
return p;
}
int main(){
int n,p,q,len,k;
char a[9999];
while(cin>>p){
if(p%2==0||p==13)
{cout<<"密钥不合法,请重新输入"<<endl;
break; }
cin>>q>>a;
len=strlen(a);
//判断大小写 ,并转成数字0-25
for(int i=0;i<len;i++){
if(a[i]>=65&&a[i]<=90)
a[i]-=65;
else if(a[i]>=97&&a[i]<=122)
a[i]-=97;
n=a[i]-q;
if(n<0)
n+=26;
n=n*f(p);
n=n%26+65;//由数字转成大写字母
a[i]=n;
}
for(int i=0;i<len;i++)//输出明文
cout<<a[i]<<" ";}
return 0;
}