我正在编写凯撒密码的代码,该密码通过密钥移动每个字母,似乎只要密钥大于 26,它就不起作用。任何想法将不胜感激。
我试过将密钥添加到原始字符,然后从中减去 90(z 的 ASCII 值),然后将该数字添加到 65(a 的 ASCII 值)。我将这些计算放在一个循环中,循环运行直到值小于或等于 90。这也不起作用,下面的代码是我尝试过的最接近工作的代码。 c 代表原始字符。 n 代表它被移动的键或数字。 NUMS_IN_ALPHA 的值为 26
例如:如果 c 是 'x' 并且 n 是 50,则 c 的最后一个字符应该是 'v' 但它给了我 �
c = c + n;
if (c > 'z') {
c = c - 'z' + 'a' - 1;
}
else if(c < 'a') {
c = c + NUMS_IN_ALPHA;
}
我刚刚更改了我的代码(现在如下所示),现在它适用于除大负数以外的所有内容。
例如:如果 c 是 'n' 并且 n 是 -28,则 c 的最后一个字符应该是 'l' 但它给了我 2
int val = c - 'a';
val = (val + n) % NUMS_IN_ALPHA;
c = 'a' + val;
可以使任何一段代码正常工作的提示都很棒。
您的写作思路是正确的
c = c - 'z' + 'a' - 1
:您将减去字母表的长度以使c
回到该范围内。但是,您希望 'z' - 'a'
获得字母表的长度,而不是 'z' + 'a'
。
此外,
'z' - 'a'
将得到 25,而不是 26。因此您还需要在该减法中加一。
如果
c
在字母表范围 (c < 'a')
下,您将执行相同的计算,只是将其添加到 c
而不是从中减去。
char shift(char c, int n) {
// perform shift
int c2 = c + n;
// value is over range
if (c2 > 'z') {
c2 = c2 - ('z' - 'a' + 1);
}
// value is under range
else if (c2 < 'a') {
c2 = c2 + ('z' - 'a' + 1);
}
}
通过使用模数运算符 (
%
) 代替此 if/else 子句设置,您肯定可以采取一些捷径。