题目描述

凯撒加密算法Caesar
在密码学中,凯撒密码(英语:Caesar cipher),或称凯撒加密、凯撒变换、变换加密,是一种最简单且最广为人知的加密技术。它是一种替换加密的技术,明文中的所有字母都在字母表上向后(或向前)按照一个固定数目进行偏移后被替换成密文。例如,当偏移量是3的时候,所有的字母A将被替换成D,B变成E,以此类推。这个加密方法是以罗马共和时期恺撒的名字命名的,当年恺撒曾用此方法与其将军们进行联系。

​ 凯撒密码的替换方法是通过排列明文和密文字母表,密文字母表示通过将明文字母表向左或向右移动一个固定数目的位置。例如,当偏移量是左移3的时候(解密时的密钥就是3):
明文字母表:ABCDEFGHIJKLMNOPQRSTUVWXYZ
密文字母表:DEFGHIJKLMNOPQRSTUVWXYZABC

​ 当偏移量是3的时候,所有的字母A将被替换成D,B变成E,以此类推。
​ 使用时,加密者查找明文字母表中需要加密的消息中的每一个字母所在位置,并且写下密文字母表中对应的字母。需要解密的人则根据事先已知的密钥反过来操作,得到原来的明文。例如:
明文:THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG
密文:WKH TXLFN EURZQ IRA MXPSV RYHU WKH ODCB GRJ
​ 加密系统使用的秘诀是发送方和接收方需要知道加密用的偏移量,这个加密算法虽然现在看来特别容易破解,但是它刚开始使用的时候还是很安全的。
​ 未加密的文字称为明文plaintext. 加密后的文字称为密文ciphertext. 偏移的位置称为钥匙 key.
例如用钥匙1 加密HELLO 产生密文IFMMP:
​ plaintext H E L L O

​ key 1 1 1 1 1
​ = ciphertext I F M M P
​ 如果p是明文, pi 是p中第 ith 个 字符, k是密码(正整数),那么密文c中第i个字符 ci,的计算公式如下:
ci = (pi + k) % 26
​ 你可以把A看作一个数组的第一个元素 (下标是0), B 的下标是 1, …, Z 的下标就是25. 假设明文p是Hi ,密钥 k 是 3. p0 是 H (aka 7), 下一个字符 p1, 是 i (aka 8). 密文的第一个字符c0, 是 K, 第二个字符 c1是 L.
​ 请写程序 Caesar.c 其功能是用 Caesar 加密算法给信息加密.用户输入的钥匙可能不是正整数,这时我们要求要求用户必须输入正整数作为密钥.
程序的运行如下例。密钥是1 ,明文是HELLO:
​ plaintext: HELLO
​ ciphertext: IFMMP
​ 明文是 hello, world,密钥是13时运行输入:
​ plaintext: hello, world
​ ciphertext: uryyb, jbeyq
注意:标点符号和空格不加密,只有文本加密! 小写字母保持小写,大写字母保持大写。
部分代码已经给出,请将to-list 中的5的任务完成,就可以实现以上任务。

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <stdio.h>
#include <string.h>
#include <windows.h>
// 清空输入缓冲区
void flushInputBuffer() {
int c;
while ((c = getchar()) != '\n' && c != EOF);
}

// 获取加密密钥
int get_key() {
int key;
printf("输入加密密钥(正整数): ");
scanf("%d", &key);

// 处理密钥的非正整数输入
while (key <= 0) {
printf("请输入正整数作为加密密钥: ");
scanf("%d", &key);
}

return key;
}

// 加密和解密函数
void change(char p[], char c[], int len, int key) {
for (int i = 0; i < len; i++) {
if (p[i] >= 'A' && p[i] <= 'Z') {
c[i] = 'A' + (p[i] - 'A' + key) % 26; // 加密大写字母
} else if (p[i] >= 'a' && p[i] <= 'z') {
c[i] = 'a' + (p[i] - 'a' + key) % 26; // 加密小写字母
} else {
c[i] = p[i]; // 保留非字母字符
}
}
c[len] = '\0'; // 在密文字符串的末尾添加空字符
}
// 检查解密后的文本是否与原始文本匹配
void check(char p[], char origin[]) {
if (strcmp(p, origin) == 0) {
printf("加密正确。\n");
} else {
printf("加密不正确。\n");
}
}

int main() {
system("chcp 65001");
int key = get_key();
char p[100], c[100];

// 获取输入
flushInputBuffer();
printf("请输入明文:");
fgets(p, sizeof(p), stdin);

// 处理输入的换行符
int len = strlen(p);
if (p[len - 1] == '\n') {
p[len - 1] = '\0';
len--;
}
// 加密
change(p, c, len, key);

// 显示加密后的结果
printf("密文是: %s", c);

// 解密
char origin[100];
change(c, origin, len, 26 - key);

// 显示解密后的结果
printf("原始文本是:\n%s\n", origin);

// 检查加密是否正确
check(p, origin);

return 0;
}

屎山——不倒就是山,倒了才是屎