import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; /** * Main Class for interaction with the user. * */ public final class Shell { /** * number of arguments / rotor. */ private static final int ROTORARGS = 3; /** * Patchboard-permutation. */ private static final int[] PATCHBOARDPERMU = new int[] {9, 22, 20, 11, 2, 12 , 13, 14, 7, 15, 16, 25, 24, 23, 8, 17, 0, 3, 10, 4, 6, 21, 1, 19 , 18, 5}; /** * Reflector- permutation. */ private static final int[] REFLECTORPERMU = new int[] {8, 12, 4, 19, 2, 6, 5 , 17, 0, 24, 18, 16, 1, 25, 23, 22, 11, 7, 10, 3, 21, 20, 15, 14 , 9, 13}; /** * Amount of Symbols the alphabet uses. */ private static int symbols = PATCHBOARDPERMU.length; private Shell() { } /** * Convert char-Array to Enigma-permutation-array. * @param charArray char-array to convert * @return Enigma-compatible permutation array */ private static int[] convertCharInt(final char[] charArray) { int[] intArray = new int[charArray.length]; for (int i = 0; i < charArray.length; i++) { intArray[i] = (charArray[i] - 65); } return intArray; } /** * Convert Enigma-int to char. * @param i Enigma-int * @return char */ private static char convertIntChar(final int i) { return (char) (i + 65); } /** * Checks if every Parameter for a Enigma exists. * @param stringArray Array of all programm parameters * @return true if right number of parameters are given
* false if wrong number of parameters or parameters * are zero */ private static boolean checkArgsLength(final String[] stringArray) { return stringArray.length % ROTORARGS == 0 && stringArray.length != 0; } /** * Extracts the Permutation-Array Elements out of the Arguments * given by the User.
Every third Element is a Permutation-Array. * Furthermore, the lengths of the Array is checked to handle faults. * @param stringAr the String entered by the user. * @return Permutation-Array[][] for every Rotor as a * char-array or
null if any error occurs. */ private static int[][] extractPermuArray(final String[] stringAr) { int[][] intArray = new int[(stringAr.length / ROTORARGS)] [Shell.symbols]; for (int i = 0; i < (stringAr.length) / ROTORARGS; i++) { if (stringAr[(i * ROTORARGS)].length() == Shell.symbols) { intArray[i] = convertCharInt( stringAr[(i * ROTORARGS)].toCharArray()); } else { return null; } } return intArray; } /** * Extract the tick-Positions out of string-array into a int-array. * @param stringAr All Arguments committed to the Programm * @return int-array with rotors tick-positions
* or null if tick-positition has more then * one character */ private static int[] extractTickPosArray(final String[] stringAr) { int[] intArray = new int[(stringAr.length / ROTORARGS)]; for (int i = 0; i < (stringAr.length / ROTORARGS); i++) { if (stringAr[1 + (i * ROTORARGS)].toCharArray().length == 1) { intArray[i] = stringAr[1 + (i * ROTORARGS)].charAt(0) - 65; } else { return null; } } return intArray; } /** * Extract the initial-Positions out of string-array into a int-array. * @param stringAr All Arguments committed to the Programm * @return int-array with rotors initial-positions
* or null if initial-positition has more then * one character */ private static int[] extractInitialPosArray(final String[] stringAr) { int[] intArray = new int[(stringAr.length / ROTORARGS)]; for (int i = 0; i < (stringAr.length / ROTORARGS); i++) { if (stringAr[2 + (i * ROTORARGS)].toCharArray().length == 1) { intArray[i] = stringAr[2 + (i * ROTORARGS)].charAt(0) - 65; } else { return null; } } return intArray; } /** * Checks if char is a capital-Letter. * @param ch Character * @return true
/ * or false */ private static boolean isEnigmaChar(final int ch) { if (ch < 0 || ch >= Shell.symbols) { return false; } return true; } /** * Checks if char-array is a capital-Letter-array. * @param ch Character-array * @return true
/ * or false */ private static boolean isEnigmaCharArray(final int[] ch) { for (int i = 0; i < ch.length; i++) { if (!isEnigmaChar(ch[i])) { return false; } } return true; } /** * Checks if char-array-array is a capital-Letter-array-array. * @param ch Character-array-array * @return true
/ * or false */ private static boolean isEnigmaCharArray(final int[][] ch) { for (int i = 0; i < ch.length; i++) { if (!isEnigmaCharArray(ch[i])) { return false; } } return true; } /** * Checks if a permutation contains a char twice. * @param permu Permutation * @return true if duplicate char is found
* false if chars are unique */ private static boolean hasDuplicateChar(final int[][] permu) { boolean[][] foo = new boolean[permu.length][permu[0].length]; int i; int j; for (i = 0; i < permu.length; i++) { for (j = 0; j < permu[i].length; j++) { if (foo[i][permu[i][j]]) { return true; } else { foo[i][permu[i][j]] = true; } } } return false; } /** * Main method for the Enigma-Simulation. * @param args All parameter given to the Shell * @throws IOException IOException */ public static void main(final String[] args) throws IOException { int[][] permu = new int[(args.length / ROTORARGS)][Shell.symbols]; int[] tickPos = new int[(args.length / ROTORARGS)]; int[] initialPos = new int[(args.length / ROTORARGS)]; Enigma myEnigma; if (checkArgsLength(args)) { if (extractPermuArray(args) != null) { permu = extractPermuArray(args); } else { System.out.println("Error! Wrong Permutation!"); return; } if (extractTickPosArray(args) != null) { tickPos = extractTickPosArray(args); } else { System.out.println("Error! wrong Tick Position!"); return; } if (extractInitialPosArray(args) != null) { initialPos = extractInitialPosArray(args); } else { System.out.println("Error! wrong initial Position!"); return; } } else { System.out.println("Error: wrong number of Arguments"); return; } //Check if only Capital Letters are used if (!isEnigmaCharArray(permu) || !isEnigmaCharArray(tickPos) || !isEnigmaCharArray(initialPos)) { System.out.print("Error! wrong character in config"); return; } if (hasDuplicateChar(extractPermuArray(args))) { System.out.println("Error! Duplicate char in Permutation"); } BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); myEnigma = new Enigma(tickPos, initialPos, permu, PATCHBOARDPERMU , REFLECTORPERMU); while (true) { String stdinp = br.readLine(); if (stdinp.equals("")) { return; } int[] ciphertxt = convertCharInt(stdinp.toCharArray()); if (!isEnigmaCharArray(ciphertxt)) { System.out.print("Error! Wrong input"); return; } for (int i = 0; i < ciphertxt.length; i++) { System.out.print(convertIntChar(myEnigma.encode(ciphertxt[i]))); } System.out.println(); } } }