用C语言设计一个设明文字母表为:p={p0,p1,…,pn-1}密文字母表:c={c0,c1,…,cn-1} 引入两个参数 a、b,要求a和n互素,即gcd(a,n)=1;加密算法:ci=E(Pi)=(a*pi+b)modn在解密时,首先需求解a在有限域Zn上的乘法逆元a-1∈Zn,可用欧几里得算法求解;解密算法:pi=D(ci)=a-1(ci-b)modn(1)取明文空间和密文空间为26个英文字母表,其大小为n=26;(2)求出集合{0,1,2,3,…,25}中所有与26互素的数,并从中任取一个,作为a。另外,任取b∈{0,1,2,3,…,25};输出a和b;(3)求出a在有限域Zn上的乘法逆元a-1∈Zn;(4)从键盘输入一个字符串,长度约为15字符。然后按照a b c d e f g h i j k l m n o p q r s t u v w x y z分别对应0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25的方式,将明文转换为数字序列(不区分大小写,并忽略空格);(5)对第(4)步得到的数字序列逐数字加密,得到密文数字序列;(6)按照第(4)步中的映射方式,将第(5)步得到的数字序列映射为字母序列(即密文),并输出密文;(7)按照第(4)步中的映射方式,将第(6)步得到的密文序列映射为数字序列;(8)按照解密算法,对第(7)步得到的数字序列逐数字解密,得到明文数字序列;(9)按照第(4)步中的映射方式,将第(8)步得到的数字序列映射为字母序列(即明文),并输出。
时间: 2023-06-13 18:08:14 浏览: 104
以下是用C语言实现的代码:
```c
#include <stdio.h>
#include <string.h>
// 求a在有限域Zn上的乘法逆元
int mod_inverse(int a, int n) {
int t, r, q, t1 = 0, t2 = 1, r1 = n, r2 = a;
while (r2 != 0) {
q = r1 / r2;
t = t1 - q * t2;
r = r1 - q * r2;
t1 = t2;
t2 = t;
r1 = r2;
r2 = r;
}
if (t1 < 0) {
t1 += n;
}
return t1;
}
// 加密函数
int encrypt(int p, int a, int b, int n) {
return (a * p + b) % n;
}
// 解密函数
int decrypt(int c, int a, int b, int n) {
int a_inv = mod_inverse(a, n);
return (a_inv * (c - b + n)) % n;
}
int main() {
int n = 26; // 字母表大小为26
int a, b;
int i, j;
// 求与26互素的数作为a
for (i = 1; i < n; i++) {
if (i % 2 == 0 || i % 13 == 0) {
continue;
}
a = i;
break;
}
// 随机选择b
b = 7;
printf("a = %d, b = %d\n", a, b);
// 输入字符串并转换为数字序列
char plaintext[16];
int plaintext_num[16];
printf("请输入明文(长度不超过15个字符):");
fgets(plaintext, 16, stdin);
plaintext[strcspn(plaintext, "\n")] = '\0'; // 去掉换行符
for (i = 0; i < strlen(plaintext); i++) {
if (plaintext[i] >= 'a' && plaintext[i] <= 'z') {
plaintext_num[i] = plaintext[i] - 'a';
} else if (plaintext[i] >= 'A' && plaintext[i] <= 'Z') {
plaintext_num[i] = plaintext[i] - 'A';
} else {
plaintext_num[i] = -1; // 非字母字符对应-1
}
}
// 加密明文数字序列得到密文数字序列
int ciphertext_num[16];
for (i = 0; i < strlen(plaintext); i++) {
if (plaintext_num[i] == -1) {
ciphertext_num[i] = -1; // 非字母字符不加密
} else {
ciphertext_num[i] = encrypt(plaintext_num[i], a, b, n);
}
}
// 将密文数字序列映射为密文
char ciphertext[16];
for (i = 0; i < strlen(plaintext); i++) {
if (ciphertext_num[i] == -1) {
ciphertext[i] = plaintext[i]; // 非字母字符不加密
} else {
ciphertext[i] = 'a' + ciphertext_num[i];
}
}
printf("密文:%s\n", ciphertext);
// 将密文序列映射为数字序列
for (i = 0; i < strlen(plaintext); i++) {
if (ciphertext[i] >= 'a' && ciphertext[i] <= 'z') {
ciphertext_num[i] = ciphertext[i] - 'a';
} else if (ciphertext[i] >= 'A' && ciphertext[i] <= 'Z') {
ciphertext_num[i] = ciphertext[i] - 'A';
} else {
ciphertext_num[i] = -1; // 非字母字符对应-1
}
}
// 解密密文数字序列得到明文数字序列
int plaintext_num2[16];
for (i = 0; i < strlen(plaintext); i++) {
if (ciphertext_num[i] == -1) {
plaintext_num2[i] = -1; // 非字母字符不解密
} else {
plaintext_num2[i] = decrypt(ciphertext_num[i], a, b, n);
}
}
// 将明文数字序列映射为明文
char plaintext2[16];
for (i = 0; i < strlen(plaintext); i++) {
if (plaintext_num2[i] == -1) {
plaintext2[i] = plaintext[i]; // 非字母字符不解密
} else {
plaintext2[i] = 'a' + plaintext_num2[i];
}
}
printf("解密得到的明文:%s\n", plaintext2);
return 0;
}
```
运行程序后,输入明文,即可得到加密后的密文和解密后的明文。
阅读全文