【现代密码学】-网络安全实验:移位、仿射、乘数密码加解密

现代密码学基础——移位、仿射、乘数的加解密
1.实验内容
自选一种编程语言,实现古典密码中多项式代换密码的加解密过程。由于多项式代换密码可一般化移位密码、乘数密码、仿射密码,分别对多项式代换密码参数进行设置,完成这三个特例的实现。
多项式代换密码加密方程为:
f (l)=ktl t+kt-1l t-1+…+k1l +k0 mod q。
其中,kt, …, k0Zq,lZq。

#include <stdio.h>
#include<stdlib.h>
int euclidean(int d, int f);
#define MAX 100
#define YIWEI 3
#define	YIWEI2 3

void yiweijiami()//移位密码加密函数
{
	char C[MAX];
	char M[MAX];
	int K = YIWEI, i;
	printf("请输入明文M(不可输入空白串)\n");
	//gets_s(M + 1, 20);
	scanf_s("%s", M,20);
	for (i = 0; M[i] != '\0'; i++)
	{
		C[i] = (M[i] - 'a' + K) % 26 + 'a';
	}
	C[i] = '\0';
	printf("加密后的密文是:\n%s\n", C);
}
void yiweijiemi()//移位密码解密函数
{
	char C[MAX];
	char M[MAX];
	int K = YIWEI, i;
	//解密
	printf("请输入密文C(不可输入空白串)\n");
	//gets_s(C + 1, 20);
	scanf_s("%s", C,20);
	for (i = 0; C[i] != '\0'; i++)
	{
		M[i] = (C[i] - 'a' - K) % 26 + 'a';
	}
	M[i] = '\0';
	printf("解密后的明文是:\n%s\n", M);
}
void chengshujiami()//乘数加密算法
{
	char C[MAX];
	char M[MAX];
	int K = YIWEI, i;
	//加密
	printf("请输入明文M(不可输入空白串)\n");
	scanf_s("%s", M, 20);
	for (i = 0; M[i] != '\0'; i++)
	{
		C[i] = (M[i] - 'a')*K % 26 + 'a';
		//C[i] = (M[i] - 'a' + K) % 26 + 'a';
		//return (a - 'a') * secret % MOD_NUM + 'a';
	}
	C[i] = '\0';
	printf("加密后的密文是:\n%s\n", C);
	//printf("乘数加密");
}
void chengshujiemi()//乘数解密算法
{
	char C[MAX];
	char M[MAX];
	int K = YIWEI, i;
	//解密
	printf("请输入密文C(不可输入空白串)\n");
	scanf_s("%s", C, 20);
	for (i = 0; C[i] != '\0'; i++)
	{
		M[i] = (C[i] - 'a')* euclidean(K, 26) % 26 + 'a';
			//return (ciphertext - 'a') * euclidean(secret, MOD_NUM) % MOD_NUM + 'a';
		//M[i] = (C[i] - 'a' - K) % 26 + 'a';
	}
	M[i] = '\0';
	printf("解密后的明文是:\n%s\n", M);
	//printf("乘数解密");
}
int euclidean(int d, int f)//欧几里得算法 用于乘法逆元
{
	//1
	int x[3], y[3];
	x[0] = 1; x[1] = 0; x[2] = f;
	y[0] = 0; y[1] = 1; y[2] = d;
	//2
flag:	if (y[2] == 0)
	return -1; //null
		//3
		if (y[2] == 1)
			return y[1];
		//4
		int q = x[2] / y[2];
		int T[3] = { x[0] - q*y[0], x[1] - q*y[1], x[2] - q*y[2] };
		x[0] = y[0]; x[1] = y[1]; x[2] = y[2];
		y[0] = T[0]; y[1] = T[1]; y[2] = T[2];
		goto flag;
}
void fangshejiami()//仿射密码加密
{
	char C[MAX];
	char M[MAX];
	int K = 5;
	int i;
	int z = 0;
	int K2 = 8;
	//int K = YIWEI, i;
	//int K2 = YIWEI2;
	//加密
	printf("请输入明文M(不可输入空白串)\n");
	scanf_s("%s", M, 20);
	for (i = 0; M[i] != '\0'; i++)
	{
		if (M[i] >= 'A' && M[i] <= 'Z')
		{
			C[z] = (K*(M[i] - 'A') + K2) % 26 + 'A';
		}
		else if (M[i] >= 'a' && M[i] <= 'z')
		{
			C[z] = (K*(M[i] - 'a') + K2) % 26 + 'a';
		}
		else
		{  //判断是否是空格
			C[z] = M[i];
		}
		z++;
	}
		//C[i] = (M[i] - 'a' + K) % 26 + 'a';
		
	C[i] = '\0';
	printf("加密后的密文是:\n%s\n", C);
	//printf("乘数加密");
	//printf("仿射加密");
}
void fangshejiemi()//仿射密码解密
{
	char C[MAX];
	char M[MAX];
	int K = 5;
	int i;
	int z = 0;
	int K2 = 8;
	int K3 = 21;
	//int K = YIWEI, i;
	//int K2 = YIWEI2;
	//解密
	printf("请输入密文C(不可输入空白串)\n");
	scanf_s("%s", C, 20);
	for (i = 0; C[i] != '\0'; i++)
	{
		if (C[i] >= 'A' && C[i] <= 'Z')
		{
			M[z] = (K3*((C[i] - 'A') - K2)) % 26 + 'A';
			if (K3*((C[i] - 'A') - K2) < 0)
			{
				M[z] = M[z] + 26;
			}
		}
		else if (C[i] >= 'a' && C[i] <= 'z'){
			M[z] = (K3*((C[i] - 'a') - K2)) % 26 + 'a';
			if (K3*((C[i] - 'a') - K2) < 0){  //处理负数
				M[z] = M[z] + 26;
			}
		}
		else{  //判断是否是空格
			M[z] = C[i];
		}
		z++;
	}
	
	//C[i] = (M[i] - 'a' + K) % 26 + 'a';

	M[i] = '\0';
	printf("加密后的明文是:\n%s\n", M);
	//printf("乘数加密");
	//printf("仿射加密");
	//printf("仿射解密");
}
void choose1()//首页选择界面
{
	int test1 = 1;
	while (test1)
	{
		printf("\n请输入选择(1:移位密码 2:乘数密码 3:仿射密码 0:退出)\n");
		int n;
		scanf_s("%d",&n);
		if (n == 1)
		{
			int test = 1;
			while (test)//对于菜单的选择
			{
				printf("\n请输入选择(1:加密  2:解密  0:退出):\n");
				int n;
				scanf_s("%d",&n);
				if (n == 1)
				{
					yiweijiami();
				}
				else if (n == 2)
				{
					yiweijiemi();
				}
				else if (n == 0)
				{
					printf("欢迎使用!!\n");
					test = 0;
					choose1();
				}
				else
				{
					printf("输入错误!\n请重新输入!");
					choose1();
				}
			}
		}
		else if (n == 2)
		{
			int test = 1;
			while (test)//对于菜单的选择
			{
				printf("\n请输入选择(1:加密  2:解密  0:退出):\n");
				int n;
				scanf_s("%d", &n);
				if (n == 1)
				{
					chengshujiami();
				}
				else if (n == 2)
				{
					chengshujiemi();
				}
				else if (n == 0)
				{
					printf("欢迎使用!!\n");
					test = 0;
					return;
				}
				else
				{
					printf("输入错误!\n请重新输入!");
					choose1();
				}
			}
		}
		else if (n == 3)
		{
			int test = 1;
			while (test)//对于菜单的选择
			{
				printf("\n请输入选择(1:加密  2:解密  0:退出):\n");
				int n;
				scanf_s("%d", &n);
				if (n == 1)
				{
					fangshejiami();
				}
				else if (n == 2)
				{
					fangshejiemi();
				}
				else if (n == 0)
				{
					printf("欢迎使用!!\n");
					test = 0;
					return;
				}
				else
				{
					printf("输入错误!\n请重新输入!");
					choose1();
				}
			}
		}
		else if (n == 0)
		{
			printf("欢迎使用!!\n");
			test1 = 0;
			return;
		}
		else
		{
			printf("输入错误!\n请重新输入!");
			choose1();
		}
	}
	
}
int main()
{
	choose1();//调用选择界面函数
	return 0;
}

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
仿射密码是一种基于数学原理的加密算法,它可以通过随机生成密钥a、b来加密和解密任意满足条件的数据。下面是一个基于C语言实现的仿射加密算法的示例代码: ```c #include <stdio.h> // 求两数的最大公约数 int gcd(int a, int b) { return b ? gcd(b, a % b) : a; } // 求a模N=26的逆 int exgcd(int a, int n) { int p = a, q = n; int x = 0, y = 1; int z = q / p; while (p != 1 && q != 1) { int t = p; p = q % p; q = t; t = y; y = x - y * z; x = t; z = q / p; } y %= n; if (y < 0) y += n; return y; } // 加密函数 void encrypt(char *plaintext, char *ciphertext, int a, int b) { int i; for (i = 0; plaintext[i] != '\0'; i++) { if (plaintext[i] >= 'a' && plaintext[i] <= 'z') { ciphertext[i] = (a * (plaintext[i] - 'a') + b) % 26 + 'a'; } else if (plaintext[i] >= 'A' && plaintext[i] <= 'Z') { ciphertext[i] = (a * (plaintext[i] - 'A') + b) % 26 + 'A'; } else { ciphertext[i] = plaintext[i]; } } ciphertext[i] = '\0'; } // 解密函数 void decrypt(char *ciphertext, char *plaintext, int a, int b) { int i, a_inv = exgcd(a, 26); for (i = 0; ciphertext[i] != '\0'; i++) { if (ciphertext[i] >= 'a' && ciphertext[i] <= 'z') { plaintext[i] = (a_inv * (ciphertext[i] - 'a' - b + 26)) % 26 + 'a'; } else if (ciphertext[i] >= 'A' && ciphertext[i] <= 'Z') { plaintext[i] = (a_inv * (ciphertext[i] - 'A' - b + 26)) % 26 + 'A'; } else { plaintext[i] = ciphertext[i]; } } plaintext[i] = '\0'; } int main() { char plaintext[100], ciphertext[100], decrypted[100]; int a, b; printf("请输入密钥a和b(用逗号隔开):"); scanf("%d,%d", &a, &b); if (gcd(a, 26) != 1) { printf("密钥a必须与26互质!\n"); return 0; } printf("请输入明文:"); scanf("%s", plaintext); encrypt(plaintext, ciphertext, a, b); printf("加密后的密文为:%s\n", ciphertext); decrypt(ciphertext, decrypted, a, b); printf("解密后的明文为:%s\n", decrypted); return 0; } ``` 在这个示例代码中,我们定义了两个函数encrypt和decrypt,分别用于加密和解密数据。在加密时,我们将明文中的每个字符都转换为一个数字,然后使用公式(a * x + b) % 26来计算密文中的每个字符。在解密时,我们使用公式(a' * (y - b) % 26)来计算明文中的每个字符,其中a'是a模26的逆元。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值