仿射密码(代换密码)

1、基本概念

加法密码和乘法密码结合就构成仿射密码,仿射密码的加密和解密算法是:CEk(m)=(k1*m+k2) mod n

加密过程:c=E(p)=(a*p+b)mod26
解密过程:p=D(c)=((c-b)*(a的逆))mod26
MDk(c)=k3(ck2) mod n(其中(k3 ×k1)mod26 = 1)仿射密码具有可逆性的条件是gcd(k1n)=1。当k1=1时,仿射密码变为加法密码,当k2=0时,仿射密码变为乘法密码。仿射密码中的密钥空间的大小为nφ(n),当n为26字母,φ(n)=12,因此仿射密码的密钥空间为12×26 = 312。仿射密码是一种代换密码。密钥有两个、由0-25的整数数组成,是一种线性代换密码。和凯撒密码都是代换密码!

2、加密例子

例如我们想对字符串"test"进行加密,首先我们将字符串"test"拆分为单个字符.字符加密算法如下:
int encryption(char * plaintext,char *ciphertext,int a,int b){  
	
	int strLength = strlen(plaintext);
	int i=0;
	for(;i<strLength;i++){
		if(plaintext[i]==' '){
			ciphertext[i]=plaintext[i];
		}
		else{
			ciphertext[i] = ((plaintext[i]-'a')*a+b)%26+'a';
		}
	}
	ciphertext[i]='\0';
	return 0;
}
以上函数plaintext表示明文,ciphertext表示密文,a,b代表密钥对、取值范围为0-25,在仿射密码中要求a 和26的最大公约数为1 也就是a和26是互素的,如果不能保证其互素性则不能保证能够正确解密。通过以上代码对字符串“test”加密得到的结果是"gfzg” 。在此之前需要检查a和26是否互素。 以下代码判断两个数是否互素
int Stein_GCD(int x, int y)   //求最大公约数
{
    if (x == 0) return y;
    if (y == 0) return x;
    if (x % 2 == 0 && y % 2 == 0)
        return 2 * Stein_GCD(x >> 1, y >> 1);
    else if (x % 2 == 0)
        return Stein_GCD(x >> 1, y);
    else if (y % 2 == 0)
        return Stein_GCD(x, y >> 1);
    else
        return Stein_GCD(min(x, y), fabs((double)x-y));
}

3、解密例子

通过以上方法将字符串"test"进行加密得到的结果为"gfzg",使用以下方法对其进行解密得到明文字符串"test",以下为解密代码:
int decryption(char *ciphertext,char * plaintext,int a,int b){
	
	int strLength = strlen(ciphertext);
	int i=0;
	int num=0;
	for(i=0;i<strLength;i++){
		
		if(ciphertext[i]==' '){
			plaintext[i]=ciphertext[i];
		}
		else{
		if((((ciphertext[i]-'a')-b)*IntegerInverse(a))<0){
			num=26-abs((((ciphertext[i]-'a')-b)*IntegerInverse(a)))%26;
			plaintext[i] = num+'a';
		}else{
		
			plaintext[i] = (((ciphertext[i]-'a')-b)*IntegerInverse(a))%26+'a';
		}
		}
	}
	plaintext[i]='\0';
	return 0;
}
参数表示的含义和加密过程中表示的含义相同。在解密事用到a的逆,以下代码实现求a的模26的逆运算。
int IntegerInverse(int num){  //求一个数的模26的逆
	for(int i=0;i<MAX;i++){
		if((i*num)%26==1){
			return i;
		}
	}
	return -1; 
}

4、加解密演示

加解密代码演示

5、完整代码

#include <iostream>
#include "math.h"
#include "string.h"
#define MAX 10000
using namespace std;

int Stein_GCD(int x, int y)   //求最大公约数
{
    if (x == 0) return y;
    if (y == 0) return x;
    if (x % 2 == 0 && y % 2 == 0)
        return 2 * Stein_GCD(x >> 1, y >> 1);
    else if (x % 2 == 0)
        return Stein_GCD(x >> 1, y);
    else if (y % 2 == 0)
        return Stein_GCD(x, y >> 1);
    else
        return Stein_GCD(min(x, y), fabs((double)x-y));
}


int IntegerInverse(int num){  //求一个数的模26的逆
	for(int i=0;i<MAX;i++){
		if((i*num)%26==1){
			return i;
		}
	}
	return -1; 
}

int encryption(char * plaintext,char *ciphertext,int a,int b){  
	
	int strLength = strlen(plaintext);
	int i=0;
	for(;i<strLength;i++){
		if(plaintext[i]==' '){
			ciphertext[i]=plaintext[i];
		}
		else{
			ciphertext[i] = ((plaintext[i]-'a')*a+b)%26+'a';
		}
	}
	ciphertext[i]='\0';
	return 0;
}

int decryption(char *ciphertext,char * plaintext,int a,int b){
	
	int strLength = strlen(ciphertext);
	int i=0;
	int num=0;
	for(i=0;i<strLength;i++){
		
		if(ciphertext[i]==' '){
			plaintext[i]=ciphertext[i];
		}
		else{
		if((((ciphertext[i]-'a')-b)*IntegerInverse(a))<0){
			num=26-abs((((ciphertext[i]-'a')-b)*IntegerInverse(a)))%26;
			plaintext[i] = num+'a';
		}else{
		
			plaintext[i] = (((ciphertext[i]-'a')-b)*IntegerInverse(a))%26+'a';
		}
		}
	}
	plaintext[i]='\0';
	return 0;
}

int main()
{
	int a,b;
	char *plainText=new char(100);
	char *ciphertext=new char(100);
	
	cout<<"请输入密钥对:"<<endl;
	cin>>a>>b;
	
	if(Stein_GCD(a,26)==1){
		cout<<"请输入明文"<<endl;
		getchar();
		gets(plainText);   //输入了明文
		encryption(plainText,ciphertext,a,b);
		cout<<"加密得到的密文为:"<<ciphertext<<endl;
		decryption(ciphertext,plainText,a,b);
		cout<<"解密得到的明文为:"<<plainText<<endl;
	}else{
		cout<<"无法进行加密操作"<<endl;
	}
	getchar();
	getchar();
	return 0;
}

6、总结

最近一直研究网络安全相关知识,关于加解密算法会一直持续更新


  • 6
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值