仿射函数(affine)
所谓仿射函数,是指满足如下条件的函数
在域中,有函数映射,c=ax+b,其中a有逆元,也就是x有唯一解。
一般来说,仿射函数定义在有限的数域中。古典密码的仿射函数是
c = (ax+b) mod 26, 一般只考虑26个英文字母,其中a满足与26互素。
显然,只有a与26互素,根据贝祖定理,有
sa+26t = 1
则有
sc = (sax+sb) mod 26
sc = (x+sb) mod 26
x= (sc-sb) mod 26
之所以要让x是唯一的,只是为了让解密唯一,不会产生歧义。
故在仿射密码中,加密函数为
c = (ax+b) mod 26, c为密文,x为明文,a、b为参数,满足gcd(a,26)=1
解密函数为
x = (sc-sb) mod 26, 其中有 sa = 1 mod 26
有时候,为了方便,可以设b为0。然而,这样做会让密钥空间得很小。因为与26互素的只有12个。
为了求出s,可能需要扩展的欧几里得算法,但是,由于这里的数字较小,完全可以用暴力搜索,求出s。
c++语言实现
#include<iostream>
using namespace std;
int find_s(int a){
for(int i=1;i<26;i++){
if(a*i%26==1){
return i;
}
}
}
string encrypt(int a,int b,string message){
for(int i=0;i<message.size();i++){
message[i]-='a';
message[i]=(a*message[i]+b)%26;
message[i]+='A';
}
return message;
}
string decrypt(int a,int b,string cipher){
int s=find_s(a);
for(int i=0;i<cipher.size();i++){
cipher[i]-='A';
cipher[i]=(s*cipher[i]+(26-s)*b)%26;//adding 26-s equals -s.
cipher[i]+='a';
}
return cipher;
}
int main(){
int a=3,b=7;//the key
string m;
cout<<"Please enter the message:"<<endl;
cin>>m;
string c;
c=encrypt(a,b,m);
cout<<"The ciphertext is "<<c<<endl;;
m=decrypt(a,b,c);
cout<<"After decryption "<<m<<endl;
}