一.理论
1.仿射加密是种特殊的替换加密
2.加密:y=ax+b mod 26
? ?解密:x=a'(y-b)mod 26? ? ? ? ? ?a'是a的逆元,a*a'=1mod26
? ?x,y,a,b都是整数环Z26中的元素,a限制于a有逆元即gcd(a,26)=1,所以a只有12种
3.攻击方法:暴力破解(穷尽搜索)和字母频率分析
二.算法思路
(1)加密
1.明密文用字符数组存储,求数组字符个数确定加密次数
2.每次加密不能直接对字母ASCII操作,因为涉及乘法,所以要先将字母变成0到25的数值,再进行整数环Z26内的运算,再将其变回字母(应考虑大小写)。
(2)解密
解密不做详细论述,未知密钥用字母频率分析,已知密钥涉及求逆运算(扩张欧几里得算法EEA),本文不做展示。
三.源代码
#include <iostream>
/**
仿射加密 作者:孤羽
*/
using namespace std;
int Affine_encryption(int a,int b,char plain[],char ciphertext[])//仿射加密
{
int i,j=0;
for(i=0;plain[i]!='\0';i++)
{
if(plain[i]>64&&plain[i]<91)//确定是字母
{
j=plain[i]-65; //明文化为整数环Z26的元素
ciphertext[i]=(a*j+b)%26+65;
}
else if(plain[i]>96&&plain[i]<123)
{
j=plain[i]-97;
ciphertext[i]=(a*j+b)%26+97;
}
}
return i;//返回输出长度(i+1),以控制输出密文
}
int main()
{
int a,b;
char plain[1000],ciphertext[1000];
int a1[12]={1,3,5,7,9,11,15,17,19,21,23,25};
//int a1[12]={'1','3','5','7','9','11','15','17','19','21','23','25'}; //错误定义
cout<<"输入密钥a,b:"<<endl;
cin>>a>>b;
cin.get();
cout<<"输入明文"<<endl;
cin.get(plain,1000);
int j=0,c; //j用于判断a是否满足条件gcd(a,26)=1,c存储返回值
for(int i=0;i<12;i++)
{
if(a==a1[i])
{
c=Affine_encryption(a,b,plain,ciphertext);
j=1;
}
}
if(j==1)
{
for(int i=0;i<=c;i++)
cout<<ciphertext[i];//直接全部输出会出现乱码
cout<<endl;
}
else
{
cout<<"a不满足条件"<<endl;
}
}
|