凯撒密码
凯撒密码就是简单移位,注意负数取模的情况就好了。
#include<bits/stdc++.h>
using namespace std;
const int mod = 26;
int k;
string str;
// 解密函数
string decryptionFunction(string eCode){
string dCode = "";
for(int i=0;i<eCode.length();i++){
int n = eCode[i] - 'a';
int m = (n-k+mod)%mod;
dCode += ('a'+m);
}
return dCode;
}
int main(){
cout<<"请输入明文和密钥:"<<endl;
while(cin>>str>>k){
string eCode = "";
for(int i=0;i<str.length();i++){
int n = str[i]-'a';
int m = (n+k)%mod;
eCode += ('a'+m);
}
cout<<"加密后的密文:"<<eCode<<endl;
cout<<"调用解密函数:"<<decryptionFunction(eCode)<<endl;
}
return 0;
}
仿射密码
仿射密码的话,加密过程和上述凯撒密码没多少区别,重在在于解密那一块。
首先,我们得到了密文编号 c
,怎么求得 m
呢?
m = ( c - 5 ) / 3
(mod 26)
但是这里会有一种情况要考虑,如果 c-5
的结果小于 3
,那么是不是 m
的值就为 0
,所以我们采用如下解决方式,让 m = (c-5) * X
(mod 26)这个 X
是 3
的逆元。我们调用求逆元函数,就可以得到 X
#include<bits/stdc++.h>
using namespace std;
const int mod = 26;
int k;
string str;
typedef long long ll;
// 拓展gcd
void exgcd(ll a,ll b,ll& d,ll& x,ll& y){
if(!b) { d = a; x = 1; y = 0; }
else{ exgcd(b, a%b, d, y, x); y -= x*(a/b); }
}
// 求逆元
ll inv(ll a, ll p){
ll d,x,y;
exgcd(a,p,d,x,y);
return d == 1 ? (x+p)%p : -1;
}
// 解密函数
string decryptionFunction(string eCode){
string dCode = "";
// 求逆元
int rev = inv(3,mod);
for(int i=0;i<eCode.length();i++){
int c = eCode[i] - 'a';
c = (c-5+mod)%mod;
int m = (c*rev)%mod;
dCode += ('a'+m);
}
return dCode;
}
int main(){
cout<<"请输入明文:"<<endl;
while(cin>>str){
string eCode = "";
for(int i=0;i<str.length();i++){
int n = str[i]-'a';
int m = (3*n+5)%mod;
eCode += ('a'+m);
}
cout<<"加密后的密文:"<<eCode<<endl;
cout<<"调用解密函数:"<<decryptionFunction(eCode)<<endl;
}
return 0;
}
学如逆水行舟,不进则退