目录
1.古典密码
1.1仿射密码
1.2维吉尼亚密码
1.3 PLAYFAIR
1.4 ADFGX
1.5 HILL加密
2.序列密码
2.1 LFSR
2.2 RC4
2.3 A5
3.DES加解密
3.1 DES
3.2 DES-ECB
3.3 DES-CBC
3.4 DES-CFB
3.5 DES-OFB
3.6 DES-CTR
3.7 模式选用和比较
4.RSA加密
5.Hash函数(MD5)
6.综合实验
源码:
1.古典密码
1.1仿射密码
#include<bits/stdc++.h>
using namespace std;
int k1,k2,k;
string s;
char c;
int re()
{
for(int i=1;;i++)
if((i*k1)%26==1)
{
return i;
}
}
void encode(int x)
{
x=(k1*x+k2)%26;
c='A'+x-1;
cout<<c;
}
void decode(int x)
{
x=(x-k2)*k%26;
while(x<0) x+=26;
c='a'+x-1;
cout<<c;
}
int main()
{
cout<<"下标从1开始,加密输入小写字符,解密输入大写字母"<<endl;
while(1)
{
cout<<"请输入k1,k2 : ";
cin>>k1>>k2;
cout<<"请输入待处理的字符串 : ";
getline(cin,s);
getline(cin,s);
k=re();//计算k1的逆
for(int i=0;i<s.length();i++)
{
if(s[i]>='a'&&s[i]<='z')
encode(s[i]-'a'+1);
else if(s[i]>='A'&&s[i]<='Z') decode(s[i]-'A'+1);
else cout<<s[i];
}
cout<<endl;
}
return 0;
}
//k1=7 k2=10
//明文:please send moneys
//密文:RPSQMS MSDL WKDSCM
#include<bits/stdc++.h>
using namespace std;
int k1,k2,k,len,tip=0;
string key,s;
char c;
void encode(int x)
{
x=(s[x]-'a'+key[tip]-'a')%26;
c='A'+x;
cout<<c;
}
void decode(int x)
{
x=(s[x]-'A'-(key[tip]-'a'))%26;
while(x<0) x+=26;
c='a'+x;
cout<<c;
}
int main()
{
cout<<"下标从0开始,加密输入小写字符,解密输入大写字母"<<endl;
while(1)
{
tip=0;
cout<<"请输入密钥(小写) :";
getline(cin,key);
cout<<"请输入待处理的字符串 : ";
getline(cin,s);
len=key.length();
for(int i=0;i<s.length();i++)
{
if(s[i]>='a'&&s[i]<='z')
encode(i),tip++;
else if(s[i]>='A'&&s[i]<='Z') decode(i),tip++;
else cout<<s[i];
tip%=len;
}
cout<<endl;
}
return 0;
}
//密钥:encryption
//明文:public key distribution
//密文:THDCGR DMM QMFVIGQNBWBR
#include<bits/stdc++.h>
using namespace std;
struct node{
int x,y;
}post[30];//记录每个单词的位置
int bo[30];
string key,s;
char c,g[10][10];
void pre()//构造密码表
{
int i=0,j=0,t;
for(int k=0;k<key.length();k++) //关键词填充
if(key[k]>='a'&&key[k]<='z')
{
t=key[k]-'a';
if(bo[t]==0)//判断是否重复
{
bo[t]=1;
post[t].x=i;post[t].y=j;g[i][j]=t+'A';
j++;
if(j>=5) j=0,i++;
}
}
if(bo[9]) post[8].x=post[9].x,post[8].y=post[9].y;
for(int k=0;k<26;k++)
if(k!=9&&bo[k]==0&&!(k==8&&bo[9])) //剩余单词填充
{
bo[k]=1;
post[k].x=i;post[k].y=j;g[i][j]=k+'A';
j++;
if(j>=5) j=0,i++;
}
post[9].x=post[8].x,post[9].y=post[8].y;
}
int main()
{
cout<<"密钥(小写),明文(小写),密文(大写)"<<endl;
while(1)
{
cout<<"请输入密钥:";
getline(cin,key);
cout<<"请输入字符串:";
getline(cin,s);
cout<<"请输入事先约定好的一个字母: ";
cin>>c;
//
pre();
cout<<"输出密码表:"<<endl;
for(int i=0;i<5;i++)
{
cout<<" ";
for(int j=0;j<5;j++)
cout<<g[i][j];
cout<<endl;
}
for(int i=0;i<s.length();i++)
if(s[i]==' ')
s.erase(s.begin()+i);
/
int tip=0,top;
if(s[0]>='a'&&s[0]<='z')//加密
{
for(int i=0,j=1;j<s.length();)
{
if(s[i]==s[j]) s.insert(i+1,1,c);//重复字符,插入
i+=2;j+=2;
}
if(s.length()%2) s.insert(s.length(),1,c);
for(int i=0;i<s.length();i+=2)
{
int tx=post[s[i]-'a'].x,ttx=post[s[i+1]-'a'].x,ty=post[s[i]-'a'].y,tty=post[s[i+1]-'a'].y;
if(tx==ttx) //同行,取右边
{
cout<<g[tx][(ty+1)%5]<<g[tx][(tty+1)%5];
}
else if(ty==tty)//同列。取下面
{
cout<<g[(tx+1)%5][ty]<<g[(ttx+1)%5][ty];
}
else cout<<g[tx][tty]<<g[ttx][ty];//取两角
cout<<" ";
}
}
else
{
char tmp[100000];int tip=0;
for(int i=0;i<s.length();i+=2)
{
int tx=post[s[i]-'A'].x,ttx=post[s[i+1]-'A'].x,ty=post[s[i]-'A'].y,tty=post[s[i+1]-'A'].y;
if(tx==ttx)//同行,取左边
{
tmp[tip]=(char)(g[tx][(ty-1+5)%5]-'A'+'a');
tmp[tip+1]=(char)(g[tx][(tty-1+5)%5]-'A'+'a');
tip+=2;
}
else if(ty==tty)//同列,取上面
{
tmp[tip]=(char)(g[(tx-1+5)%5][ty]-'A'+'a');
tmp[tip+1]=(char)(g[(ttx-1+5)%5][ty]-'A'+'a');
tip+=2;
}
else //取反对角
{
tmp[tip]=(char)(g[tx][tty]-'A'+'a');
tmp[tip+1]=(char)(g[ttx][ty]-'A'+'a');
tip+=2;
}
}
if(tmp[tip]==c) tip--;
for(int i=0;i+2<tip;i++)
if(tmp[i]==tmp[i+2]&&tmp[i+1]==c)//重复字母,去掉插入字母
tmp[i+1]=' ';
for(int i=0;i<tip;i++)
if(tmp[i]>='a'&&tmp[i]<='z')
cout<<tmp[i];
}
cout<<endl;
memset(bo,0,sizeof(bo));
getline(cin,key);
}
return 0;
}
//密钥:fivestars
//明文:playfair cipher was actually
//密文:QK BW IT VA AS OK VB IG IC TA WT QZ KZ
//字母:q
//PPT:ch2 P42
#include<bits/stdc++.h>
using namespace std;
char g[6][6]={
{
' ','A','D','F','G','X'},
{
'A','p','g','c','e','n'},
{
'D','b','q','o','z','r'},
{
'F','s','l','a','f','t'},
{
'G','m','d','v','i','w'},
{
'X','k','u','y','x','h'}}; //字母表
struct node{
int x,y;
bool operator<(const node &a) const{
if(x==a.x) return y<a.y;
return x<a.x;
}
}t;
map<char,node>post,wei;
string s,key;
int main()
{
cout<<"输出密码表:"<<endl;
for(int i=0;i<=5;i++)
{
cout<<" ";
for(int j=0;j<=5;j++)
{
cout<<g[i][j]<<" ";
t.x=i;t.y=j;post[g[i][j]]=t;
}
cout<<endl;
}
post['A'].x=1;post['A'].y=1;
post['D'].x=2;post['D'].y=2;
post['F'].x=3;post['F'].y=3;
post['G'].x=4;post['G'].y=4;
post['X'].x=5;post['X'].y=5;//存储每个字母在字母表中的位置
cout<<"明文(小写),密文(大写),关键字(大写,不能有重复字母)"<<endl;
while(1)
{
cout<<"输入字符串:";
getline(cin,s);
cout<<"输入关键字:";
getline(cin,key);
for(int i=0;i<s.length();i++)//去空格
if(s[i]==' ')
s.erase(s.begin()+i);
for(int i=0;i<key.length();i++)
if(key[i]==' ')
key.erase(key.begin()+i);
if(s[0]>='a'&&s[0]<='z')//加密
{
第一步:代替
for(int i=0;i<s.length();)
{
int tx=post[s[i]].x,ty=post[s[i]].y;
s.erase(s.begin()+i);
s.insert(i,1,g[tx][0]);
s.insert(i+1,1,g[0][ty]);
i+=2;
}
//第二步:关键字标记
queue<char>q[30];//存储
char p[100000];
int len=key.length();
for(int i=0;i<len;i++)
{
p[i]=key[i];
int tmp=key[i]-'A';
for(int j=i;j<s.length();j+=len)
q[tmp].push(s[j]);
}
//排序,按列读
sort(p,p+len);
for(int j=0;j<len;j++)
while(q[p[j]-'A'].size())
{
if(q[p[j]-'A'].front()>='A'&&q[p[j]-'A'].front()<='Z')
cout<<q[p[j]-'A'].front();
q[p[j]-'A'].pop();
}
}
else//解密
{
queue<char>q[30];
char p[100000];
int len=key.length(),res;
map<char,int>po;
for(int i=0;i<len;i++)
p[i]=key[i],po[key[i]]=i;
sort(p,p+len);//关键字排序
res=s.length()%len;
for(int i=0,j=0;i<s.length()&&j<len;j++)//将密文分给不同的关键字字母
{
wei[p[j]].x=i;
if(po[p[j]]<res) wei[p[j]].y=i+s.length()/len;
else wei[p[j]].y=i+s.length()/len-1;
for(int k=wei[p[j]].x;k<=wei[p[j]].y;k++)
q[p[j]-'A'].push(s[k]);
i=wei[p[j]].y+1;
}
char tt[100000];int tip=0;
for(int i=0;i<s.length();)//矩阵行读
{
for(int j=0;j<len;j++)
if(q[key[j]-'A'].size())
{
if(q[key[j]-'A'].front()>='A'&&q[key[j]-'A'].front()<='Z')
tt[tip]=q[key[j]-'A'].front(),tip++,i++;
q[key[j]-'A'].pop();
}
}
for(int i=0;i<tip;i+=2)//通过行列找到明文
{
int tx=post[tt[i]].x,ty=post[tt[i+1]].y;
cout<<g[tx][ty];
}
}
cout<<endl;
}
return 0;
}
//明文:kaiser wilhelm
//关键字:RHEIN
//密文:FAGDFAFXFGFAXXDGGGXGXGDGAA
#include<bits/stdc++.h>
using namespace std;
int k[300][300],k1[300][300],t[300][300],tmp[300][300];
string s;
int n;
int main()
{
cout<<"输入 n = ";
cin>>n;
cout<<"请输入密钥(n*n矩阵):"<<endl;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
cin>>k[i][j];k[i][j]%=26;
}
cout<<"请输入字符串(长度为n*n ; 明文:小写):"<<endl;
getline(cin,s);
getline(cin,s);
for(int i=0;i<s.length();i++)//去空格
if(s[i]==' ')
s.erase(s.begin()+i);
for(int i=1;i<=n;i++)//明文分组排列
for(int j=1;j<=n;j++)
{
if(s[(n*(i-1))+j-1]>='a'&&s[(n*(i-1))+j-1]<='z')
tmp[i][j]=(s[(n*(i-1))+j-1]-'a')%26;
else tmp[i][j]=(s[(n*(i-1))+j-1]-'A')%26;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
t[i][j]=tmp[j][i];
if(s[0]>='a'&&s[0]<='z')//加密
{
for(int i=1;i<=n;i++)//矩阵乘
for(int j=1;j<=n;j++)
{
k1[i][j]=0;
for(int kk=1;kk<=n;kk++)
k1[i][j]=(k1[i][j]+k[i][kk]*t[kk][j])%26;
}
/
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cout<<(char)('A'+k1[j][i]);
}
else//解密
{
///求k的逆矩阵k1
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
k[i][j]=0;
for(int kk=1;kk