Java Feistel密码arrrayindexoutofbounds在函数F的XOR之后。

Java Feistel密码arrrayindexoutofbounds在函数F的XOR之后。,java,arrays,xor,feistel-cipher,Java,Arrays,Xor,Feistel Cipher,我试图在Java中实现一个明文Feistel密码,我使用一个硬编码的“字母表”数组为原始明文消息的每个字符分配数值。我的问题是,一旦我将函数应用于右半部分并与左半部分进行异或运算,我有时会留下一个超出“字母表”数组边界的数字 以下是字母表数组: public static char[] alphabet = new char[] {'a', 'b', 'c', 'd', 'e','f' ,'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', '

我试图在Java中实现一个明文Feistel密码,我使用一个硬编码的“字母表”数组为原始明文消息的每个字符分配数值。我的问题是,一旦我将函数应用于右半部分并与左半部分进行异或运算,我有时会留下一个超出“字母表”数组边界的数字

以下是字母表数组:

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;
}
  private static int function(int character, int key, int roundNumber) {
    return (2 * roundNumber * key * character) % 23;
}
这是一段用于加密的代码:

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++;
    }
我尝试了%26左半部[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

我很确定我能弄明白。因此,由于字母表数组中的最高数组索引是26,这意味着XOR在其最高值(二进制中为10111)是一个5位操作。对于5位,异或将产生的最大数为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) % 26;
}
  private static int function(int character, int key, int roundNumber) {
    return (2 * roundNumber * key * character) % 23;
}
带有%26的旧函数很好,但是%23给了我更好的加密结果。无论哪种方式,它们都低于5位或更低