密码学-1.仿射密码加解密(c++)

一.关键步骤:

(1) 加密:先将大小写转换成数字0-25,按照c=m*p+q%26进行加密

image-20210801185058524

加密结果如图所示

image-20210801185009312

(2) 解密:根据m=(c-q)*p-1,关键是求出密钥p的逆,代码如图

image-20210801185137273

解密结果如图1.4所示.

(3)破解:密钥空间为311,可以进行暴力破解,关键破解代码

image-20210801185224985

二.安全性分析:

仿射密码安全性较弱,抵抗不了穷举攻击

三.加密源码

#include<bits/stdc++.h>
using namespace std;
int main(){
	//c=a*p+q;
	int p,q,len,n,x;
	char a[9999],c;
	while(cin>>p){// 输入密钥p,q,明文a 
		cin>>q>>a;
		if((p%2==0)||(p==1&&q==0)){//p!=1&&q!=0,p需与26互素 
			cout<<"密钥不合法";
			break; 
		}
		len=strlen(a);
	for(int i=0;i<len;i++){//字母转成数字0-25 
		if(a[i]>=65&&a[i]<=90)
		    a[i]-=65;
		else if(a[i]>=97&&a[i]<=122)
		    a[i]-=97;
		x=a[i];
		cout<<x<<" ";}//将转成数字的明文输出 
		cout<<"密文如下"<<endl;	
		for(int i=0;i<len;i++){//加密n=a*p+q 
			n=p*a[i]+q;
			cout<<n<<" ";//输出加密后的数字 
			n=n%26+65;
		a[i]=n;
		} 
		cout<<endl;
		for(int i=0;i<len;i++)
		cout<<a[i]<<" ";//输出加密后的字母 
	} 
	return 0;
	} 

四.解密源码

#include<bits/stdc++.h>
using namespace std;
//n=a*p+q
int f(int p){//  求p的逆 ; 
	int m,k,r,d,i;
	int a[8][4]={0};
	a[0][0]=1,a[0][3]=1;
	k=p;
	m=26,r=1,d=0,i=0;
	while(r){//列表法求出逆 
		r=m%k;
		d=m/k;
		i++;
		a[i][0]=a[i-1][1];
		a[i][2]=a[i-1][3];
		a[i][1]=a[i-1][0]-a[i-1][1]*d;
		a[i][3]=a[i-1][2]-a[i-1][3]*d;
		m=k;
		k=r;				
	}
	if(a[i-1][3]<0)//如果逆小于0,加26 
	a[i-1][3]+=26;
	p=a[i-1][3];
	return p;
}
int main(){
	int n,p,q,len,k;
	char a[9999];
	while(cin>>p){
	    if(p%2==0||p==13)
		    {cout<<"密钥不合法,请重新输入"<<endl; 
			break; } 
		cin>>q>>a;
		len=strlen(a);
		
		//判断大小写 ,并转成数字0-25
		
		for(int i=0;i<len;i++){
			if(a[i]>=65&&a[i]<=90)
			    a[i]-=65;
			else if(a[i]>=97&&a[i]<=122)
			    a[i]-=97;	    
		n=a[i]-q;
		if(n<0)
		    n+=26;
		n=n*f(p);
		n=n%26+65;//由数字转成大写字母 
		a[i]=n;
		}
	for(int i=0;i<len;i++)//输出明文 
	cout<<a[i]<<" ";}
	return 0;
	}
posted @ 2021-08-01 18:56  1ink  阅读(1748)  评论(0编辑  收藏  举报