4
\$\begingroup\$

A few days ago I began to work on my first project that's bigger than any others that I've attempted before. The purpose of this was to learn how to better code using OOP techniques. The code is all in one Main class (https://github.com/ViceroyFaust/JavaEnigma/):

package owl;

import java.io.BufferedReader;
import java.io.FileReader;
import java.net.URL;

public class Main {
// Rotors I II III of the Enigma I model and Reflector B

    private static final String ABC = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final String I = "EKMFLGDQVZNTOWYHXUSPAIBRCJ";
    private static final String II = "AJDKSIRUXBLHWTMCQGZNPYFVOE";
    private static final String III = "BDFHJLCPRTXVZNYEIWGAKMUSQO";
    private static final String ReflectorB = "YRUHQSLDPXNGOKMIEBFZCWVJAT";
    private static int leftPosition = 0;
    private static int midPosition = 0;
    private static int rightPosition = 0;
    private static int ringL = 0;
    private static int ringM = 0;
    private static int ringR = 0;

    private static URL url = Main.class.getResource("Message.txt");

    public static void main(String[] args) {
        try {
            FileReader fr = new FileReader(url.getPath());
            BufferedReader reader = new BufferedReader(fr);
            String ringstellung = reader.readLine();
            String position = reader.readLine();
            String message = reader.readLine();
            setRing(ringstellung);
            setPosition(position);
            System.out.println(encrypt(message));

            reader.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void setRing(String ringstellung) {
        ringL = ringstellung.charAt(0) - 65;
        ringM = ringstellung.charAt(1) - 65;
        ringR = ringstellung.charAt(2) - 65;
    }

    private static void setPosition(String position) {
        leftPosition = position.charAt(0) - 65;
        midPosition = position.charAt(1) - 65;
        rightPosition = position.charAt(2) - 65;

    }

    private static StringBuilder encrypt(String message) {
        StringBuilder output = new StringBuilder();
        for (int messageIndex = 0; messageIndex < message.length(); messageIndex++) {
            char c = message.charAt(messageIndex);
            if (c == ' ') {
                output.append(' ');
                continue;
            }
            int indexABC = 0;
            rightPosition++; // right most rotor turns
            if (rightPosition == 22) { // if V turns, rotor II turns
                midPosition++;
                if (midPosition == 5) { // if E turns, rotor I is turned
                    leftPosition++;
                }
            }
            if (rightPosition > 26) {
                rightPosition -= 26;
            }
            if (midPosition > 26) {
                midPosition -= 26;
            }
            if (leftPosition > 26) {
                leftPosition -= 26;
            }
            // System.out.printf("%c %c %c%n", ABC.charAt(leftPosition),
            // ABC.charAt(midPosition), ABC.charAt(rightPosition));
            // System.out.printf("%c %c %c%n%n", ABC.charAt(ringL), ABC.charAt(ringM),
            // ABC.charAt(ringR));
            // right rotor encryption
            for (int foo = 0; foo < 26; foo++) {
                if (ABC.charAt(foo) == c) {
                    indexABC = foo + rightPosition - ringR;
                    if (indexABC > 25) {
                        indexABC -= 26;
                    }
                    if (indexABC < 0) {
                        indexABC += 26;
                    }
                    break;
                }
            }
            c = III.charAt(indexABC);
            for (int foo = 0; foo < 26; foo++) {
                if (ABC.charAt(foo) == c) {
                    indexABC = foo - rightPosition + ringR;
                    if (indexABC > 25) {
                        indexABC -= 26;
                    }
                    if (indexABC < 0) {
                        indexABC += 26;
                    }
                    break;
                }
            }
            c = ABC.charAt(indexABC);
            // System.out.println(c);

            // middle rotor encryption
            for (int foo = 0; foo < 26; foo++) {
                if (ABC.charAt(foo) == c) {
                    indexABC = foo + midPosition - ringM;
                    if (indexABC > 25) {
                        indexABC -= 26;
                    }
                    if (indexABC < 0) {
                        indexABC += 26;
                    }
                    break;
                }
            }
            c = II.charAt(indexABC);
            for (int foo = 0; foo < 26; foo++) {
                if (ABC.charAt(foo) == c) {
                    indexABC = foo - midPosition + ringM;
                    if (indexABC > 25) {
                        indexABC -= 26;
                    }
                    if (indexABC < 0) {
                        indexABC += 26;
                    }
                    break;
                }
            }
            c = ABC.charAt(indexABC);
            // System.out.println(c);

            // left rotor encryption
            for (int foo = 0; foo < 26; foo++) {
                if (ABC.charAt(foo) == c) {
                    indexABC = foo + leftPosition - ringL;
                    if (indexABC > 25) {
                        indexABC -= 26;
                    }
                    if (indexABC < 0) {
                        indexABC += 26;
                    }
                    break;
                }
            }
            c = I.charAt(indexABC);
            for (int foo = 0; foo < 26; foo++) {
                if (ABC.charAt(foo) == c) {
                    indexABC = foo - leftPosition + ringL;
                    if (indexABC > 25) {
                        indexABC -= 26;
                    }
                    if (indexABC < 0) {
                        indexABC += 26;
                    }
                    break;
                }
            }
            c = ABC.charAt(indexABC);
            // System.out.println(c + "\n");

            // reflector
            c = ReflectorB.charAt(indexABC);
            // System.out.println(c + "\n");

            // Reflected Left Rotor
            for (int foo = 0; foo < 26; foo++) {
                if (ABC.charAt(foo) == c) {
                    indexABC = foo + leftPosition - ringL;
                    if (indexABC > 25) {
                        indexABC -= 26;
                    }
                    if (indexABC < 0) {
                        indexABC += 26;
                    }
                    break;
                }
            }
            c = ABC.charAt(indexABC);
            for (int foo = 0; foo < 26; foo++) {
                if (I.charAt(foo) == c) {
                    indexABC = foo - leftPosition + ringL;
                    if (indexABC > 25) {
                        indexABC -= 26;
                    }
                    if (indexABC < 0) {
                        indexABC += 26;
                    }
                    break;
                }
            }
            c = ABC.charAt(indexABC);
            // System.out.println(c);

            // Reflected Middle Rotor
            for (int foo = 0; foo < 26; foo++) {
                if (ABC.charAt(foo) == c) {
                    indexABC = foo + midPosition - ringM;
                    if (indexABC > 25) {
                        indexABC -= 26;
                    }
                    if (indexABC < 0) {
                        indexABC += 26;
                    }
                    break;
                }
            }
            c = ABC.charAt(indexABC);
            for (int foo = 0; foo < 26; foo++) {
                if (II.charAt(foo) == c) {
                    indexABC = foo - midPosition + ringM;
                    if (indexABC > 25) {
                        indexABC -= 26;
                    }
                    if (indexABC < 0) {
                        indexABC += 26;
                    }
                    break;
                }
            }
            c = ABC.charAt(indexABC);
            // System.out.println(c);

            // Reflected Right Rotor
            for (int foo = 0; foo < 26; foo++) {
                if (ABC.charAt(foo) == c) {
                    indexABC = foo + rightPosition - ringR;
                    if (indexABC > 25) {
                        indexABC -= 26;
                    }
                    if (indexABC < 0) {
                        indexABC += 26;
                    }
                    break;
                }
            }
            c = ABC.charAt(indexABC);
            for (int foo = 0; foo < 26; foo++) {
                if (III.charAt(foo) == c) {
                    indexABC = foo - rightPosition + ringR;
                    if (indexABC > 25) {
                        indexABC -= 26;
                    }
                    if (indexABC < 0) {
                        indexABC += 26;
                    }
                    break;
                }
            }
            c = ABC.charAt(indexABC);
            output.append(c);
            // System.out.println(c);
        }
        return output;
    }
}

And the input is the following:

ABC
XYZ
ALPHA DELTA CHARLIE

The code works and all of the output is correct. You can set any of the settings on the rotors, such as the Ring Settings and the Initial Position. I have not yet added the feature of the Plugboard, because I want to organise my code before I add any big features.

So, the question is, how can I reorgise the code in order to make it follow the OOP structure better, and whate are some general things which will help me to program better in the future?

\$\endgroup\$
4
\$\begingroup\$

This won't be a complete answer, but without getting into OOP you should see that there's A LOT of duplicated code. You can rewrite your for cycles in a method operating on just the changing parts.

private static int rotate(final char c, int indexABCShift, final String characters){
    int indexABC = 0;
    for (int foo = 0; foo < 26; foo++) {
        if (characters.charAt(foo) == c) {
            indexABC = foo + indexABCShift;
            if (indexABC > 25) {
                indexABC -= 26;
            }
            if (indexABC < 0) {
                indexABC += 26;
            }
            break;
        }
    }
    return indexABC;
}

private static StringBuilder encrypt(String message) {
    StringBuilder output = new StringBuilder();
    for (int messageIndex = 0; messageIndex < message.length(); messageIndex++) {
        char c = message.charAt(messageIndex);
        if (c == ' ') {
            output.append(' ');
            continue;
        }
        int indexABC = 0;
        rightPosition++; // right most rotor turns
        if (rightPosition == 22) { // if V turns, rotor II turns
            midPosition++;
            if (midPosition == 5) { // if E turns, rotor I is turned
                leftPosition++;
            }
        }
        if (rightPosition > 26) {
            rightPosition -= 26;
        }
        if (midPosition > 26) {
            midPosition -= 26;
        }
        if (leftPosition > 26) {
            leftPosition -= 26;
        }

        indexABC = rotate(c, rightPosition - ringR, ABC);
        c = III.charAt(indexABC);
        indexABC = rotate(c, - rightPosition + ringR, ABC);
        c = ABC.charAt(indexABC);
        indexABC = rotate(c, + midPosition - ringM, ABC);
        c = II.charAt(indexABC);
        indexABC = rotate(c, - midPosition + ringM, ABC);
        c = ABC.charAt(indexABC);
        indexABC = rotate(c, + leftPosition - ringL, ABC);
        c = I.charAt(indexABC);
        indexABC = rotate(c, - leftPosition + ringL, ABC);
        // reflector
        c = ReflectorB.charAt(indexABC);
        indexABC = rotate(c, + leftPosition - ringL, ABC);
        c = ABC.charAt(indexABC);
        indexABC = rotate(c, - leftPosition + ringL, I);
        c = ABC.charAt(indexABC);
        // Reflected Middle Rotor
        indexABC = rotate(c, + midPosition - ringM, ABC);
        c = ABC.charAt(indexABC);
        indexABC = rotate(c, - midPosition + ringM, II);
        c = ABC.charAt(indexABC);
        indexABC = rotate(c, + rightPosition - ringR, ABC);
        c = ABC.charAt(indexABC);
        indexABC = rotate(c, - rightPosition + ringR, III);
        c = ABC.charAt(indexABC);
        output.append(c);
    }
    return output;
}

This alone will save you 150 lines. That's one of the main programming good habits - Don't Repeat Yourself. I cannot offer some OOP solution to the problem without really understanding the enigma, but you should start with splitting the code into smaller methods and keep the variables local inside the methods as much as possible. For example the ring positions don't need to be static variables - you can compute them in the main and pass them to the encrypt function. Also you can split the encrypt by separating iteration over the input string and encrypting single letter.

\$\endgroup\$
  • \$\begingroup\$ The line calling the rotate method right before the reflector throws the code off, which messes up the entire encryption. For some reason, the reflector relies on that one specific loop within the encrypt();. \$\endgroup\$ – ViceroyFaust Aug 3 at 1:07
  • \$\begingroup\$ Okay, I figured it out. The output for the last letter on the Rotor before the Reflector is useless, because the location of the letter is used for the reflector, and not the letter itself. \$\endgroup\$ – ViceroyFaust Aug 3 at 1:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.