解密在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)
,以便您可以单独测试它们。
我写了简单的凯撒密码算法,加密效果很好,但是当我想解密单词时,我得到了错误的结果。例如,密钥为 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)
,以便您可以单独测试它们。