问题描述:输入密钥K的值,加密算法:e(x)=x+k(mod 26)。即当前明文字母顺序(如A为1)加上K值之后对应的字母即为密文。解密算法:d(y)=y-k(mod 26)。与加密相反,解密是当前密文字母顺序减去K值对应的字母即为明文。26即26个英文字母。
例:输入:abc
输出:def
代码:求得的密文和解密出的明文均以小写输出
#define _CRT_SECURE_NO_WARNINGS 1
//移位密码体制
#include<stdio.h>void menu() {printf("-------移位密码体制--------\n");printf("------- 1. 加密 --------\n");printf("------- 2. 解密 --------\n");printf("------- 0. 退出 --------\n");
}void encryption_and_decryption(int input) {int k = 0;int count = 0;printf("请输入秘钥值:->");scanf("%d", &k);getchar(); //吸收输入秘钥值后敲的回车char str[100] = { 0 };//最长加密解密长度为100if (input == 1) { //执行加密算法printf("请输入明文:");}else //执行解密算法{printf("请输入密文:");}for (int i = 0; i < 100; i++) {scanf("%c", &str[i]);count++;if (str[i] == '\n') { //回车代表输入结束count--; //减去多接收的回车符break;}}for (int i = 0; i < count; i++){if (str[i] >= 'A' && str[i] <= 'Z') { //将大写转换为小写str[i] += 32;}//if (str[i] == 32) { //将输入中的空格保留// str[i] = ' ';//}else {if (input == 1) {str[i] = (str[i] - 'a' + k + 26) % 26 + 'a'; //加密算法,加‘a'是为了将ASCII值转换为字符存储}else{str[i] = (str[i] - 'a' - k + 26) % 26 + 'a'; //解密算法,括号中加26是为了保证正数}}}if (input == 1) {printf("生成密文是:");}else {printf("解密明文是:");}for (int i = 0; i < count; i++){printf("%c", str[i]);}printf("\n");
}void test() {int input = 0;do {menu();printf("请选择:->");scanf("%d", &input);switch (input){case 1:encryption_and_decryption(input);//传input值确定该算法是实行加密还是解密break;case 2:encryption_and_decryption(input);break;case 0:printf("已退出加密解密系统\n");break;default:printf("输入有误,请重新输入!\n");break;}} while (input);
}int main() {test();return 0;
}
上述代码中我将输入空格格式保留的代码注释了,当初写出那段代码想的是用户输入明文或密文中如有空格在转换后我也可以很好的将空格保留输出,比较美观。但是后期跟老师交流知道,真正加密中明文是不会有空格出现的,因为这样就告诉了“敌人”语句的断句,更容易破解,更不安全。
运行结果截图:
如果上述加密解密算法括号中没有多加上26,运行截图就会发生以下改变:
这是因为密文是‘b’,ASCII值比‘a’多1,解密算法是 str[i] = (str[i] - 'a' - k ) % 26 + 'a',括号运算得的结果是-2,对26取余数还是-2,这时加上‘a’,对应下面的ASCII表知道‘a’往前两位就是截图中的‘_’。
如果内容对你有帮助,关注我,给我点个小小的赞吧!
若内容有误,请指正并多多包容,谢谢。