import java.util.*; /** *

Title: Enigma

*

Description: A Simulation of the German Military Enigma Machine. * Specifications of rotors and reflectors obtained from * http://www.codesandciphers.org.uk/enigma/rotorspec.htm and * http://homepages.tesco.net/~andycarlson/enigma/simulating_enigma.html

* @author Meghan Emilio * @version 1.0 */ public class Enigma { //STATIC ROTORS public final static StringBuffer rotorI = new StringBuffer("EKMFLGDQVZNTOWYHXUSPAIBRCJ"); public final static StringBuffer rotorII = new StringBuffer("AJDKSIRUXBLHWTMCQGZNPYFVOE"); public final static StringBuffer rotorIII = new StringBuffer("BDFHJLCPRTXVZNYEIWGAKMUSQO"); public final static StringBuffer rotorIV = new StringBuffer("ESOVPZJAYQUIRHXLNFTGKDCMWB"); public final static StringBuffer rotorV = new StringBuffer("VZBRGITYUPSDNHLXAWMJQOFECK"); public final static StringBuffer rotorVI = new StringBuffer("JPGVOUMFYQBENHZRDKASXLICTW"); public final static StringBuffer rotorVII = new StringBuffer("NZJHGRCXMYSWBOUFAIVLPEKQDT"); public final static StringBuffer rotorVIII = new StringBuffer("JPGVOUMFYQBENHZRDKASXLICTW"); //STATIC REFLECTORS public static final StringBuffer reflectorB = new StringBuffer("YRUHQSLDPXNGOKMIEBFZCWVJAT"); public static final StringBuffer reflectorC = new StringBuffer("FVPJIAOYEDRZXWGCTKUQSBNMHL"); public static final StringBuffer reflector0 = new StringBuffer("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); //CURRENT ROTORS AND REFLECTOR IN USE public StringBuffer firstRotor; public StringBuffer firstRotorT = new StringBuffer(reflector0.toString()); public StringBuffer secondRotor; public StringBuffer secondRotorT = new StringBuffer(reflector0.toString()); public StringBuffer thirdRotor; public StringBuffer thirdRotorT = new StringBuffer(reflector0.toString()); public StringBuffer reflector; //CURRENT PLUGBOARD SETTINGS public char[] plugBoard = 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'}; //STATIC "NOTCHES" - when each rotor rotates public final static StringBuffer[] notches = {new StringBuffer("Q"),new StringBuffer("E"),new StringBuffer("V"),new StringBuffer("J"), new StringBuffer("Z"),new StringBuffer("Z"),new StringBuffer("Z"),new StringBuffer("Z")}; //CURRENT ROTOR NOTCHES private StringBuffer n1; private StringBuffer n2; /** * Class Constructor *@param r1 rotor to be used as first rotor *@param r2 rotor to be used as second rotor *@param r3 rotor to be used as third rotor *@param r reflector to be used */ public Enigma(String r1, String r2, String r3, String r) { firstRotor = getValue(r1)[0]; n1 = getValue(r1)[1]; secondRotor = getValue(r2)[0]; n2 = getValue(r2)[1]; thirdRotor = getValue(r3)[0]; reflector = getValue(r)[0]; } /** *Sets the first Rotor *@param r1 rotor to be used as first rotor *@return void */ public void setFirstRotor(String r1){ firstRotor = getValue(r1)[0]; n1 = getValue(r1)[1]; } /** *Sets the second Rotor *@param r2 rotor to be used as second rotor *@return void */ public void setSecondRotor(String r2){ secondRotor = getValue(r2)[0]; n2 = getValue(r2)[1]; } /** *Sets the second Rotor *@param r3 rotor to be used as third rotor *@return void */ public void setThirdRotor(String r3){ thirdRotor = getValue(r3)[0]; } /** *Sets the intial settings of the rotors. *@param s1 initial setting for first rotor *@param s2 initial setting for second rotor *@param s3 initial setting for third rotor *@return void */ public void initialSettings(String s1, String s2, String s3){ int p; //First Rotor p = firstRotorT.toString().indexOf(s1); firstRotorT.append(firstRotorT.substring(0,p)); firstRotorT.delete(0,p); //Second Rotor p = secondRotorT.toString().indexOf(s2); secondRotorT.append(secondRotorT.substring(0,p)); secondRotorT.delete(0,p); //Third Rotor p = thirdRotorT.toString().indexOf(s3); thirdRotorT.append(thirdRotorT.substring(0,p)); thirdRotorT.delete(0,p); } /** *Creates a plubboard connection between two letters *@param x first character to be connected *@param y second character to be connected *@return void */ public void setPlugBoard(char x, char y){ for(int i=0; i90 || s.charAt(0)<65 || s.charAt(1)>90 || s.charAt(1)<65) return false; } StringTokenizer token = new StringTokenizer(str, " "); while(token.hasMoreTokens()){ s = token.nextToken(); if(s.length()==2) setPlugBoard(s.charAt(0), s.charAt(1)); else return false; } return true; } /** *Returns the value of the specified Rotor. *@param v name or number of rotor *@return StringBuffer[] correct rotor */ public StringBuffer[] getValue(String v){ StringBuffer[] result = new StringBuffer[2]; if (v.equals("RotorI") || v.equals("1")){ result[0] = rotorI; result[1] = notches[0]; return result; } if (v.equals("RotorII")|| v.equals("2")){ result[0] = rotorII; result[1] = notches[1]; return result; } if (v.equals("RotorIII")|| v.equals("3")){ result[0] = rotorIII; result[1] = notches[2]; return result; } if (v.equals("RotorIV")|| v.equals("4")){ result[0] = rotorIV; result[1] = notches[3]; return result; } if (v.equals("RotorV")|| v.equals("5")){ result[0] = rotorV; result[1] = notches[4]; return result; } if (v.equals("RotorVI")|| v.equals("6")){ result[0] = rotorVI; result[1] = notches[5]; return result; } if (v.equals("RotorVII")|| v.equals("7")){ result[0] = rotorVII; result[1] = notches[6]; return result; } if (v.equals("RotorVIII")|| v.equals("8")){ result[0] = rotorVIII; result[1] = notches[7]; return result; } if (v.equals("ReflectorB")){ result[0] = reflectorB; result[1] = new StringBuffer(""); return result; } if (v.equals("ReflectorC")){ result[0] = reflectorC; result[1] = new StringBuffer(""); return result; } if (v.equals("No Reflector")){ result[0] = reflector0; result[1] = new StringBuffer(""); return result; } return new StringBuffer[]{new StringBuffer("ERROR"), new StringBuffer("")}; } /** *Returns the character obtained after passing l through *the current first rotor *@param l character input *@return char obtained after passing l through the current first rotor */ public char rotorOne(char l){ int position = firstRotorT.toString().indexOf(l); return firstRotor.charAt(position); } /** *Returns the character obtained after passing l through *the current second rotor *@param l character input *@return char obtained after passing l through the current second rotor */ public char rotorTwo(char l){ int position = secondRotorT.toString().indexOf(l); return secondRotor.charAt(position); } /** *Returns the character obtained after passing l through *the current third rotor *@param l character input *@return char obtained after passing l through the current third rotor */ public char rotorThree(char l){ int position = thirdRotorT.toString().indexOf(l); return thirdRotor.charAt(position); } /** *Returns the character obtained after passing l through *the current reflector *@param l character input *@return char obtained after passing l through the current reflector */ public char reflector(char l){ int position = (int)l - 65; l = reflector.charAt(position); return l; } /** *Returns the character obtained after passing l through *the current first rotor in the reverse direction *@param l character input *@return char obtained after passing l through the current *first rotor in the reverse direction */ public char IrotorOne(char l){ int position = firstRotor.toString().indexOf(l); return firstRotorT.charAt(position); } /** *Returns the character obtained after passing l through * the current second rotor in the reverse direction *@param l character input *@return char obtained after passing l through the current *second rotor in the reverse direction */ public char IrotorTwo(char l){ int position = secondRotor.toString().indexOf(l); return secondRotorT.charAt(position); } /** *Returns the character obtained after passing l through *the current third rotor in the reverse direction *@param l character input *@return char obtained after passing l through the current *third rotor in the reverse direction */ public char IrotorThree(char l){ int position = thirdRotor.toString().indexOf(l); return thirdRotorT.charAt(position); } /** * Rotates the rotors according to their current settings *@param void *@return void */ public void rotate(){ StringBuffer currentR1 = new StringBuffer(firstRotorT.charAt(0)+""); StringBuffer currentR2 = new StringBuffer(secondRotorT.charAt(0)+""); //Rotate first rotor firstRotorT.append(firstRotorT.charAt(0)); firstRotorT.delete(0, 1); //if first rotor is at notch if (currentR1.toString().equals(n1.toString())){ //then also rotate second rotor secondRotorT.append(secondRotorT.charAt(0)); secondRotorT.delete(0, 1); //if second rotor is at notch if(currentR2.toString().equals(n2.toString())){ //then also rotate the third rotor thirdRotorT.append(thirdRotorT.charAt(0)); thirdRotorT.delete(0, 1); } } } /** *Returns the result of passing c through *the plugboard with its current settings *@param c the inputted character *@return char the result of passing c through *the plugboard with its current settings */ public char plugBoard(char c){ int i = (int)(c) - 65; return plugBoard[i]; } /** *Returns the current setting of the first rotor. *@param void *@return char that is the current setting of the first rotor */ public char getFRSetting(){ return firstRotorT.charAt(0); } /** *Returns the current setting of the second rotor. *@param void *@return char that is the current setting of the second rotor */ public char getSRSetting(){ return secondRotorT.charAt(0); } /** *Returns the current setting of the third rotor. *@param void *@return char that is the current setting of the third rotor */ public char getTRSetting(){ return thirdRotorT.charAt(0); } /** *Encrypts/Decrypts the inputted string using the *machine's current settings *@param p the text to be encrypted/decrypted *@return void */ public String encrypt(String p){ p = p.toUpperCase(); String e = ""; char c; int k; //for the length of the inputted text for(int i=0; i=65){ //rotate the rotors rotate(); //pass the character through the plugboard c = plugBoard(c); //then through the first rotor c = rotorOne(c); //then through the second rotor c = rotorTwo(c); //then through the third rotor c = rotorThree(c); //then through the reflector c = reflector(c); //then through the first rotor in the reverse direction c = IrotorThree(c); //then through the second rotor in the reverse direction c = IrotorTwo(c); //then through the third rotor in the reverse direction c = IrotorOne(c); //and finally back through the plugboard c = plugBoard(c); //and add the new character to the encrypted/decrypted message e = e + c; } //if c is a space simply add it to the encrypted/decrypted message //to conserve spaces else if(c==32) e = e + c; //if c is neither a space nor a letter, then there is an error else return null; } //return the complete encrypted/decrpyted message return e; } /** *Parses Plugboard input to check for repeated letters *as each letter can only be used once in the plugboard *@param str the inputted plug board settings *@return void */ public boolean pbParser(String str){ //if no plug board settings were input, then continue if(str.length()<=0 || str.equals(null) || str == null){ return true; } //otherwise, check to make sure letters are not repeated for(int i=0; i90 || str.charAt(i)<65) i++; //if the current letter appears in the rest of the string else if(str.substring(i+1).indexOf(str.charAt(i)) != -1) return false; } //otherwise, return true return true; } }