0

I am trying to implement a plaintext Feistel Cipher in Java where I am assigning numeric values to each char of the original plaintext message using a hardcoded 'alphabet' array. My problem is that once I apply the function to the right half and XOR with the left, I am sometimes left with a number that is out of bounds of my 'alphabet' array.

Here is the alphabet array:

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', ' '};

This is the function:

    private static int function(int character, int key, int roundNumber) {
    return (2 * roundNumber * key * character) % 26;
}

And here is the block of code for enciphering:

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++;
    }

The error happens at this line:

str1 += alphabet[leftHalf[i]];

I've tried %26 the leftHalf[i] number so that it fits the alphabet array, but that ruins the point of the cipher and I am unable to decipher it.

I have also tried several different functions, but I think it mainly has to do with the XOR. Is there a way to ensure that the XOR will return something within the alphabet array bounds, or am I going about this whole thing in the wrong way? Any help is appreciated.

Also, Error code:

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

1 Answers1

0

Pretty sure I was able to figure it out. So since the highest array index in the alphabet array was 26, that meant the XOR would be a 5 bit operation at its highest (10111 in binary). With 5 bits, the maximum number the XOR would produce is 31 (11111 in binary). So I just added 5 more redundant, unused lowercase letters to the alphabet array to make its length 31. Then I just had to make sure the function returned a number within 5 bits as well, which is what the modulus is for.

new array:

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'};

new function:

  private static int function(int character, int key, int roundNumber) {
    return (2 * roundNumber * key * character) % 23;
}

the old function with %26 was fine, but %23 was giving me better enciphered results. Either way they are both under 5 bits or under.