目录+源码

该博客详细介绍了古典密码学的各种加密方法,包括仿射密码、维吉尼亚密码、PLAYFAIR、ADFGX和HILL加密。进一步讨论了序列密码如LFSR和RC4,以及A5算法。深入探讨了DES加解密的不同模式,如ECB、CBC、CFB、OFB和CTR,并对这些模式进行了比较。同时,提到了RSA公钥加密算法和MD5哈希函数。最后,博客中提供了综合实验的相关源码。
摘要由CSDN通过智能技术生成

目录
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

1.2维吉尼亚密码

#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

1.3 PLAYFAIR

#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

1.4 ADFGX

#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 

1.5 HILL加密

#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
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值