0

So I am making a Caesar cipher program I have the encryption working just fine it is the decryption I am having trouble with.

Here is the code that works for encryption on uppercase letters:

        if (isupper(p[i])){
    char c = ((p[i] - 'A') + k % 26) + 'A';
     }

Now I would think that decryption would be:

        if (isupper(pp[i])){
    char c = (abs((p[i] - 'A') - k) % 26) + 'A';
     }

The issue that I'm having is that if k=1 and p[i]='A' it will just output the letter 'B' and not 'Z' it does not wrap around like it should so if k=2 and p[i]='A' it should output the letter 'Y'. It works if k=1 and p[i]='B' it will output 'A' thanks for any help.

4

3 回答 3

1

这应该这样做:

if (isupper(p[i])){
    char c = (p[i] - 'A' + 26 - k) % 26) + 'A';
}

+ 26给你你的包装

可以这样想(三位数的格式只是为了让事情排列整齐):

| 000 | 001 | 002 | ... | 024 | 025 | plain
|  A  |  B  |  C  | ... |  Y  |  Z  |
| 003 | 004 | 005 | ... | 001 | 002 | crypto

现在,认识到

(n + 26) % 26 === (n % 26)

所以:

| 000 | 001 | 002 | ... | 024 | 025 | plain
|  A  |  B  |  C  | ... |  Y  |  Z  |
| 029 | 030 | 031 | ... | 053 | 054 | crypto

当您考虑模 26 时,等效于上述情况

这让生活变得轻松了很多。明文符号集由从'A'到的一组连续整数组成'A' + 25。问题是密文符号集不连续......在025. 通过添加 26,您可以将密文转换为从'A' + k + 26到的连续范围'A' + k + 49

然后将连续密文符号集映射到明文符号集要容易得多。

由于凯撒代码可能是任一方向的偏移,而解密只是相反的偏移,您可以将其结合起来

boolean decrypt;
int k; 
...
k = k % 26; // Ensure that the shift doesn't include any wrapping
if(decrypt) {
    k *= -1;
}
if (isupper(p[i])){
    char c = (p[i] - 'A' + 26 + k) % 26) + 'A';
}
于 2012-10-18T21:56:21.283 回答
0

在加密中,

((p[i] - 'A') + k % 26) + 'A'

认为它被评估为

t1 = p[i] - 'A'
t2 = k % 26
result = t1 + t2 + 'A'

这可能不是你想要的。解密不会逆转该算术,主要是因为额外的分组改变了操作的顺序。

于 2012-10-18T21:51:00.833 回答
0

你没有考虑他们环绕的事实,试试这样:

if ((p[i] - 'A' - k) < 0 )
    c = 'Z' - (abs(p[i] - 'A' - k) % 26) + 1;
else 
    c = (abs(p[i] - 'A' - k) % 26) + 'A';

而且我认为您也不需要模数“%”。

于 2012-10-18T21:55:03.750 回答