古典密码----仿射密码加解密

理论部分

  • 仿射密码是移位密码的一个推广,其加密过程不仅包含移位操作,而且使用了乘法运算。与移位密码相同,仿射密码的明文空间M和密文空间C均为Z26,因此,在使用仿射密码体制对英文消息进行加密之前,需要在26个英文字母与Z26中的元素之间建立一一对应关系,然后才能应用仿射密码体制进行相应的加密计算和解密计算。

代码部分

C语言实现

#include <stdio.h>
#include <math.h>
#include<string.h>
#define N 200 

using namespace std;

void Affine(char *Input, char *Output, int length,int k1, int k2,int p){
	int km=k1,ka=k2;
	for(int i=0; i<length; i++){
  		if(Input[i]>='a'&&Input[i]<='z')
	  		Output[i]=(km*(Input[i]-'a')+ka)%p+'a';
		else
			if(Input[i]>='A'&&Input[i]<='Z')
				Output[i]=(km*(Input[i]-'A')+ka)%p+'A';
	  		else
	  			Output[i]=Input[i];
	}
	
	Output[length]='\0';//字符串时及时添加结束标志以防额外增加数组长度。 
	printf("The Input  Text is: %s.\n",Input);
//	fflush(stdin);
	printf("The Output Text is: %s.\n",Output);	
//	fflush(stdin);
} 

int EEA(int r0, int r1, int &r0_inverse, int &r1_inverse) {
	int R0=r0,R1=r1;
	if(r0==0 || r1==0){
		printf("ERROR: One of the two input numbers is zero.\n");
		return 0;
	}

	int q=0,r2=0,s0=1,s1=0,s2=0,t0=0,t1=1,t2=0;
	while(r1!=0){
		q=r0/r1;
		r2=r0%r1;
		s2=s0-s1*q;
		t2=t0-t1*q;
		//更新r0、r1、s0、s1、t0、t1 
		r0=r1;r1=r2;
		s0=s1;s1=s2;
		t0=t1;t1=t2;
	}
	//printf("THE GCD of R0 AND R1 IS: %d .\n", r0);
	//printf("Original s0 and t0: %d , %d.\n",s0,t0);
	if(r0==1){
		s0=(R1+(s0%R1))%R1;
		t0=(R0+(t0%R0))%R0;
		//printf("Afterwards [P+( x mod P)]mod P: s0 = %d ,t0= %d.\n",s0,t0);
		r0_inverse= s0;
		r1_inverse= t0;
		//printf("The inverse of %d mod %d is: %d\n",R1,R0,r1_inverse) ;
	}else{ 
		printf("THE GCD is: %d  UNEQUAL TO 1, NO INVERSE EXITS.\n",r0) ;
		return 1;
	} 
	return 0;
}

int main(){
 	int p =  26, k1, k2;//仿射密钥 c=k1*m+k2 mod p 古典密码p=26
	int p_, k_1, flag; 
 	char message[N + 1];
	do {
		flag = 0;
		printf("\nPlease input the three affine cipher parameters:k1,k2,p,以逗号分隔:"); 
	 	//读取数值时,默认以空格分隔,如需逗号则在%d后面指定格式:scanf("%d,%d",&k1,&k2);
		scanf("%d,%d,%d",&k1, &k2, &p);
	 	printf("\nThe input keys are: k1=%d , k2= %d, p= %d \n",k1,k2,p); 
		//getchar()在scanf()后,可以吸收回车符,以便输入下一个字符/串。特别是在后续需输入含空格的字符串时 
		getchar();
		flag = EEA(p, k1, p_, k_1);
		if (flag == 1)
			printf("输入的密钥无效,请重新输入!\n");
	} while(flag == 1);
	printf("Input the message to process:");
	//以回车(换行)作为字符串读取的结束,默认遇空格、回车、跳格键结束。 
	scanf("%[^\n]", message);
	printf("\nThe message/plaintext is:%s", message);
	int length = strlen(message);
 	char cipher[length], decipher[length];
	printf("对输入的文本进行加密处理:\n");
	printf("消息加密前后对比如下:\n");
	Affine(message, cipher, length, k1, k2, p);
	//补充解密部分
	printf("消息解密前后对比如下:\n");
	Affine(cipher, decipher, length, k_1, ((p - k2) * k_1) % 26, p);
	return 0;
}

运行结果截图

  • gcd为1
    在这里插入图片描述
  • gcd不为1
    在这里插入图片描述
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Len1Mi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值