C#凯撒密码(Caesar Cipher)负偏移量加密结果异常求助
问题根因
C# 中的取模运算符%对负数运算时会返回负数结果,当使用负偏移密钥时,(ch + key) - d的计算结果为负数,模26后仍为负值,加上基准字符d(A或a)后结果不在字母ASCII范围内,因此输出不符合预期。
比如输入字符a(ASCII值97)、密钥-3时,计算过程为:(97-3 -97) %26 = -3%26 = -3,-3 +97 =94,对应字符不是预期的x,因此结果错误。
修复方案
只需要在计算偏移量时,对结果额外加26后再做一次取模,保证最终偏移值落在0~25的正整数区间即可,修改cipher方法的返回逻辑即可:
修改前的代码行:
return (char)((((ch + key) - d) % 26) + d);
修改后的代码行:
return (char)(((((ch + key) - d) % 26) + 26) % 26 + d);
你也可以选择先对密钥做预处理,把任意大小的密钥统一转换为0~25的正偏移,避免重复计算:
// 预处理密钥,兼容正负值和超过26的大偏移 key = (key % 26 + 26) % 26;
修改后的完整可运行代码
Console.WriteLine("Type a string to encrypt:"); string UserString = Console.ReadLine(); Console.WriteLine("\n"); Console.Write("Type in the position:"); int key = Convert.ToInt32(Console.ReadLine()); // 可选:提前预处理密钥,兼容所有范围的密钥输入 // key = (key % 26 + 26) % 26; Console.WriteLine("\n"); Console.WriteLine("Encrypted Data"); string cipherText = Encipher(UserString, key); Console.WriteLine(cipherText); Console.Write("\n"); char cipher(char ch, int key) { if (!char.IsLetter(ch)) { return ch; } char d = char.IsUpper(ch) ? 'A' : 'a'; // 修复负数取模问题 return (char)(((((ch + key) - d) % 26) + 26) % 26 + d); } string Encipher(string input, int key) { string output = string.Empty; foreach (char ch in input) output += cipher(ch, key); return output; }
修改后输入字符串abcdefghijklmnopqrstuvwxyz、密钥-3时,输出结果为xyzabcdefghijklmnopqrstuvw,符合预期。
内容的提问来源于stack exchange,提问作者Aleksandar Yordanov
相关产品推荐
相关产品推荐

