我正在尝试在Java中实现明文Feistel Cipher,我使用硬编码的“字母”数组为原始明文消息的每个字符分配数值。我的问题是,一旦我将函数应用于右半部分并且向左应用XOR,我有时会留下一个超出我的'alphabet'数组范围的数字。
这是字母数组:
public static char[] alphabet = new char[] {'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', ' '};
这是功能:
private static int function(int character, int key, int roundNumber) {
return (2 * roundNumber * key * character) % 26;
}
这是用于加密的代码块:
for(int r = 1; r <= rounds; r++) {
String str1 = "";
String str2 = "";
// looping through left half and applying XOR with function
for(int i = 0; i < midpoint; i++){
leftHalf[i] ^= (function(rightHalf[i], KEY, r));
System.out.println(leftHalf[i]);
// turn left half numbers back to chars
str1 += alphabet[leftHalf[i]];
}
// turning right half numbers back to chars
for (int i = 0; i < rightHalf.length; i++) {
str2 += alphabet[rightHalf[i]];
}
System.out.println("ENCIPHER-" + r + " " + str1 + str2);
temp = leftHalf; leftHalf = rightHalf; rightHalf = temp; // swap after
KEY++;
}
错误发生在这一行:
str1 += alphabet[leftHalf[i]];
我已经尝试了%left the leftHalf [i]编号,以便它适合字母数组,但这会破坏密码点,我无法破译它。
我也尝试了几种不同的功能,但我认为它主要与XOR有关。有没有办法确保XOR将返回字母数组边界内的某些内容,或者我是否以错误的方式处理这整个事情?任何帮助表示赞赏。
另外,错误代码:
Please enter a message to be encrypted: hello there
Please enter number of encryption rounds between 1 and 20: 5
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 31
at com.company.FeistelCipher.main(FeistelCipher.java:94)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
[7][4][11][11][14][26][26][19][7][4][17][4]
Original Message: hello there
5
24
31
Process finished with exit code 1
答案 0 :(得分:0)
很确定我能够搞清楚。因此,由于字母数组中最高的数组索引是26,这意味着XOR最高为5位操作(二进制为10111)。使用5位时,XOR将产生的最大数量为31(二进制为11111)。所以我只是在字母数组中添加了5个冗余的,未使用的小写字母,使其长度为31.然后我只需要确保函数返回5位以内的数字,这就是模数的含义。
新阵列:
public static char[] alphabet = new char[] {'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', ' ', 'a', 'b', 'c', 'd', 'e', 'f'};
新功能:
private static int function(int character, int key, int roundNumber) {
return (2 * roundNumber * key * character) % 23;
}
%26的旧功能很好,但%23给了我更好的加密结果。无论哪种方式,它们都低于5位或低于5位。