解密在java (caesarCipher) 错误结果

Decryption in java (caesarCipher) wrong result

我写了简单的凯撒密码算法,加密效果很好,但是当我想解密单词时,我得到了错误的结果。例如,密钥为 15 的“PQRO”应该是“ABCZ”,但我得到 "ABCB".

public static void decrypt(String text, int k) {
    char[] tAlf = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
    char[] tChar = text.toCharArray();
    for (int i = 0; i < tChar.length; i++) {
        for (int j = 0; j < tAlf.length; j++) {
            if (text.charAt(i) == tAlf[j]) {
                System.out.print(tAlf[(Math.abs(j-k)) % 26]);
            }
        }
    }
}

看起来算法无法在字母表中倒退到 'Z'。

这里的技巧是理解数学运算。

首先,%不是取模运算,是取余运算,也就是说结果可能是负数

abs 将从负值创建正值。但这与用负值抵消问题不同,因为它会映射到例如-1 到 1 而不是 25。

所以您可以做的是创建一个实际的模运算。在 Java 即:

int mod(int x, int n) {
    return ((x % n) + n) % n;
}

这应该可以解决您的问题。


至于调试,您应该始终从将事情分成更小的部分开始。将 Math.abs(j-k)) % 26 带出数组索引并将其分配给例如一个整数 newIndex 变量,因此您实际上可以看到中间结果。更好的是:尝试创建单独的方法,例如 int charToIndex(char c)char indexToChar(int i),以便您可以单独测试它们。