C语言凯撒密码算法问题:大密钥处理异常
解决凯撒密码大密钥处理的乱码问题
嘿,我看到你在处理凯撒密码大密钥时遇到了奇怪的乱码输出,咱们来一步步搞定这个问题~
问题根源
你看到的错误输出}ääç oçèä|,本质是两个核心问题导致的:
- 大密钥未做模运算处理:凯撒密码基于26个英文字母循环,密钥超过26时,实际等效于
密钥 % 26(比如50 mod 26 = 24,加50和加24的加密效果完全一致)。直接用50这类大密钥会让字符值超出字母的ASCII范围,再加上unsigned char的溢出特性(数值超过255会绕回),最终变成扩展ASCII字符,显示成乱码。 - 溢出后的范围判断失效:你的原代码用
if (shifting > 'z')来判断是否超出字母范围,但当unsigned char溢出后(比如密钥过大导致数值绕回至小于'a'的区间),这个判断逻辑就完全失效了。
修复后的代码
我修改了你的代码,解决了上述问题,同时优化了逻辑的简洁性和可靠性:
#include <stdio.h> #include <ctype.h> // 使用标准字符判断函数,更规范 int main() { char array[100]; int z; printf("This tiny application encodes plain text to the Caesar Encryption\n"); printf("Type in some text to encode :"); fgets(array, 100, stdin); printf("Type in the key/shifting of the letters:\n"); scanf("%d", &z); // 处理密钥:转换为0-25的有效范围,同时支持负数密钥(解密场景) z = z % 26; if (z < 0) { z += 26; } for (int i = 0; array[i] != '\0'; i++) { // 只处理字母字符,空格、换行等非字母内容保持原样 if (isalpha(array[i])) { if (islower(array[i])) { // 小写字母:用模运算直接实现循环,避免溢出问题 array[i] = 'a' + (array[i] - 'a' + z) % 26; } else { // 大写字母同理 array[i] = 'A' + (array[i] - 'A' + z) % 26; } } } printf("Encrypted text: %s\n", array); return 0; }
关键修改点说明
- 密钥模26处理:不管输入的密钥是50、100还是负数,都会转换成0-25之间的有效偏移,从根源避免了字符溢出问题。
- 用模运算替代范围判断:
'a' + (array[i] - 'a' + z) %26的逻辑直接计算出循环后的字母位置,不需要额外判断是否超出范围,简洁又可靠。 - 使用标准字符函数:
isalpha、islower比直接判断ASCII范围更规范,也能兼容不同编码环境。 - 保留非字母字符:空格、换行符等非字母内容不会被修改,符合凯撒密码的常规行为。
测试验证
用你的测试案例:文本Hello World,密钥50(等效于24),加密后会得到正确结果:
Fcjjm Umpjb
你可以运行修复后的代码试试,结果就正常啦~
内容的提问来源于stack exchange,提问作者Private Joker
相关产品推荐
相关产品推荐

