C语言实现仿射密码

一.仿射密码

​ 仿射密码是一种古典密码,它是通过对明文中的每个字符进行数学变换来加密消息的。这种加密方法最初被使用于古罗马时期,凯撒密码就是一种简单的仿射密码。在现代密码学中,仿射密码已经不再被视为安全的加密方法,因为它容易受到各种攻击,如频率分析攻击和线性密码分析攻击。然而,仿射密码仍然具有教育意义,可以帮助初学者了解密码学的基本概念和技术。

二.基本原理

​ 仿射加密是一种基于数学运算的对称加密技术,其原理是使用一个仿射变换来对明文进行加密。

2.1加密

具体来说,仿射加密需要选择两个整数a和b作为加密密钥。加密过程中,先将明文中的每个字符对应到一个数字上(比如A对应0,B对应1等),形成一个数字序列。然后,对该数字序列中的每个数字x,执行下面的运算:

y = (ax + b) mod m

其中,m是字母表大小(比如26,如果只考虑大写字母的话),mod表示模运算,即取余数。这样得到的y就是该数字的加密结果。最后,将每个加密结果对应到相应的字母上(比如0对应A,1对应B等),就得到了加密后的密文。

2.2解密

解密过程与加密过程相似,也是选择两个整数a和b作为解密密钥,并将密文中的每个字符对应到一个数字上,再执行下面的运算:

x = a^-1(y - b) mod m

其中,a-1表示a的逆元,也就是满足aa-1 ≡ 1 (mod m)的整数。这样得到的x就是该数字的解密结果。最后,将每个解密结果对应到相应的字母上,就得到了原始的明文。

三.优缺点

3.1优点

  • 仿射密码简单易懂,容易实现和使用。

  • 加密速度快,因为使用的是基本的算术运算。

  • 支持多种语言,包括中文、英文等。

  • 提供了一定程度的安全保障,可以用于一些低级别的加密需求。

3.2缺点

  • 安全性较低,容易受到暴力破解和频率分析等攻击。

  • 密钥空间较小,只有 2626种可能的密钥。

  • 容易受到已知明文攻击。

  • 不支持数字和标点符号等特殊字符的加密。

总体而言,由于仿射密码的安全性相对较弱,因此在现代加密技术中很少被使用。

四.补充

4.1参数说明

仿射密码的解密过程中,存在求逆元这一步,而要使其逆元存在,基本要求是参数a必须与总字母数m互质

4.2字母表说明

abcdefghijklmnopqrstuvwxyz
012345678910111213141516171819202122232425

在本次实验中,我们定义每个字母代表的数字如上所示。

五.C语言实现

#include<stdio.h>
#include<string.h>

#define Maxsize 50    //定义最大传送信息量

//加密函数
void jiami(char *&p,int a,int b)
{
	printf("密文:");
	for(int i=0;i<strlen(p)-1;i++)
	{
		printf("%c",(char)(((p[i] + 'a' - 97*2)*a+b)%26+97));
	}
	printf("\n");
}

// 求逆元
int mod_inverse(int a, int m)
{
	int x, y, q, r1 = m, r2 = a, r, t1 = 0, t2 = 1, t;
	while (r2 > 0) {
		q = r1 / r2;
		r = r1 - q * r2;
		r1 = r2;
		r2 = r;
		t = t1 - q * t2;
		t1 = t2;
		t2 = t;
	}
	x = t1;
	if (x < 0) {
		x += m;
	}
	return x;
}

//解密函数
void jiemi(char *&q,int x,int b)
{
	printf("明文:");
	for(int i=0;i<strlen(q);i++)
	{
		printf("%c",(char)((((q[i]+'a'-97*2)-b)*x)%26+97));
	}
}

int main() 
{
	char str1[Maxsize],str2[Maxsize];
	char *p=str1,*q=str2;         //两个数组指针,分别代替明文、密文
	int a,b;
	printf("请输入明文:");
	fgets(str1, Maxsize, stdin);
	printf("请输入移位密匙系数1:");
	scanf("%d",&a);
	printf("请输入移位密匙系数2:");
	scanf("%d",&b);
	jiami(p,a,b);                    //加密测试
	printf("------------------");
	printf("\n");
	printf("请输入密文:");
	printf("\n");
	scanf("%s",str2);
	int x=mod_inverse(a,26);
	jiemi(q,x,b);                 //解密测试
}

六.实验结果

isUh.jpg

  • 8
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是使用C语言实现仿射密码的示例代码: ```c #include <stdio.h> #include <string.h> #include <ctype.h> int gcd(int a, int b) { if (b == 0) { return a; } else { return gcd(b, a % b); } } int mod_inverse(int a, int m) { int x0 = 1, x1 = 0, y0 = 0, y1 = 1; int r0 = a, r1 = m, q, r, x, y; while (r1 != 0) { q = r0 / r1; r = r0 % r1; x = x0 - q * x1; y = y0 - q * y1; r0 = r1; r1 = r; x0 = x1; x1 = x; y0 = y1; y1 = y; } if (r0 > 1) { return -1; } if (x0 < 0) { x0 += m; } return x0; } int is_valid_key(int k, int m) { return gcd(k, m) == 1; } void affine_encrypt(char *plaintext, int k, int b, char *ciphertext) { int i, x, y; for (i = 0; i < strlen(plaintext); i++) { if (isalpha(plaintext[i])) { x = toupper(plaintext[i]) - 'A'; y = (k * x + b) % 26; ciphertext[i] = 'A' + y; } else { ciphertext[i] = plaintext[i]; } } ciphertext[i] = '\0'; } int main() { char plaintext[100], ciphertext[100]; int k, b; printf("请输入明文:"); gets(plaintext); printf("请输入密钥k和b:"); scanf("%d%d", &k, &b); if (!is_valid_key(k, 26)) { printf("无效的密钥!\n"); return 0; } affine_encrypt(plaintext, k, b, ciphertext); printf("密文为:%s\n", ciphertext); return 0; } ``` 这个代码中,我们使用了两个辅助函数gcd和mod_inverse,分别用于求最大公约数和模反元素。is_valid_key函数用于检查密钥是否有效,即要求密钥k与模数26互质。affine_encrypt函数用于对明文进行加密,具体实现和前面介绍的算法类似。需要注意的是,这个程序只能处理大小写字母,如果要处理数字或其他字符,需要进行相应的修改。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

墨城烟柳ベ旧人殇

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

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

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

打赏作者

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

抵扣说明:

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

余额充值