diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 1f61281..8ab5f06 100755 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,8 +1,14 @@ CHANGELOG ENIGMANDROID -v0.1.6-not-yet-released -*Updated CHANGELOG (oops) +v0.1.7-not-yet-released *TODO:Fix about dialog (outdated manual) -* +*TODO: Add Enigma Z (find Rotor wiring reference somewhere) + +v0.1.6-10.09.2015< +*Updated CHANGELOG (oops) +*Added Enigma D +*Added rotor names to ringSettingsDialog +*Rewrote major parts of the app once again :) +*Added option to break messages up into blocks v0.1.5-27.08.2015< *Added french number spelling diff --git a/app/build.gradle b/app/build.gradle index 5032d0f..dafc414 100755 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,8 +8,8 @@ android { applicationId "de.vanitasvitae.enigmandroid" minSdkVersion 15 targetSdkVersion 23 - versionCode 11 - versionName "0.1.5-27.08.2015-beta" + versionCode 12 + versionName "0.1.6-10.09.2015-beta" } buildTypes { release { diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/MainActivity.java b/app/src/main/java/de/vanitasvitae/enigmandroid/MainActivity.java index 9f029a1..5298d9b 100755 --- a/app/src/main/java/de/vanitasvitae/enigmandroid/MainActivity.java +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/MainActivity.java @@ -14,7 +14,6 @@ import android.view.MenuItem; import android.view.View; import android.widget.Toast; -import de.vanitasvitae.enigmandroid.enigma.Plugboard; import de.vanitasvitae.enigmandroid.enigma.inputPreparer.InputPreparer; import de.vanitasvitae.enigmandroid.layout.LayoutContainer; @@ -47,6 +46,7 @@ public class MainActivity extends Activity protected String prefMachineType; protected boolean prefAnomaly; protected String prefNumericLanguage; + protected String prefMessageFormatting; @Override public void onCreate(Bundle savedInstanceState) @@ -71,7 +71,7 @@ public class MainActivity extends Activity String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT); if (sharedText != null) { - layoutContainer.getInputView().setText(sharedText); + layoutContainer.getInput().setRawText(sharedText); } } } @@ -86,12 +86,18 @@ public class MainActivity extends Activity { switch (prefMachineType) { - case "M4": - this.setContentView(R.layout.activity_main_m4); + case "I": + this.setContentView(R.layout.activity_main_i_m3); break; case "M3": this.setContentView(R.layout.activity_main_i_m3); break; + case "M4": + this.setContentView(R.layout.activity_main_m4); + break; + case "D": + this.setContentView(R.layout.activity_main_d); + break; default: this.setContentView(R.layout.activity_main_i_m3); break; @@ -106,6 +112,8 @@ public class MainActivity extends Activity this.setPrefAnomaly(sharedPreferences.getBoolean("prefAnomaly", true)); this.setPrefNumericLanguage(sharedPreferences.getString("prefNumericLanguage", getResources(). getStringArray(R.array.pref_alias_numeric_spelling_language)[0])); + this.setPrefMessageFormatting(sharedPreferences.getString("prefMessageFormatting", getResources(). + getStringArray(R.array.pref_alias_message_formatting)[0])); } public void setPrefMachineType(String type) @@ -116,22 +124,22 @@ public class MainActivity extends Activity String savedInput = ""; if(layoutContainer != null) { - savedInput = layoutContainer.getInputView().getText().toString(); + savedInput = layoutContainer.getInput().getText(); } updateContentView(); layoutContainer = LayoutContainer.createLayoutContainer(prefMachineType); - layoutContainer.getInputView().setText(savedInput); + layoutContainer.setInputPreparer(InputPreparer.createInputPreparer(prefNumericLanguage)); + layoutContainer.getInput().setText(savedInput); } } public String getPrefMachineType() { if(prefMachineType != null) return prefMachineType; - else - { - updatePreferenceValues(); - return prefMachineType; - } + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); + this.prefMachineType = sharedPreferences.getString("prefMachineType", getResources(). + getStringArray(R.array.pref_list_machine_type)[0]); + return prefMachineType; } public void setPrefAnomaly(boolean anomaly) @@ -139,7 +147,7 @@ public class MainActivity extends Activity if(prefAnomaly !=anomaly) { prefAnomaly = anomaly; - layoutContainer.getEnigma().setPrefAnomaly(anomaly); + if(layoutContainer != null) layoutContainer.getEnigma().setPrefAnomaly(anomaly); } } @@ -153,20 +161,37 @@ public class MainActivity extends Activity if(prefNumericLanguage == null || !prefNumericLanguage.equals(lang)) { prefNumericLanguage = lang; - layoutContainer.getEnigma().setInputPreparer(InputPreparer.createInputPreparer(lang)); + layoutContainer.setInputPreparer(InputPreparer.createInputPreparer(lang)); } } public String getPrefNumericLanguage() { if(prefNumericLanguage != null) return prefNumericLanguage; - else + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); + this.prefNumericLanguage = sharedPreferences.getString("prefNumericLanguage", getResources(). + getStringArray(R.array.pref_alias_numeric_spelling_language)[0]); + return prefNumericLanguage; + } + + public void setPrefMessageFormatting(String messageFormatting) + { + if(prefMessageFormatting == null || !prefMessageFormatting.equals(messageFormatting)) { - updatePreferenceValues(); - return prefNumericLanguage; + prefMessageFormatting = messageFormatting; + layoutContainer.setEditTextAdapter(messageFormatting); } } + public String getPrefMessageFormatting() + { + if(prefMessageFormatting != null) return prefMessageFormatting; + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); + this.prefMessageFormatting = sharedPreferences.getString("prefMessageFormatting", getResources(). + getStringArray(R.array.pref_alias_message_formatting)[0]); + return prefMessageFormatting; + } + @Override public boolean onCreateOptionsMenu(Menu menu) { @@ -183,7 +208,7 @@ public class MainActivity extends Activity int id = item.getItemId(); if (id == R.id.action_reset) { - layoutContainer.reset(); + layoutContainer.resetLayout(); Toast.makeText(getApplicationContext(), R.string.message_reset, Toast.LENGTH_SHORT).show(); return true; @@ -205,7 +230,7 @@ public class MainActivity extends Activity } else if (id == R.id.action_send) { - if(layoutContainer.getOutputView().getText().length() == 0) + if(layoutContainer.getOutput().getText().length() == 0) { Toast.makeText(this, R.string.error_no_text_to_send, Toast.LENGTH_SHORT).show(); } @@ -213,7 +238,7 @@ public class MainActivity extends Activity { Intent sendIntent = new Intent(); sendIntent.setAction(Intent.ACTION_SEND); - sendIntent.putExtra(Intent.EXTRA_TEXT, layoutContainer.getOutputView().getText().toString()); + sendIntent.putExtra(Intent.EXTRA_TEXT, layoutContainer.getOutput().getModifiedText()); sendIntent.setType("text/plain"); startActivity(Intent.createChooser(sendIntent, getResources().getText(R.string.send_to))); } @@ -229,15 +254,7 @@ public class MainActivity extends Activity */ public void doCrypto(View v) { - if(layoutContainer.getInputView().getText().length()!=0) { - layoutContainer.getEnigma().setConfiguration(layoutContainer.createConfiguration()); - layoutContainer.getEnigma().setPlugboard(new Plugboard(layoutContainer.createPlugboardConfiguration())); - String m = layoutContainer.getInputView().getText().toString(); - m = layoutContainer.getEnigma().getInputPreparer().prepareString(m); - layoutContainer.getInputView().setText(m); - layoutContainer.getOutputView().setText(layoutContainer.getEnigma().encrypt(m)); - layoutContainer.updateLayout(); - } + layoutContainer.doCrypto(); } /** @@ -285,8 +302,10 @@ public class MainActivity extends Activity this.setPrefMachineType(sharedPrefs.getString("prefMachineType", getResources() .getStringArray(R.array.pref_list_machine_type)[0])); this.setPrefAnomaly(sharedPrefs.getBoolean("prefAnomaly", true)); - this.setPrefNumericLanguage(this.prefNumericLanguage = sharedPrefs.getString("prefNumericLanguage", getResources(). + this.setPrefNumericLanguage(sharedPrefs.getString("prefNumericLanguage", getResources(). getStringArray(R.array.pref_alias_numeric_spelling_language)[0])); + this.setPrefMessageFormatting(sharedPrefs.getString("prefMessageFormatting", + getResources().getStringArray(R.array.pref_alias_message_formatting)[0])); break; } diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma.java b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma.java index d14652a..2b99936 100755 --- a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma.java +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma.java @@ -1,8 +1,5 @@ package de.vanitasvitae.enigmandroid.enigma; -import de.vanitasvitae.enigmandroid.MainActivity; -import de.vanitasvitae.enigmandroid.enigma.inputPreparer.InputPreparer; - /** * Main component of the Enigma machine * This is the mostly abstract base of any enigma machine. @@ -28,41 +25,27 @@ public abstract class Enigma protected static String machineType; protected boolean doAnomaly = false; //Has the time come to handle an anomaly? protected boolean prefAnomaly; //Do you WANT to simulate the anomaly? - protected InputPreparer inputPreparer; + + public Enigma() + { + initialize(); + } /** * Set the enigma to an initial state */ public abstract void initialize(); - /** - * Set the reflector of the enigma machine to one of type type. - * @param type type indicator of the reflector - * @return success (not every reflector fits in every machine) - */ - public abstract boolean setReflector(int type); - - /** - * Set the rotor on position pos to a rotor of type type with ring-setting ringSetting and - * rotation rotation. - * @param pos position of the rotor - * @param type type indicator - * @param ringSetting ringSetting - * @param rotation rotation - * @return success - */ - public abstract boolean setRotor(int pos, int type, int ringSetting, int rotation); - /** * Encrypt / Decrypt a given String w. * w must be prepared using prepare(w) beforehand. * Doing so changes the state of the rotors but not the state of the plugboard and the * ringSettings * - * @param w Text to decrypt/encrypt + * @param w Text to decrypt/encryptString * @return encrypted/decrypted string */ - public String encrypt(String w) + public String encryptString(String w) { //output string String output = ""; @@ -93,60 +76,16 @@ public abstract class Enigma public abstract char encryptChar(char k); /** - * Normalize the input. - * Normalizing means keeping the input via modulo in the range from 0 to n-1, where n is equal - * to the size of the rotors. - * This is necessary since java allows negative modulo values, - * which can break this implementation - * @param input input signal - * @return "normalized" input signal + * Set the state of the enigma + * @param state new state */ - public abstract int normalize(int input); + public abstract void setState(EnigmaStateBundle state); /** - * Set config of the enigma - * - * @param conf configuration + * Return an object representing the current state of the enigma + * @return state */ - public abstract void setConfiguration(int[] conf); - - /** - * Set the plugboard - * @param p Plugboard - */ - public abstract void setPlugboard(Plugboard p); - - /** - * Return the configuration, the enigma machine is in right NOW - * - * @return array containing configuration - */ - public abstract int[] getConfiguration(); - - /** - * Set the inputPreparer - * @param preparer concrete InputPreparer - */ - public void setInputPreparer(InputPreparer preparer) - { - this.inputPreparer = preparer; - } - - - - /** - * Return the inputPreparer - * @return inputPreparer - */ - public InputPreparer getInputPreparer() - { - if(inputPreparer == null) - { - MainActivity main = (MainActivity) MainActivity.ActivitySingleton.getInstance().getActivity(); - inputPreparer = InputPreparer.createInputPreparer(main.getPrefNumericLanguage()); - } - return this.inputPreparer; - } + public abstract EnigmaStateBundle getState(); /** * set prefAnomaly variable @@ -165,4 +104,5 @@ public abstract class Enigma { return machineType; } + } diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/EnigmaStateBundle.java b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/EnigmaStateBundle.java new file mode 100644 index 0000000..a433491 --- /dev/null +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/EnigmaStateBundle.java @@ -0,0 +1,301 @@ +package de.vanitasvitae.enigmandroid.enigma; + +/** + * Class that contains a possible state of an enigma machine. + * Used to store and transport configuration and settings. + * Copyright (C) 2015 Paul Schaub + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * @author vanitasvitae + */ +public class EnigmaStateBundle{ + private int typeEntryWheel; + + private int typeRotor1; + private int typeRotor2; + private int typeRotor3; + private int typeRotor4; + private int typeRotor5; + private int typeRotor6; + private int typeRotor7; + private int typeRotor8; + + private int rotationRotor1; + private int rotationRotor2; + private int rotationRotor3; + private int rotationRotor4; + private int rotationRotor5; + private int rotationRotor6; + private int rotationRotor7; + private int rotationRotor8; + + private int ringSettingRotor1; + private int ringSettingRotor2; + private int ringSettingRotor3; + private int ringSettingRotor4; + private int ringSettingRotor5; + private int ringSettingRotor6; + private int ringSettingRotor7; + private int ringSettingRotor8; + + private int typeReflector; + + private int rotationReflector; + private int ringSettingReflector; + + private String configurationPlugboard; + + private String configurationReflector; + + public int getTypeRotor1() { + return typeRotor1; + } + + public void setTypeRotor1(int typeRotor1) { + this.typeRotor1 = typeRotor1; + } + + public int getTypeRotor2() { + return typeRotor2; + } + + public void setTypeRotor2(int typeRotor2) { + this.typeRotor2 = typeRotor2; + } + + public int getTypeRotor3() { + return typeRotor3; + } + + public void setTypeRotor3(int typeRotor3) { + this.typeRotor3 = typeRotor3; + } + + public int getTypeRotor4() { + return typeRotor4; + } + + public void setTypeRotor4(int typeRotor4) { + this.typeRotor4 = typeRotor4; + } + + public int getTypeRotor5() { + return typeRotor5; + } + + public void setTypeRotor5(int typeRotor5) { + this.typeRotor5 = typeRotor5; + } + + public int getTypeRotor6() { + return typeRotor6; + } + + public void setTypeRotor6(int typeRotor6) { + this.typeRotor6 = typeRotor6; + } + + public int getTypeRotor7() { + return typeRotor7; + } + + public void setTypeRotor7(int typeRotor7) { + this.typeRotor7 = typeRotor7; + } + + public int getTypeRotor8() { + return typeRotor8; + } + + public void setTypeRotor8(int typeRotor8) { + this.typeRotor8 = typeRotor8; + } + + public int getRotationRotor1() { + return rotationRotor1; + } + + public void setRotationRotor1(int rotationRotor1) { + this.rotationRotor1 = rotationRotor1; + } + + public int getRotationRotor2() { + return rotationRotor2; + } + + public void setRotationRotor2(int rotationRotor2) { + this.rotationRotor2 = rotationRotor2; + } + + public int getRotationRotor3() { + return rotationRotor3; + } + + public void setRotationRotor3(int rotationRotor3) { + this.rotationRotor3 = rotationRotor3; + } + + public int getRotationRotor4() { + return rotationRotor4; + } + + public void setRotationRotor4(int rotationRotor4) { + this.rotationRotor4 = rotationRotor4; + } + + public int getRotationRotor5() { + return rotationRotor5; + } + + public void setRotationRotor5(int rotationRotor5) { + this.rotationRotor5 = rotationRotor5; + } + + public int getRotationRotor6() { + return rotationRotor6; + } + + public void setRotationRotor6(int rotationRotor6) { + this.rotationRotor6 = rotationRotor6; + } + + public int getRotationRotor7() { + return rotationRotor7; + } + + public void setRotationRotor7(int rotationRotor7) { + this.rotationRotor7 = rotationRotor7; + } + + public int getRotationRotor8() { + return rotationRotor8; + } + + public void setRotationRotor8(int rotationRotor8) { + this.rotationRotor8 = rotationRotor8; + } + + public int getRingSettingRotor1() { + return ringSettingRotor1; + } + + public void setRingSettingRotor1(int ringSettingRotor1) { + this.ringSettingRotor1 = ringSettingRotor1; + } + + public int getRingSettingRotor2() { + return ringSettingRotor2; + } + + public void setRingSettingRotor2(int ringSettingRotor2) { + this.ringSettingRotor2 = ringSettingRotor2; + } + + public int getRingSettingRotor3() { + return ringSettingRotor3; + } + + public void setRingSettingRotor3(int ringSettingRotor3) { + this.ringSettingRotor3 = ringSettingRotor3; + } + + public int getRingSettingRotor4() { + return ringSettingRotor4; + } + + public void setRingSettingRotor4(int ringSettingRotor4) { + this.ringSettingRotor4 = ringSettingRotor4; + } + + public int getRingSettingRotor5() { + return ringSettingRotor5; + } + + public void setRingSettingRotor5(int ringSettingRotor5) { + this.ringSettingRotor5 = ringSettingRotor5; + } + + public int getRingSettingRotor6() { + return ringSettingRotor6; + } + + public void setRingSettingRotor6(int ringSettingRotor6) { + this.ringSettingRotor6 = ringSettingRotor6; + } + + public int getRingSettingRotor7() { + return ringSettingRotor7; + } + + public void setRingSettingRotor7(int ringSettingRotor7) { + this.ringSettingRotor7 = ringSettingRotor7; + } + + public int getRingSettingRotor8() { + return ringSettingRotor8; + } + + public void setRingSettingRotor8(int ringSettingRotor8) { + this.ringSettingRotor8 = ringSettingRotor8; + } + + public int getTypeReflector() { + return typeReflector; + } + + public void setTypeReflector(int typeReflector) { + this.typeReflector = typeReflector; + } + + public int getTypeEntryWheel() { + return typeEntryWheel; + } + + public void setTypeEntryWheel(int typeEntryWheel) { + this.typeEntryWheel = typeEntryWheel; + } + + public String getConfigurationPlugboard() { + return configurationPlugboard; + } + + public void setConfigurationPlugboard(String configurationPlugboard) { + this.configurationPlugboard = configurationPlugboard; + } + + public String getConfigurationReflector() { + return configurationReflector; + } + + public void setConfigurationReflector(String configurationReflector) { + this.configurationReflector = configurationReflector; + } + + public int getRotationReflector() { + return rotationReflector; + } + + public void setRotationReflector(int rotationReflector) { + this.rotationReflector = rotationReflector; + } + + public int getRingSettingReflector() { + return ringSettingReflector; + } + + public void setRingSettingReflector(int ringSettingReflector) { + this.ringSettingReflector = ringSettingReflector; + } +} diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_D.java b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_D.java new file mode 100644 index 0000000..7593ae9 --- /dev/null +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_D.java @@ -0,0 +1,131 @@ +package de.vanitasvitae.enigmandroid.enigma; + +import android.util.Log; + +import de.vanitasvitae.enigmandroid.enigma.rotors.Reflector; +import de.vanitasvitae.enigmandroid.enigma.rotors.Rotor; + +/** + * Concrete implementation of an enigma machine of type I + * Copyright (C) 2015 Paul Schaub + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * @author vanitasvitae + */ +public class Enigma_D extends Enigma { + protected Rotor entryWheel; + protected Rotor rotor1; + protected Rotor rotor2; + protected Rotor rotor3; + + protected Reflector.ReflectorEnigmaD reflector; + + public Enigma_D() + { + super(); + machineType = "D"; + } + + @Override + public void initialize() + { + this.entryWheel = Rotor.createRotor(0, 0, 0); + this.rotor1 = Rotor.createRotor(11, 0, 0); + this.rotor2 = Rotor.createRotor(12, 0, 0); + this.rotor3 = Rotor.createRotor(13, 0, 0); + this.reflector = new Reflector.ReflectorEnigmaD(); + } + + @Override + public void nextState() + { + rotor1.rotate(); + if (rotor1.isAtTurnoverPosition() || (this.doAnomaly && prefAnomaly)) + { + rotor2.rotate(); + this.doAnomaly = rotor2.doubleTurnAnomaly(); + if (rotor2.isAtTurnoverPosition()) + { + rotor3.rotate(); + } + } + } + + @Override + public char encryptChar(char k) + { + nextState(); + int x = ((int) k)-65; //Cast to int and remove Unicode Offset (A=65 in Unicode.) + //Encryption + //forward direction + x = entryWheel.encryptForward(x); + x = rotor1.normalize(x + rotor1.getRotation() - rotor1.getRingSetting()); + x = rotor1.encryptForward(x); + x = rotor1.normalize(x - rotor1.getRotation() + rotor1.getRingSetting() + rotor2.getRotation() - rotor2.getRingSetting()); + x = rotor2.encryptForward(x); + x = rotor1.normalize(x - rotor2.getRotation() + rotor2.getRingSetting() + rotor3.getRotation() - rotor3.getRingSetting()); + x = rotor3.encryptForward(x); + x = rotor1.normalize(x - rotor3.getRotation() + rotor3.getRingSetting() + reflector.getRotation() - reflector.getRingSetting()); + //TODO: CHECK + //backward direction + x = reflector.encrypt(x); + x = rotor1.normalize(x + rotor3.getRotation() - rotor3.getRingSetting() - reflector.getRotation() + reflector.getRingSetting()); + x = rotor3.encryptBackward(x); + x = rotor1.normalize(x + rotor2.getRotation() - rotor2.getRingSetting() - rotor3.getRotation() + rotor3.getRingSetting()); + x = rotor2.encryptBackward(x); + x = rotor1.normalize(x + rotor1.getRotation() - rotor1.getRingSetting() - rotor2.getRotation() + rotor2.getRingSetting()); + x = rotor1.encryptBackward(x); + x = rotor1.normalize(x - rotor1.getRotation() + rotor1.getRingSetting()); + x = entryWheel.encryptBackward(x); + return (char) (x + 65); //Add Offset again, cast back to char and return + } + + @Override + public void setState(EnigmaStateBundle state) + { + this.entryWheel = Rotor.createRotor(state.getTypeEntryWheel(), 0, 0); + this.rotor1 = Rotor.createRotor(state.getTypeRotor1(), state.getRotationRotor1(), state.getRingSettingRotor1()); + this.rotor2 = Rotor.createRotor(state.getTypeRotor2(), state.getRotationRotor2(), state.getRingSettingRotor2()); + this.rotor3 = Rotor.createRotor(state.getTypeRotor3(), state.getRotationRotor3(), state.getRingSettingRotor3()); + this.reflector = new Reflector.ReflectorEnigmaD(Plugboard.parseConfigurationString(state.getConfigurationReflector())); + this.reflector.setRotation(state.getRotationReflector()); + this.reflector.setRingSetting(state.getRingSettingReflector()); + } + + @Override + public EnigmaStateBundle getState() + { + EnigmaStateBundle state = new EnigmaStateBundle(); + + state.setTypeRotor1(rotor1.getNumber()); + state.setTypeRotor2(rotor2.getNumber()); + state.setTypeRotor3(rotor3.getNumber()); + + state.setRotationRotor1(rotor1.getRotation()); + state.setRotationRotor2(rotor2.getRotation()); + state.setRotationRotor3(rotor3.getRotation()); + + state.setRingSettingRotor1(rotor1.getRingSetting()); + state.setRingSettingRotor2(rotor2.getRingSetting()); + state.setRingSettingRotor3(rotor3.getRingSetting()); + + state.setTypeReflector(reflector.getNumber()); + state.setRotationReflector(reflector.getRotation()); + state.setRingSettingReflector(reflector.getRingSetting()); + state.setConfigurationReflector(reflector.getConfiguration()); + + return state; + } +} diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_I.java b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_I.java index 969f950..86b1b85 100644 --- a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_I.java +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_I.java @@ -24,7 +24,8 @@ import de.vanitasvitae.enigmandroid.enigma.rotors.Rotor; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * @author vanitasvitae */ -public class Enigma_I extends Enigma { +public class Enigma_I extends Enigma +{ protected Rotor rotor1; protected Rotor rotor2; protected Rotor rotor3; @@ -33,16 +34,20 @@ public class Enigma_I extends Enigma { protected Plugboard plugboard; - public Enigma_I() { + public Enigma_I() + { + super(); machineType = "I"; } @Override public void initialize() { - this.setPlugboard(new Plugboard()); - //I,II,III, A, 0,0,0, 0,0,0 - this.setConfiguration(new int[]{1,2,3,1,0,0,0,0,0,0}); + this.plugboard= new Plugboard(); + this.rotor1 = Rotor.createRotor(1, 0, 0); + this.rotor2 = Rotor.createRotor(2, 0, 0); + this.rotor3 = Rotor.createRotor(3, 0, 0); + this.reflector = Reflector.createReflector(1); } @Override @@ -68,104 +73,59 @@ public class Enigma_I extends Enigma { //Encryption //forward direction x = plugboard.encrypt(x); - x = normalize(x + rotor1.getRotation() - rotor1.getRingSetting()); + x = rotor1.normalize(x + rotor1.getRotation() - rotor1.getRingSetting()); x = rotor1.encryptForward(x); - x = normalize(x - rotor1.getRotation() + rotor1.getRingSetting() + rotor2.getRotation() - rotor2.getRingSetting()); + x = rotor1.normalize(x - rotor1.getRotation() + rotor1.getRingSetting() + rotor2.getRotation() - rotor2.getRingSetting()); x = rotor2.encryptForward(x); - x = normalize(x - rotor2.getRotation() + rotor2.getRingSetting() + rotor3.getRotation() - rotor3.getRingSetting()); + x = rotor1.normalize(x - rotor2.getRotation() + rotor2.getRingSetting() + rotor3.getRotation() - rotor3.getRingSetting()); x = rotor3.encryptForward(x); - x = normalize(x - rotor3.getRotation() + rotor3.getRingSetting()); + x = rotor1.normalize(x - rotor3.getRotation() + rotor3.getRingSetting()); //TODO: CHECK //backward direction x = reflector.encrypt(x); - x = normalize(x + rotor3.getRotation() - rotor3.getRingSetting()); + x = rotor1.normalize(x + rotor3.getRotation() - rotor3.getRingSetting()); x = rotor3.encryptBackward(x); - x = normalize(x + rotor2.getRotation() - rotor2.getRingSetting() - rotor3.getRotation() + rotor3.getRingSetting()); + x = rotor1.normalize(x + rotor2.getRotation() - rotor2.getRingSetting() - rotor3.getRotation() + rotor3.getRingSetting()); x = rotor2.encryptBackward(x); - x = normalize(x + rotor1.getRotation() - rotor1.getRingSetting() - rotor2.getRotation() + rotor2.getRingSetting()); + x = rotor1.normalize(x + rotor1.getRotation() - rotor1.getRingSetting() - rotor2.getRotation() + rotor2.getRingSetting()); x = rotor1.encryptBackward(x); - x = normalize(x - rotor1.getRotation() + rotor1.getRingSetting()); + x = rotor1.normalize(x - rotor1.getRotation() + rotor1.getRingSetting()); x = plugboard.encrypt(x); return (char) (x + 65); //Add Offset again, cast back to char and return } @Override - public int normalize(int input) { - return (input+26) % 26; + public void setState(EnigmaStateBundle state) + { + plugboard.setConfiguration(Plugboard.parseConfigurationString( + state.getConfigurationPlugboard())); + rotor1 = Rotor.createRotor(state.getTypeRotor1(), state.getRotationRotor1(), state.getRingSettingRotor1()); + rotor2 = Rotor.createRotor(state.getTypeRotor2(), state.getRotationRotor2(), state.getRingSettingRotor2()); + rotor3 = Rotor.createRotor(state.getTypeRotor3(), state.getRotationRotor3(), state.getRingSettingRotor3()); + reflector = Reflector.createReflector(state.getTypeReflector()); } @Override - public void setPlugboard(Plugboard p) + public EnigmaStateBundle getState() { - this.plugboard = p; - } + EnigmaStateBundle state = new EnigmaStateBundle(); - @Override - public int[] getConfiguration() - { - int[] conf = new int[10]; - conf[0] = rotor1.getType(); - conf[1] = rotor2.getType(); - conf[2] = rotor3.getType(); - conf[3] = reflector.getType(); - conf[4] = rotor1.getRotation(); - conf[5] = rotor2.getRotation(); - conf[6] = rotor3.getRotation(); - conf[7] = rotor1.getRingSetting(); - conf[8] = rotor2.getRingSetting(); - conf[9] = rotor3.getRingSetting(); - return conf; - } + state.setConfigurationPlugboard(plugboard.getConfigurationString()); - @Override - /** - * conf: - * 0..2 -> rotor1..rotor3 type - * 3 -> reflector type - * 4..6 -> rotor1..rotor3 rotation - * 7..9 -> rotor1..rotor3 ringSetting - */ - public void setConfiguration(int[] conf) - { - this.setRotor(1,conf[0],conf[7],conf[4]); - this.setRotor(2,conf[1],conf[8],conf[5]); - this.setRotor(3,conf[2],conf[9],conf[6]); - this.setReflector(conf[3]); - } + state.setTypeRotor1(rotor1.getNumber()); + state.setTypeRotor2(rotor2.getNumber()); + state.setTypeRotor3(rotor3.getNumber()); - @Override - public boolean setRotor(int pos, int type, int ringSetting, int rotation) - { - if(pos >= 1 && pos <= 3) { - if (type >= 1 && type <= 5) { - Rotor rotor = Rotor.createRotor(type, ringSetting, rotation); - switch (pos) { - case 1: - rotor1 = rotor; - break; - case 2: - rotor2 = rotor; - break; - default: - rotor3 = rotor; - break; - } - return true; - } - } - Log.d("EnigmAndroid/M3/setRot", "Error: Type " + type + " at position " + pos); - return false; - } + state.setTypeReflector(reflector.getNumber()); - @Override - public boolean setReflector(int type) - { - if(type >= 1 && type <= 3) - { - reflector = Reflector.createReflector(type); - return true; - } - Log.d("EnigmAndroid/I/setRef", "Error: Can't set type "+type); - return false; + state.setRotationRotor1(rotor1.getRotation()); + state.setRotationRotor2(rotor2.getRotation()); + state.setRotationRotor3(rotor3.getRotation()); + + state.setRingSettingRotor1(rotor1.getRingSetting()); + state.setRingSettingRotor2(rotor2.getRingSetting()); + state.setRingSettingRotor3(rotor3.getRingSetting()); + + return state; } } diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_M3.java b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_M3.java index d016838..6af47a4 100644 --- a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_M3.java +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_M3.java @@ -1,7 +1,5 @@ package de.vanitasvitae.enigmandroid.enigma; -import android.util.Log; - import de.vanitasvitae.enigmandroid.enigma.rotors.Reflector; import de.vanitasvitae.enigmandroid.enigma.rotors.Rotor; @@ -33,43 +31,10 @@ public class Enigma_M3 extends Enigma_I @Override public void initialize() { - this.setPlugboard(new Plugboard()); - //I,II,III, B, 0,0,0, 0,0,0 - this.setConfiguration(new int[]{1,2,3,2,0,0,0,0,0,0}); - } - @Override - public boolean setRotor(int pos, int type, int ringSetting, int rotation) - { - if(pos >= 1 && pos <= 3) { - if (type >= 1 && type <= 8) { - Rotor rotor = Rotor.createRotor(type, ringSetting, rotation); - switch (pos) { - case 1: - rotor1 = rotor; - break; - case 2: - rotor2 = rotor; - break; - default: - rotor3 = rotor; - break; - } - return true; - } - } - Log.d("EnigmAndroid/M3/setRot", "Error: Type " + type + " at position " + pos); - return false; - } - - @Override - public boolean setReflector(int type) - { - if(type >= 2 && type <= 3) - { - reflector = Reflector.createReflector(type); - return true; - } - Log.d("EnigmAndroid/M3/setRef", "Error: Can't set type "+type); - return false; + this.plugboard = new Plugboard(); + this.rotor1 = Rotor.createRotor(1, 0, 0); + this.rotor2 = Rotor.createRotor(2, 0, 0); + this.rotor3 = Rotor.createRotor(3, 0, 0); + this.reflector = Reflector.createReflector(2); } } diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_M4.java b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_M4.java index 444faab..66e29c3 100644 --- a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_M4.java +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_M4.java @@ -29,70 +29,27 @@ public class Enigma_M4 extends Enigma private Rotor rotor1; private Rotor rotor2; private Rotor rotor3; - private Rotor rotor4; - private Reflector thinReflector; + + private Reflector reflector; private Plugboard plugboard; public Enigma_M4() { + super(); machineType = "M4"; } - @Override - public boolean setRotor(int pos, int type, int ringSetting, int rotation) - { - if(pos >= 1 && pos <= 3) - { - if(type >= 1 && type <= 8) - { - Rotor rotor = Rotor.createRotor(type, ringSetting, rotation); - switch (pos) - { - case 1: rotor1 = rotor; - break; - case 2: rotor2 = rotor; - break; - default: rotor3 = rotor; - } - return true; - } - else - { - Log.d("EnigmAndroid/M4/setRot", "Error: Type " + type + " at position " + pos); - return false; - } - } - //Thin rotor - else if(pos == 4) - { - if(type >=9 && type <=10) { - rotor4 = Rotor.createRotor(type, ringSetting, rotation); - return true; - } - } - Log.d("EnigmAndroid/M3/setRot", "Error: Type " + type + " at position " + pos); - return false; - } - - @Override - public boolean setReflector(int type) - { - if(type >= 4 && type <=5) - { - this.thinReflector = Reflector.createReflector(type); - return true; - } - Log.d("EnigmAndroid/M4/setRef","Error: Can't set type "+type); - return false; - } - @Override public void initialize() { - this.setPlugboard(new Plugboard()); - this.setConfiguration(new int[]{1,2,3,9,4,0,0,0,0,0,0,0,0}); + this.plugboard = new Plugboard(); + this.rotor1 = Rotor.createRotor(1, 0, 0); + this.rotor2 = Rotor.createRotor(2, 0, 0); + this.rotor3 = Rotor.createRotor(3, 0, 0); + this.rotor4 = Rotor.createRotor(9, 0, 0); + this.reflector = Reflector.createReflector(4); this.prefAnomaly = true; } @@ -136,79 +93,65 @@ public class Enigma_M4 extends Enigma //Encryption //forward direction x = plugboard.encrypt(x); - x = normalize(x + rotor1.getRotation() - rotor1.getRingSetting()); + x = rotor1.normalize(x + rotor1.getRotation() - rotor1.getRingSetting()); x = rotor1.encryptForward(x); - x = normalize(x - rotor1.getRotation() + rotor1.getRingSetting() + rotor2.getRotation() - rotor2.getRingSetting()); + x = rotor1.normalize(x - rotor1.getRotation() + rotor1.getRingSetting() + rotor2.getRotation() - rotor2.getRingSetting()); x = rotor2.encryptForward(x); - x = normalize(x - rotor2.getRotation() + rotor2.getRingSetting() + rotor3.getRotation() - rotor3.getRingSetting()); + x = rotor1.normalize(x - rotor2.getRotation() + rotor2.getRingSetting() + rotor3.getRotation() - rotor3.getRingSetting()); x = rotor3.encryptForward(x); - x = normalize(x - rotor3.getRotation() + rotor3.getRingSetting() + rotor4.getRotation() - rotor4.getRingSetting()); + x = rotor1.normalize(x - rotor3.getRotation() + rotor3.getRingSetting() + rotor4.getRotation() - rotor4.getRingSetting()); x = rotor4.encryptForward(x); - x = normalize(x - rotor4.getRotation() + rotor4.getRingSetting()); + x = rotor1.normalize(x - rotor4.getRotation() + rotor4.getRingSetting()); //backward direction - x = thinReflector.encrypt(x); - x = normalize(x + rotor4.getRotation() - rotor4.getRingSetting()); + x = reflector.encrypt(x); + x = rotor1.normalize(x + rotor4.getRotation() - rotor4.getRingSetting()); x = rotor4.encryptBackward(x); - x = normalize(x + rotor3.getRotation() - rotor3.getRingSetting() - rotor4.getRotation() + rotor4.getRingSetting()); + x = rotor1.normalize(x + rotor3.getRotation() - rotor3.getRingSetting() - rotor4.getRotation() + rotor4.getRingSetting()); x = rotor3.encryptBackward(x); - x = normalize(x + rotor2.getRotation() - rotor2.getRingSetting() - rotor3.getRotation() + rotor3.getRingSetting()); + x = rotor1.normalize(x + rotor2.getRotation() - rotor2.getRingSetting() - rotor3.getRotation() + rotor3.getRingSetting()); x = rotor2.encryptBackward(x); - x = normalize(x + rotor1.getRotation() - rotor1.getRingSetting() - rotor2.getRotation() + rotor2.getRingSetting()); + x = rotor1.normalize(x + rotor1.getRotation() - rotor1.getRingSetting() - rotor2.getRotation() + rotor2.getRingSetting()); x = rotor1.encryptBackward(x); - x = normalize(x - rotor1.getRotation() + rotor1.getRingSetting()); + x = rotor1.normalize(x - rotor1.getRotation() + rotor1.getRingSetting()); x = plugboard.encrypt(x); return (char) (x + 65); //Add Offset again and cast back to char } @Override - public int normalize(int input) { - return (input + 26) % 26; - } - - @Override - public void setPlugboard(Plugboard p) + public void setState(EnigmaStateBundle state) { - this.plugboard = p; + rotor1 = Rotor.createRotor(state.getTypeRotor1(), state.getRotationRotor1(), state.getRingSettingRotor1()); + rotor2 = Rotor.createRotor(state.getTypeRotor2(), state.getRotationRotor2(), state.getRingSettingRotor2()); + rotor3 = Rotor.createRotor(state.getTypeRotor3(), state.getRotationRotor3(), state.getRingSettingRotor3()); + rotor4 = Rotor.createRotor(state.getTypeRotor4(), state.getRotationRotor4(), state.getRingSettingRotor4()); + reflector = Reflector.createReflector(state.getTypeReflector()); + plugboard.setConfiguration(Plugboard.parseConfigurationString(state.getConfigurationPlugboard())); + } @Override - public int[] getConfiguration() { - int[] configuration = new int[13]; - configuration[0] = rotor1.getType(); - configuration[1] = rotor2.getType(); - configuration[2] = rotor3.getType(); - configuration[3] = rotor4.getType(); - - configuration[4] = thinReflector.getType(); - - configuration[5] = rotor1.getRotation(); - configuration[6] = rotor2.getRotation(); - configuration[7] = rotor3.getRotation(); - configuration[8] = rotor4.getRotation(); - - configuration[9] = rotor1.getRingSetting(); - configuration[10] = rotor2.getRingSetting(); - configuration[11] = rotor3.getRingSetting(); - - configuration[12] = rotor4.getRingSetting(); - return configuration; - } - - @Override - public void setConfiguration(int[] conf) + public EnigmaStateBundle getState() { - if(conf.length != 13) - { - Log.d("EnigmAndroid/M4/setCon", "Invalid conf array length. conf array length " + - "should be 13 (is "+conf.length+")"); - } - else - { - setRotor(1, conf[0], conf[9], conf[5]); - setRotor(2, conf[1], conf[10], conf[6]); - setRotor(3, conf[2], conf[11], conf[7]); - setRotor(4, conf[3], conf[12], conf[8]); - setReflector(conf[4]); - } + EnigmaStateBundle state = new EnigmaStateBundle(); + state.setTypeRotor1(rotor1.getNumber()); + state.setTypeRotor2(rotor2.getNumber()); + state.setTypeRotor3(rotor3.getNumber()); + state.setTypeRotor4(rotor4.getNumber()); + + state.setRotationRotor1(rotor1.getRotation()); + state.setRotationRotor2(rotor2.getRotation()); + state.setRotationRotor3(rotor3.getRotation()); + state.setRotationRotor4(rotor4.getRotation()); + + state.setRingSettingRotor1(rotor1.getRingSetting()); + state.setRingSettingRotor2(rotor2.getRingSetting()); + state.setRingSettingRotor3(rotor3.getRingSetting()); + state.setRingSettingRotor4(rotor4.getRingSetting()); + + state.setTypeReflector(reflector.getNumber()); + + state.setConfigurationPlugboard(plugboard.getConfigurationString()); + + return state; } } diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Plugboard.java b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Plugboard.java index 3d3350d..4e4abf9 100644 --- a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Plugboard.java +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Plugboard.java @@ -4,6 +4,8 @@ import android.app.Activity; import android.widget.Toast; import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; import de.vanitasvitae.enigmandroid.MainActivity; import de.vanitasvitae.enigmandroid.R; @@ -51,7 +53,7 @@ public class Plugboard * * @param configuration two dimensional array of plugs */ - public void setConfiguration(int[][] configuration) + public boolean setConfiguration(int[][] configuration) { if(configuration != null) { boolean validConfiguration = true; @@ -62,9 +64,18 @@ public class Plugboard break; } } - if (!validConfiguration) plugs = new Integer[26]; + if (!validConfiguration) + { + plugs = new Integer[26]; + return false; + } + return true; + } + else + { + plugs = new Integer[26]; + return false; } - else plugs = new Integer[26]; } /** @@ -116,7 +127,28 @@ public class Plugboard } return parsedConfiguration; } + } + public String getConfigurationString() + { + String out = ""; + Set remaining = new HashSet<>(); + for(int i=0; i<26; i++) + { + remaining.add(i); + } + while(!remaining.isEmpty()) + { + Integer x = remaining.iterator().next(); + if(!x.equals(encrypt(x))) + { + out = out + (char) (x+65) + (char) (encrypt(x)+65) +","; + remaining.remove(encrypt(x)); + } + remaining.remove(x); + } + if(out.length() != 0) out = out.substring(0,out.length()-1); + return out; } /** @@ -136,12 +168,15 @@ public class Plugboard +" "+(char)(a+65)+","+(char) (b+65),Toast.LENGTH_LONG).show(); return false; } - if(plugs[a] != null || plugs[b] != null) + if((plugs[a] != null || plugs[b] != null)) { - Toast.makeText(activity.getApplication().getApplicationContext(), - activity.getResources().getText(R.string.error_plug_already_in_use).toString() - +" "+(char) (a+65)+","+(char)(b +65), Toast.LENGTH_SHORT).show(); - return false; + if (!plugs[a].equals(b) || !plugs[b].equals(a)) { + Toast.makeText(activity.getApplication().getApplicationContext(), + activity.getResources().getText(R.string.error_plug_already_in_use).toString() + + " " + (char) (a + 65) + "," + (char) (b + 65), Toast.LENGTH_SHORT).show(); + return false; + } + return true; } else { @@ -153,7 +188,7 @@ public class Plugboard /** * Encrypt input via plugboard connections - * @param input input symbol to encrypt + * @param input input symbol to encryptString * @return encrypted symbol */ public int encrypt(int input) diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/inputPreparer/EditTextAdapter.java b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/inputPreparer/EditTextAdapter.java new file mode 100644 index 0000000..a2e002f --- /dev/null +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/inputPreparer/EditTextAdapter.java @@ -0,0 +1,98 @@ +package de.vanitasvitae.enigmandroid.enigma.inputPreparer; + +import android.widget.EditText; + +/** + * Adapter-like connector between text fields and string-outputting-whatever blah + * Use this to modify the way strings get displayed without modifying the string itself. + */ +public abstract class EditTextAdapter +{ + protected EditText editText; + protected String content; + + public EditTextAdapter(EditText editText) + { + this.editText = editText; + } + + /** + * Returns the unmodified text + * @return content + */ + public String getText() + { + return content; + } + + public String getModifiedText() + { + return editText.getText().toString(); + } + + /** + * Set the text to both the content and the editText without modifying it + * @param text text + */ + public void setRawText(String text) + { + this.content = text; + this.editText.setText(text); + } + + /** + * This method needs to be overwritten by the programmer. + * The coder has to make sure, content gets set to text and also that the editText element + * gets updated with the modified text + * @param text text + */ + public abstract void setText(String text); + + public static EditTextAdapter createEditTextAdapter(EditText editText, String type) + { + switch (type) + { + case "5": return new EditTextAdapter5Gap(editText); + case "no": return new EditTextAdapterNoGap(editText); + default: return new EditTextAdapterNoGap(editText); + } + } + + public static class EditTextAdapterNoGap extends EditTextAdapter + { + public EditTextAdapterNoGap(EditText editText) + { + super(editText); + } + + @Override + public void setText(String text) + { + this.content = text; + this.editText.setText(text); + } + } + + public static class EditTextAdapter5Gap extends EditTextAdapter + { + public EditTextAdapter5Gap(EditText editText) + { + super(editText); + } + + @Override + public void setText(String text) + { + this.content = text; + String out = ""; + int i; + for(i=0; i1,...,C->3) + * @param type type indicator of the reflector * @param connections wiring of the reflector as Integer array */ - protected Reflector(String name, int type, Integer[] connections) + protected Reflector(String type, int number, Integer[] connections) { - this.name = name; this.type = type; + this.number = number; this.connections = connections; } + public int getRotation() + { + return 0; + } + + public int getRingSetting() + { + return 0; + } + + public void setRotation(int rotation) + { + //Nope, do it yourself by overriding + } + + public void setRingSetting(int ringSetting) + { + //Nopedydope + } + /** * Factory method to create reflectors. * @param type type of the created reflector - * 1 -> ReflectorA - * 2 -> ReflectorB - * anything else -> ReflectorC - * @return ReflectorA | ReflectorB | ReflectorC + * "A" -> ReflectorA + * "B" -> ReflectorB + * "C" -> ReflectorC + * "ThinB" -> ReflectorThinB + * "ThinC" -> ReflectorThinC + * "ReflectorD" -> ReflectorEnigmaD + * default -> ReflectorB + * @return Reflector */ public static Reflector createReflector(int type) { @@ -58,7 +85,9 @@ public class Reflector case 2: return new ReflectorB(); case 3: return new ReflectorC(); case 4: return new ReflectorThinB(); - default: return new ReflectorThinC(); + case 5: return new ReflectorThinC(); + case 6: return new ReflectorEnigmaD(); + default: return new ReflectorB(); } } @@ -78,18 +107,14 @@ public class Reflector * Return the type indicator of the reflector * @return type */ - public int getType() + public String getType() { return this.type; } - /** - * Return phonetic name of the reflector - * @return name - */ - public String getName() + public int getNumber() { - return this.name; + return this.number; } /** @@ -164,7 +189,7 @@ public class Reflector { public ReflectorThinB() { - super("B", 4, new Integer[]{4,13,10,16,0,20,24,22,9,8,2,14,15,1,11,12,3,23,25,21,5,19,7,17,6,18}); + super("ThinB", 4, new Integer[]{4,13,10,16,0,20,24,22,9,8,2,14,15,1,11,12,3,23,25,21,5,19,7,17,6,18}); } } @@ -179,7 +204,113 @@ public class Reflector { public ReflectorThinC() { - super("B", 5, new Integer[]{17,3,14,1,9,13,19,10,21,4,7,12,11,5,2,22,25,0,23,6,24,8,15,18,20,16}); + super("ThinC", 5, new Integer[]{17,3,14,1,9,13,19,10,21,4,7,12,11,5,2,22,25,0,23,6,24,8,15,18,20,16}); + } + } + + /** + * Plugable Reflector of the Enigma machine of type D + * Standard wiring: AI,BM,CE,DT,FG,HR,JY,KS,LQ,NZ,OX,PW,UV + * Has additional ringSetting and can rotate + */ + public static class ReflectorEnigmaD extends Reflector + { + public static final String defaultWiring = "AI,BM,CE,DT,FG,HR,JY,KS,LQ,NZ,OX,PW,UV"; + private Plugboard connections; + private int ringSetting; + private int rotation; + public ReflectorEnigmaD() + { + super("Ref-D", 6, null); + connections = new Plugboard(); + reset(); + } + + public ReflectorEnigmaD(int[][] conf) + { + super("Ref-D", 6, null); + connections = new Plugboard(conf); + } + + public void reset() + { + connections.setConfiguration(Plugboard.parseConfigurationString(defaultWiring)); + } + + public boolean setWiring(String input) + { + if(input.replace(" ","").length() != 38) + return false; + return connections.setConfiguration(Plugboard.parseConfigurationString(input)); + } + + public String getConfiguration() + { + return connections.getConfigurationString(); + } + + @Override + public int getRingSetting() + { + return this.ringSetting; + } + + @Override + public int getRotation() + { + return this.rotation; + } + + @Override + public void setRingSetting(int ringSetting) + { + this.ringSetting = ringSetting; + } + + @Override + public void setRotation(int rotation) + { + this.rotation = rotation; + } + + @Override + public int encrypt(int input) + { + return this.connections.encrypt(input); + } + + public boolean isValidConfiguration() + { + return getConfiguration().length() == 38; + } + + public static ArrayList getDuplicatePlugs(String conf) + { + String s = conf.toUpperCase().replace(" ","").replace(",",""); + ArrayList duplicates = new ArrayList<>(); + for(int i=0; i<26; i++) + { + char c = (char) (i+65); + if(s.indexOf(c) == s.lastIndexOf(c)) duplicates.add(c); + } + if(duplicates.size() == 0) return null; + return duplicates; + } + + public static ArrayList getMissingPlugs(String conf) + { + String s = conf.toUpperCase().replace(" ","").replace(",",""); + ArrayList missing = new ArrayList(); + for(int i=0; i<26; i++) + { + missing.add((char) (i + 65)); + } + for(Character c : missing) + { + if(s.indexOf(c) != -1) missing.remove(c); + } + if(missing.size() == 0) return null; + return missing; } } diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/rotors/Rotor.java b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/rotors/Rotor.java index b45fcb2..1c38075 100644 --- a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/rotors/Rotor.java +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/rotors/Rotor.java @@ -26,8 +26,8 @@ package de.vanitasvitae.enigmandroid.enigma.rotors; */ public class Rotor { - protected String name; - protected int type; + protected String type; + protected int number; protected Integer[] connections; protected Integer[] reversedConnections; protected Integer[] turnOverNotches; @@ -41,21 +41,20 @@ public class Rotor * Note that connections and reversedConnections MUST be of the same size and that * neither connections nor reversedConnections respectively MUST have any number between * 0 and connections.length-1 only once (ie they represent permutations) - * @param name phonetic name of the rotor (usually I,II,...V) - * @param type type indicator (I -> 1,...,V -> 5) + * @param type type indicator * @param connections wiring of the rotor as Integer array - * @param reversedConnections inverse wiring used to encrypt in the opposite direction + * @param reversedConnections inverse wiring used to encryptString in the opposite direction * (connections[reversedConnections[i]] = i * for all i in 0..getRotorSize()-1. * @param turnOverNotches Position(s) of the turnover notch(es) * @param ringSetting setting of the ring that holds the letters * @param rotation rotation of the rotor */ - protected Rotor(String name, int type, Integer[] connections, Integer[] reversedConnections, + protected Rotor(String type, int number, Integer[] connections, Integer[] reversedConnections, Integer[] turnOverNotches, int ringSetting, int rotation) { - this.name = name; this.type = type; + this.number = number; this.connections = connections; this.reversedConnections = reversedConnections; this.turnOverNotches = turnOverNotches; @@ -69,24 +68,31 @@ public class Rotor * @param type type indicator (1..10) * 1..8 -> I..VIII * 9,10 -> Beta, Gamma + * 11..13 -> DI..DIII * @param ringSetting setting of the outer ring (0..25) * @param rotation rotation of the rotor * @return Concrete rotor */ - public static Rotor createRotor(int type, int ringSetting, int rotation) + public static Rotor createRotor(int type, int rotation, int ringSetting) { switch (type) { - case 1: return new RotorI(ringSetting, rotation); - case 2: return new RotorII(ringSetting, rotation); - case 3: return new RotorIII(ringSetting, rotation); - case 4: return new RotorIV(ringSetting, rotation); - case 5: return new RotorV(ringSetting, rotation); - case 6: return new RotorVI(ringSetting, rotation); - case 7: return new RotorVII(ringSetting, rotation); - case 8: return new RotorVIII(ringSetting, rotation); - case 9: return new RotorBeta(ringSetting, rotation); - default: return new RotorGamma(ringSetting, rotation); + case 0: return new EntryWheelD(); + case 1: return new RotorI(rotation, ringSetting); + case 2: return new RotorII(rotation, ringSetting); + case 3: return new RotorIII(rotation, ringSetting); + case 4: return new RotorIV(rotation, ringSetting); + case 5: return new RotorV(rotation, ringSetting); + case 6: return new RotorVI(rotation, ringSetting); + case 7: return new RotorVII(rotation, ringSetting); + case 8: return new RotorVIII(rotation, ringSetting); + case 9: return new RotorBeta(rotation, ringSetting); + case 10: return new RotorGamma(rotation, ringSetting); + case 11: return new RotorDI(rotation, ringSetting); + case 12: return new RotorDII(rotation, ringSetting); + case 13: return new RotorDIII(rotation, ringSetting); + + default: return new RotorI(rotation, ringSetting); } } @@ -98,7 +104,7 @@ public class Rotor */ public int encryptForward(int input) { - return this.connections[normalize(input)];// - this.ringSetting)]; + return this.connections[normalize(input)]; } /** @@ -109,18 +115,23 @@ public class Rotor */ public int encryptBackward(int input) { - return this.reversedConnections[normalize(input)];// + this.ringSetting)]; + return this.reversedConnections[normalize(input)]; } /** * Return the type indicator (usually 1..5) * @return type indicator */ - public int getType() + public String getType() { return this.type; } + public int getNumber() + { + return this.number; + } + /** * Return the current rotation of the rotor. * The rotation consists of the actual rotation - the ringSetting @@ -189,14 +200,6 @@ public class Rotor return this.ringSetting; } - /** - * Returns the phonetic name of the rotor - * @return name - */ - public String getName() - { - return this.name; - } /** * Returns the size (ie the number of wires/size of the connections array) @@ -228,7 +231,7 @@ public class Rotor */ private static class RotorI extends Rotor { - public RotorI(int ringSetting, int rotation) + public RotorI(int rotation, int ringSetting) { super("I", 1, new Integer[]{4, 10, 12, 5, 11, 6, 3, 16, 21, 25, 13, 19, 14, 22, 24, 7, 23, 20, 18, 15, 0, 8, 1, 17, 2, 9}, @@ -244,7 +247,7 @@ public class Rotor */ private static class RotorII extends Rotor { - public RotorII(int ringSetting, int rotation) + public RotorII(int rotation, int ringSetting) { super("II", 2, new Integer[]{0, 9, 3, 10, 18, 8, 17, 20, 23, 1, 11, 7, 22, 19, 12, 2, 16, 6, 25, 13, 15, 24, 5, 21, 14, 4}, @@ -260,7 +263,7 @@ public class Rotor */ private static class RotorIII extends Rotor { - public RotorIII(int ringSetting, int rotation) + public RotorIII(int rotation, int ringSetting) { super("III", 3, new Integer[]{1, 3, 5, 7, 9, 11, 2, 15, 17, 19, 23, 21, 25, 13, 24, 4, 8, 22, 6, 0, 10, 12, 20, 18, 16, 14}, @@ -276,7 +279,7 @@ public class Rotor */ private static class RotorIV extends Rotor { - public RotorIV(int ringSetting, int rotation) + public RotorIV(int rotation, int ringSetting) { super("IV", 4, new Integer[]{4, 18, 14, 21, 15, 25, 9, 0, 24, 16, 20, 8, 17, 7, 23, 11, 13, 5, 19, 6, 10, 3, 2, 12, 22, 1}, @@ -292,7 +295,7 @@ public class Rotor */ private static class RotorV extends Rotor { - public RotorV(int ringSetting, int rotation) + public RotorV(int rotation, int ringSetting) { super("V", 5, new Integer[]{21, 25, 1, 17, 6, 8, 19, 24, 20, 15, 18, 3, 13, 7, 11, 23, 0, 22, 12, 9, 16, 14, 5, 4, 2, 10}, @@ -308,7 +311,7 @@ public class Rotor */ private static class RotorVI extends Rotor { - public RotorVI(int ringSetting, int rotation) + public RotorVI(int rotation, int ringSetting) { super("VI", 6, new Integer[]{9,15,6,21,14,20,12,5,24,16,1,4,13,7,25,17,3,10,0,18,23,11,8,2,19,22}, @@ -324,7 +327,7 @@ public class Rotor */ private static class RotorVII extends Rotor { - public RotorVII(int ringSetting, int rotation) + public RotorVII(int rotation, int ringSetting) { super("VII", 7, new Integer[]{13,25,9,7,6,17,2,23,12,24,18,22,1,14,20,5,0,8,21,11,15,4,10,16,3,19}, @@ -340,7 +343,7 @@ public class Rotor */ private static class RotorVIII extends Rotor { - public RotorVIII(int ringSetting, int rotation) + public RotorVIII(int rotation, int ringSetting) { super("VIII", 8, new Integer[]{5,10,16,7,19,11,23,14,2,1,9,18,15,3,25,17,0,12,4,22,13,8,20,24,6,21}, @@ -359,9 +362,9 @@ public class Rotor */ private static class RotorBeta extends Rotor { - public RotorBeta(int ringSetting, int rotation) + public RotorBeta(int rotation, int ringSetting) { - super("Beta",9, + super("Beta", 9, new Integer[]{11,4,24,9,21,2,13,8,23,22,15,1,16,12,3,17,19,0,10,25,6,5,20,7,14,18}, new Integer[]{17,11,5,14,1,21,20,23,7,3,18,0,13,6,24,10,12,15,25,16,22,4,9,8,2,19}, new Integer[]{}, ringSetting, rotation); @@ -390,9 +393,9 @@ public class Rotor */ private static class RotorGamma extends Rotor { - public RotorGamma(int ringSetting, int rotation) + public RotorGamma(int rotation, int ringSetting) { - super("Gamma",10, + super("Gamma", 10, new Integer[]{5,18,14,10,0,13,20,4,17,7,12,1,19,8,24,2,22,11,16,15,25,23,21,6,9,3}, new Integer[]{4,11,15,25,7,0,23,9,13,24,3,17,10,5,2,19,18,8,1,12,6,22,16,21,14,20}, new Integer[]{}, ringSetting, rotation); @@ -410,4 +413,75 @@ public class Rotor return false; } } + + private static class EntryWheelD extends Rotor + { + public EntryWheelD() + { + super("ETW-D", 0, + new Integer[]{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}, + new Integer[]{16,22,4,17,19,25,20,8,14,0,18,3,5,6,7,9,10,15,24,23,2,21,1,13,12,11}, + new Integer[]{}, 0, 0); + } + @Override + public void rotate() + { + //EntryWheel doesn't rotate + } + + @Override + public boolean doubleTurnAnomaly() + { + //\forall s \in States : nope + return false; + } + } + + /** + * Rotor I as used in the Enigma Type D + * L P G S Z M H A E O Q K V X R F Y B U T N I C J D W + * Turnover Z + */ + private static class RotorDI extends Rotor + { + public RotorDI(int rotation, int ringSetting) + { + super("D-I", 11, + new Integer[]{11,15,6,18,25,12,7,0,4,14,16,10,21,23,17,5,24,1,20,19,13,8,2,9,3,22}, + new Integer[]{7,17,22,24,8,15,2,6,21,23,11,0,5,20,9,1,10,14,3,19,18,12,25,13,16,4}, + new Integer[]{25}, ringSetting, rotation); + } + } + + /** + * Rotor II as used in the Enigma Type D + * S L V G B T F X J Q O H E W I R Z Y A M K P C N D U + * Turnover F + */ + private static class RotorDII extends Rotor + { + public RotorDII(int rotation, int ringSetting) + { + super("D-II", 12, + new Integer[]{18,11,21,6,1,19,5,23,9,16,14,7,4,22,8,17,25,24,0,12,10,15,2,13,3,20}, + new Integer[]{18,4,22,24,12,6,3,11,14,8,20,1,19,23,10,21,9,15,0,5,25,2,13,7,17,16}, + new Integer[]{5}, ringSetting, rotation); + } + } + + /** + * Rotor III as used in the Enigma Type D + * C J G D P S H K T U R A W Z X F M Y N Q O B V L I E + * Turnover O + */ + private static class RotorDIII extends Rotor + { + public RotorDIII(int rotation, int ringSetting) + { + super("D-III", 13, + new Integer[]{2,9,6,3,15,18,7,10,19,20,17,0,22,25,23,5,12,24,13,16,14,1,21,11,8,4}, + new Integer[]{11,21,0,3,25,15,2,6,24,1,7,23,16,18,20,4,19,10,5,8,9,22,12,14,17,13}, + new Integer[]{14}, ringSetting, rotation); + } + } } diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/util/RotorMaker.class b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/util/RotorMaker.class new file mode 100644 index 0000000..27f61c6 Binary files /dev/null and b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/util/RotorMaker.class differ diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/util/RotorMaker.java b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/util/RotorMaker.java index 858e578..0dad7e4 100644 --- a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/util/RotorMaker.java +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/util/RotorMaker.java @@ -1,4 +1,3 @@ -package de.vanitasvitae.enigmandroid.enigma.util; /** * Used to create wiring arrays from strings @@ -26,10 +25,30 @@ public class RotorMaker public static void main(String[] args) { if(args.length == l) makeRotor(args); - else if(args.length == 1) makeRotor(prepare(args[0])); + else if(args.length == 1) + { + if(args[0].length() > 2) + makeRotor(prepare(args[0])); + else intToChar(Integer.valueOf(args[0])); + } else System.out.println("wrong input format!"); } + public static char intToChar(int x) + { + char o = (char) (x+65); + System.out.println(o); + return o; + } + + public static int charToNumber(char x) + { + x = Character.toUpperCase(x); + int i = (int) x; + i = i-65; + System.out.println(i); + return i; + } public static void makeRotor(String input) { makeRotor(prepare(input)); diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer.java b/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer.java index 1998663..8e47344 100644 --- a/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer.java +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer.java @@ -3,7 +3,11 @@ package de.vanitasvitae.enigmandroid.layout; import android.widget.EditText; import de.vanitasvitae.enigmandroid.MainActivity; +import de.vanitasvitae.enigmandroid.R; import de.vanitasvitae.enigmandroid.enigma.Enigma; +import de.vanitasvitae.enigmandroid.enigma.EnigmaStateBundle; +import de.vanitasvitae.enigmandroid.enigma.inputPreparer.EditTextAdapter; +import de.vanitasvitae.enigmandroid.enigma.inputPreparer.InputPreparer; /** * Abstract LayoutContainer for Enigma machines @@ -27,52 +31,97 @@ import de.vanitasvitae.enigmandroid.enigma.Enigma; */ public abstract class LayoutContainer { - protected MainActivity main; - protected Enigma enigma; - protected EditText inputView; protected EditText outputView; - protected int[] ringSettings; + protected EditTextAdapter input; + protected EditTextAdapter output; + + protected InputPreparer inputPreparer; + protected MainActivity main; + + protected EnigmaStateBundle state; + + public abstract Enigma getEnigma(); + protected abstract void initializeLayout(); + public abstract void resetLayout(); + protected abstract void setLayoutState(EnigmaStateBundle state); + protected abstract void refreshState(); + public abstract void showRingSettingsDialog(); + protected abstract boolean isValidConfiguration(); public LayoutContainer() { - this.main = (MainActivity) MainActivity.ActivitySingleton.getInstance().getActivity(); + main = (MainActivity) MainActivity.ActivitySingleton.getInstance().getActivity(); + this.inputView = (EditText) main.findViewById(R.id.input); + this.outputView = (EditText) main.findViewById(R.id.output); + input = EditTextAdapter.createEditTextAdapter(inputView, main.getPrefMessageFormatting()); + output = EditTextAdapter.createEditTextAdapter(outputView, main.getPrefMessageFormatting()); + initializeLayout(); } - abstract void initialize(); - public abstract void reset(); - public abstract void updateLayout(); - public abstract int[] createConfiguration(); - public abstract int[][] createPlugboardConfiguration(); - public abstract void showRingSettingsDialog(); - - public Enigma getEnigma() + public void doCrypto() { - return enigma; - } - - public EditText getInputView() - { - return this.inputView; - } - - public EditText getOutputView() - { - return this.outputView; - } - - public static LayoutContainer createLayoutContainer(String type) - { - switch (type) + //TODO: + if(inputView.getText().length()!=0) { - case "M4": - return new LayoutContainer_M4(); - case "M3": - return new LayoutContainer_M3(); - default: - return new LayoutContainer_I(); + getEnigma().setState(getState()); + String message = inputView.getText().toString(); + message = inputPreparer.prepareString(message); + input.setText(message); + if(isValidConfiguration()) { + output.setText(getEnigma().encryptString(message)); + setLayoutState(getEnigma().getState()); + } } } + + public EnigmaStateBundle getState() + { + refreshState(); + return state; + } + + public EditTextAdapter getInput() + { + return this.input; + } + + public EditTextAdapter getOutput() + { + return this.output; + } + + public static LayoutContainer createLayoutContainer(String enigmaType) + { + switch (enigmaType) + { + case "I": return new LayoutContainer_I(); + case "M3": return new LayoutContainer_M3(); + case "M4": return new LayoutContainer_M4(); + case "D": return new LayoutContainer_D(); + default: return new LayoutContainer_I(); + } + } + + public void setInputPreparer(InputPreparer inputPreparer) + { + this.inputPreparer = inputPreparer; + } + + public void setEditTextAdapter(String type) + { + String in = input.getText(); + String out = output.getText(); + input = EditTextAdapter.createEditTextAdapter(inputView, type); + input.setText(in); + output = EditTextAdapter.createEditTextAdapter(outputView, type); + output.setText(out); + } + + public InputPreparer getInputPreparer() + { + return this.inputPreparer; + } } diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_D.java b/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_D.java new file mode 100644 index 0000000..08370d1 --- /dev/null +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_D.java @@ -0,0 +1,131 @@ +package de.vanitasvitae.enigmandroid.layout; + +import android.widget.ArrayAdapter; +import android.widget.EditText; +import android.widget.Spinner; + +import de.vanitasvitae.enigmandroid.R; +import de.vanitasvitae.enigmandroid.enigma.EnigmaStateBundle; +import de.vanitasvitae.enigmandroid.enigma.Enigma_D; + +/** + * Concrete LayoutContainer for the M3 layout. + * This class contains the layout and controls the layout elements such as spinners and stuff + * Copyright (C) 2015 Paul Schaub + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * @author vanitasvitae + */ +public class LayoutContainer_D extends LayoutContainer +{ + private Enigma_D enigma; + + protected Spinner rotor1PositionView; + protected Spinner rotor2PositionView; + protected Spinner rotor3PositionView; + protected Spinner reflectorPositionView; + + protected EditText reflectorWiringView; + + public LayoutContainer_D() + { + super(); + main.setTitle("D - EnigmAndroid"); + this.resetLayout(); + } + + @Override + protected void initializeLayout() + { + this.rotor1PositionView = (Spinner) main.findViewById(R.id.rotor1position); + this.rotor2PositionView = (Spinner) main.findViewById(R.id.rotor2position); + this.rotor3PositionView = (Spinner) main.findViewById(R.id.rotor3position); + this.reflectorPositionView = (Spinner) main.findViewById(R.id.reflector_position); + this.reflectorWiringView = (EditText) main.findViewById(R.id.reflector_wiring); + + Character[] rotorPositionArray = new Character[26]; + for(int i=0; i<26; i++) {rotorPositionArray[i] = (char) (65+i); /**Fill with A..Z*/} + + ArrayAdapter rotor1PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(), + android.R.layout.simple_spinner_item,rotorPositionArray); + rotor1PositionAdapter.setDropDownViewResource( + android.R.layout.simple_spinner_dropdown_item); + rotor1PositionView.setAdapter(rotor1PositionAdapter); + ArrayAdapter rotor2PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(), + android.R.layout.simple_spinner_item,rotorPositionArray); + rotor2PositionAdapter.setDropDownViewResource( + android.R.layout.simple_spinner_dropdown_item); + rotor2PositionView.setAdapter(rotor2PositionAdapter); + ArrayAdapter rotor3PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(), + android.R.layout.simple_spinner_item,rotorPositionArray); + rotor3PositionAdapter.setDropDownViewResource( + android.R.layout.simple_spinner_dropdown_item); + rotor3PositionView.setAdapter(rotor3PositionAdapter); + ArrayAdapter reflectorPositionAdapter = new ArrayAdapter<>(main.getApplicationContext(), + android.R.layout.simple_spinner_item,rotorPositionArray); + reflectorPositionAdapter.setDropDownViewResource( + android.R.layout.simple_spinner_dropdown_item); + reflectorPositionView.setAdapter(reflectorPositionAdapter); + } + + @Override + public void resetLayout() + { + enigma = new Enigma_D(); + setLayoutState(enigma.getState()); + outputView.setText(""); + inputView.setText(""); + } + + @Override + protected void setLayoutState(EnigmaStateBundle state) + { + this.state = state; + this.rotor1PositionView.setSelection(state.getRotationRotor1()); + this.rotor2PositionView.setSelection(state.getRotationRotor2()); + this.rotor3PositionView.setSelection(state.getRotationRotor3()); + this.reflectorPositionView.setSelection(state.getRotationReflector()); + this.reflectorWiringView.setText(state.getConfigurationReflector()); + } + + @Override + protected void refreshState() + { + state.setRotationRotor1(rotor1PositionView.getSelectedItemPosition()); + state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition()); + state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition()); + state.setRotationReflector(reflectorPositionView.getSelectedItemPosition()); + state.setConfigurationReflector(reflectorWiringView.getText().toString()); + } + + public Enigma_D getEnigma() + { + return this.enigma; + } + + @Override + public void showRingSettingsDialog() + { + new RingSettingsDialogBuilder.RingSettingsDialogBuilderRotRotRotRef(). + createRingSettingsDialog(state); + } + + @Override + protected boolean isValidConfiguration() + { + //if(Reflector.ReflectorEnigmaD.) //TODO: + return true; + } +} diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_I.java b/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_I.java index a2bbbf7..50b79fb 100644 --- a/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_I.java +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_I.java @@ -1,16 +1,12 @@ package de.vanitasvitae.enigmandroid.layout; -import android.app.AlertDialog; -import android.content.DialogInterface; -import android.view.View; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.Spinner; -import android.widget.Toast; import de.vanitasvitae.enigmandroid.R; +import de.vanitasvitae.enigmandroid.enigma.EnigmaStateBundle; import de.vanitasvitae.enigmandroid.enigma.Enigma_I; -import de.vanitasvitae.enigmandroid.enigma.Plugboard; /** * Concrete LayoutContainer for the Enigma I layout. @@ -34,6 +30,8 @@ import de.vanitasvitae.enigmandroid.enigma.Plugboard; */ public class LayoutContainer_I extends LayoutContainer { + private Enigma_I enigma; + protected Spinner rotor1View; protected Spinner rotor2View; protected Spinner rotor3View; @@ -48,26 +46,21 @@ public class LayoutContainer_I extends LayoutContainer { super(); main.setTitle("I - EnigmAndroid"); - this.enigma = new Enigma_I(); - this.ringSettings = new int[]{0,0,0}; - this.rotor1View = (Spinner) main.findViewById(R.id.rotor1); - this.rotor2View = (Spinner) main.findViewById(R.id.rotor2); - this.rotor3View = (Spinner) main.findViewById(R.id.rotor3); - this.reflectorView = (Spinner) main.findViewById(R.id.reflector); - this.rotor1PositionView = (Spinner) main.findViewById(R.id.rotor1position); - this.rotor2PositionView = (Spinner) main.findViewById(R.id.rotor2position); - this.rotor3PositionView = (Spinner) main.findViewById(R.id.rotor3position); - this.plugboardView = (EditText) main.findViewById(R.id.plugboard); - this.inputView = (EditText) main.findViewById(R.id.input); - this.outputView = (EditText) main.findViewById(R.id.output); - - initialize(); - reset(); + this.resetLayout(); } @Override - void initialize() + protected void initializeLayout() { + this.rotor1View = (Spinner) main.findViewById(R.id.rotor1); + this.rotor2View = (Spinner) main.findViewById(R.id.rotor2); + this.rotor3View = (Spinner) main.findViewById(R.id.rotor3); + this.rotor1PositionView = (Spinner) main.findViewById(R.id.rotor1position); + this.rotor2PositionView = (Spinner) main.findViewById(R.id.rotor2position); + this.rotor3PositionView = (Spinner) main.findViewById(R.id.rotor3position); + this.reflectorView = (Spinner) main.findViewById(R.id.reflector); + this.plugboardView = (EditText) main.findViewById(R.id.plugboard); + Character[] rotorPositionArray = new Character[26]; for(int i=0; i<26; i++) {rotorPositionArray[i] = (char) (65+i); /**Fill with A..Z*/} @@ -107,118 +100,54 @@ public class LayoutContainer_I extends LayoutContainer } @Override - public void reset() + public void resetLayout() { - rotor1View.setSelection(0); //I - rotor2View.setSelection(1); //II - rotor3View.setSelection(2); //III - reflectorView.setSelection(0); //A - rotor1PositionView.setSelection(0); //0 - rotor2PositionView.setSelection(0); //0 - rotor3PositionView.setSelection(0); //0 - this.ringSettings = new int[]{0,0,0}; - inputView.setText(""); + enigma = new Enigma_I(); + setLayoutState(enigma.getState()); outputView.setText(""); - plugboardView.setText(""); - enigma.setConfiguration(createConfiguration()); - enigma.setPlugboard(new Plugboard()); + inputView.setText(""); } @Override - public void updateLayout() + protected void setLayoutState(EnigmaStateBundle state) { - int[] conf = enigma.getConfiguration(); - rotor1View.setSelection(conf[0]-1); - rotor2View.setSelection(conf[1]-1); - rotor3View.setSelection(conf[2]-1); - reflectorView.setSelection(conf[3]-1); - rotor1PositionView.setSelection(conf[4]); - rotor2PositionView.setSelection(conf[5]); - rotor3PositionView.setSelection(conf[6]); - ringSettings[0] = conf[7]; - ringSettings[1] = conf[8]; - ringSettings[2] = conf[9]; + this.state = state; + this.rotor1View.setSelection(state.getTypeRotor1()-1); + this.rotor2View.setSelection(state.getTypeRotor2() - 1); + this.rotor3View.setSelection(state.getTypeRotor3() - 1); + this.reflectorView.setSelection(state.getTypeReflector() - 1); + this.rotor1PositionView.setSelection(state.getRotationRotor1()); + this.rotor2PositionView.setSelection(state.getRotationRotor2()); + this.rotor3PositionView.setSelection(state.getRotationRotor3()); + this.plugboardView.setText(state.getConfigurationPlugboard()); } @Override - public int[] createConfiguration() + protected void refreshState() { - int[] conf = new int[10]; - //Rotors 1..3 - conf[0] = rotor1View.getSelectedItemPosition() + 1; - conf[1] = rotor2View.getSelectedItemPosition() + 1; - conf[2] = rotor3View.getSelectedItemPosition() + 1; - //Reflector - conf[3] = reflectorView.getSelectedItemPosition() + 1; - - conf[4] = rotor1PositionView.getSelectedItemPosition(); - conf[5] = rotor2PositionView.getSelectedItemPosition(); - conf[6] = rotor3PositionView.getSelectedItemPosition(); - - conf[7] = ringSettings[0]; - conf[8] = ringSettings[1]; - conf[9] = ringSettings[2]; - - return conf; + state.setTypeRotor1(rotor1View.getSelectedItemPosition()+1); + state.setTypeRotor2(rotor2View.getSelectedItemPosition() + 1); + state.setTypeRotor3(rotor3View.getSelectedItemPosition() + 1); + state.setTypeReflector(reflectorView.getSelectedItemPosition()+1); + state.setRotationRotor1(rotor1PositionView.getSelectedItemPosition()); + state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition()); + state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition()); + state.setConfigurationPlugboard(plugboardView.getText().toString()); } - @Override - public int[][] createPlugboardConfiguration() { - return Plugboard.parseConfigurationString(plugboardView.getText().toString()); + public Enigma_I getEnigma() + { + return this.enigma; } @Override public void showRingSettingsDialog() { - Integer[] ringArray = new Integer[26]; - for(int i=1; i<=26; i++) {ringArray[i-1] = i;} - View ringSettingsView = View.inflate(main, R.layout.dialog_ringsettings_i_m3, null); - final Spinner ring1 = (Spinner) ringSettingsView.findViewById(R.id.rotor1ring); - ArrayAdapter ring1Adapter = new ArrayAdapter<>(main, - android.R.layout.simple_spinner_item,ringArray); - ring1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - ring1.setAdapter(ring1Adapter); - ring1.setSelection(ringSettings[0]); + new RingSettingsDialogBuilder.RingSettingsDialogBuilderRotRotRot().createRingSettingsDialog(state); + } - final Spinner ring2 = (Spinner) ringSettingsView.findViewById(R.id.rotor2ring); - ArrayAdapter ring2Adapter = new ArrayAdapter<>(main, - android.R.layout.simple_spinner_item,ringArray); - ring2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - ring2.setAdapter(ring2Adapter); - ring2.setSelection(ringSettings[1]); - - final Spinner ring3 = (Spinner) ringSettingsView.findViewById(R.id.rotor3ring); - ArrayAdapter ring3Adapter = new ArrayAdapter<>(main, - android.R.layout.simple_spinner_item,ringArray); - ring3Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - ring3.setAdapter(ring3Adapter); - ring3.setSelection(ringSettings[2]); - - AlertDialog.Builder builder = new AlertDialog.Builder(main); - builder.setTitle(R.string.title_ringsetting); - builder.setView(ringSettingsView) - .setCancelable(true) - .setPositiveButton(R.string.dialog_positiv, new DialogInterface.OnClickListener() - { - public void onClick(DialogInterface dialog, int id) - { - ringSettings[0] = ring1.getSelectedItemPosition(); - ringSettings[1] = ring2.getSelectedItemPosition(); - ringSettings[2] = ring3.getSelectedItemPosition(); - String message = main.getResources().getString( - R.string.dialog_ringsettings_success) + " " + - (ringSettings[2]+1) + ", " + - (ringSettings[1]+1) + ", " + - (ringSettings[0]+1) + "."; - Toast.makeText(main, message, Toast.LENGTH_LONG).show(); - } - }) - .setNegativeButton(R.string.dialog_negativ, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - dialog.cancel(); - Toast.makeText(main, R.string.dialog_ringsettings_abort, - Toast.LENGTH_SHORT).show(); - } - }).show(); + @Override + protected boolean isValidConfiguration() { + return true; //TODO: } } \ No newline at end of file diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_M3.java b/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_M3.java index d4b7cc1..af50105 100644 --- a/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_M3.java +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_M3.java @@ -1,8 +1,11 @@ package de.vanitasvitae.enigmandroid.layout; import android.widget.ArrayAdapter; +import android.widget.EditText; +import android.widget.Spinner; import de.vanitasvitae.enigmandroid.R; +import de.vanitasvitae.enigmandroid.enigma.EnigmaStateBundle; import de.vanitasvitae.enigmandroid.enigma.Enigma_M3; /** @@ -27,16 +30,27 @@ import de.vanitasvitae.enigmandroid.enigma.Enigma_M3; */ public class LayoutContainer_M3 extends LayoutContainer_I { + private Enigma_M3 enigma; + public LayoutContainer_M3() { super(); main.setTitle("M3 - EnigmAndroid"); - this.enigma = new Enigma_M3(); + this.resetLayout(); } @Override - void initialize() + protected void initializeLayout() { + this.rotor1View = (Spinner) main.findViewById(R.id.rotor1); + this.rotor2View = (Spinner) main.findViewById(R.id.rotor2); + this.rotor3View = (Spinner) main.findViewById(R.id.rotor3); + this.rotor1PositionView = (Spinner) main.findViewById(R.id.rotor1position); + this.rotor2PositionView = (Spinner) main.findViewById(R.id.rotor2position); + this.rotor3PositionView = (Spinner) main.findViewById(R.id.rotor3position); + this.reflectorView = (Spinner) main.findViewById(R.id.reflector); + this.plugboardView = (EditText) main.findViewById(R.id.plugboard); + Character[] rotorPositionArray = new Character[26]; for(int i=0; i<26; i++) {rotorPositionArray[i] = (char) (65+i); /**Fill with A..Z*/} @@ -76,40 +90,44 @@ public class LayoutContainer_M3 extends LayoutContainer_I } @Override - public void updateLayout() + public void resetLayout() { - int[] conf = enigma.getConfiguration(); - rotor1View.setSelection(conf[0]-1); - rotor2View.setSelection(conf[1]-1); - rotor3View.setSelection(conf[2]-1); - reflectorView.setSelection(conf[3]-2); //B=2 -> 0 - rotor1PositionView.setSelection(conf[4]); - rotor2PositionView.setSelection(conf[5]); - rotor3PositionView.setSelection(conf[6]); - ringSettings[0] = conf[7]; - ringSettings[1] = conf[8]; - ringSettings[2] = conf[9]; + enigma = new Enigma_M3(); + setLayoutState(enigma.getState()); + outputView.setText(""); + inputView.setText(""); } @Override - public int[] createConfiguration() + protected void setLayoutState(EnigmaStateBundle state) { - int[] conf = new int[10]; - //Rotors 1..3 - conf[0] = rotor1View.getSelectedItemPosition() + 1; - conf[1] = rotor2View.getSelectedItemPosition() + 1; - conf[2] = rotor3View.getSelectedItemPosition() + 1; - //Reflector - conf[3] = reflectorView.getSelectedItemPosition() + 2; //M3 has no B + this.state = state; + this.rotor1View.setSelection(state.getTypeRotor1()-1); + this.rotor2View.setSelection(state.getTypeRotor2() - 1); + this.rotor3View.setSelection(state.getTypeRotor3() - 1); + this.reflectorView.setSelection(state.getTypeReflector() - 2); + this.rotor1PositionView.setSelection(state.getRotationRotor1()); + this.rotor2PositionView.setSelection(state.getRotationRotor2()); + this.rotor3PositionView.setSelection(state.getRotationRotor3()); + this.plugboardView.setText(state.getConfigurationPlugboard()); + } - conf[4] = rotor1PositionView.getSelectedItemPosition(); - conf[5] = rotor2PositionView.getSelectedItemPosition(); - conf[6] = rotor3PositionView.getSelectedItemPosition(); + @Override + protected void refreshState() + { + state.setTypeRotor1(rotor1View.getSelectedItemPosition()+1); + state.setTypeRotor2(rotor2View.getSelectedItemPosition()+1); + state.setTypeRotor3(rotor3View.getSelectedItemPosition()+1); + state.setTypeReflector(reflectorView.getSelectedItemPosition()+2); + state.setRotationRotor1(rotor1PositionView.getSelectedItemPosition()); + state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition()); + state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition()); + state.setConfigurationPlugboard(plugboardView.getText().toString()); + } - conf[7] = ringSettings[0]; - conf[8] = ringSettings[1]; - conf[9] = ringSettings[2]; - - return conf; + @Override + public Enigma_M3 getEnigma() + { + return this.enigma; } } \ No newline at end of file diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_M4.java b/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_M4.java index cea28c4..12db678 100644 --- a/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_M4.java +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_M4.java @@ -1,16 +1,12 @@ package de.vanitasvitae.enigmandroid.layout; -import android.app.AlertDialog; -import android.content.DialogInterface; -import android.view.View; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.Spinner; -import android.widget.Toast; import de.vanitasvitae.enigmandroid.R; +import de.vanitasvitae.enigmandroid.enigma.EnigmaStateBundle; import de.vanitasvitae.enigmandroid.enigma.Enigma_M4; -import de.vanitasvitae.enigmandroid.enigma.Plugboard; /** * Concrete LayoutContainer for the M4 layout. @@ -34,6 +30,8 @@ import de.vanitasvitae.enigmandroid.enigma.Plugboard; */ public class LayoutContainer_M4 extends LayoutContainer { + private Enigma_M4 enigma; + private Spinner rotor1View; private Spinner rotor2View; private Spinner rotor3View; @@ -50,28 +48,29 @@ public class LayoutContainer_M4 extends LayoutContainer { super(); main.setTitle("M4 - EnigmAndroid"); - this.enigma = new Enigma_M4(); - this.ringSettings = new int[]{0,0,0,0}; + this.resetLayout(); + } + + + + public Enigma_M4 getEnigma() + { + return this.enigma; + } + + @Override + protected void initializeLayout() { this.rotor1View = (Spinner) main.findViewById(R.id.rotor1); this.rotor2View = (Spinner) main.findViewById(R.id.rotor2); this.rotor3View = (Spinner) main.findViewById(R.id.rotor3); this.rotor4View = (Spinner) main.findViewById(R.id.thin_rotor); - this.reflectorView = (Spinner) main.findViewById(R.id.reflector); this.rotor1PositionView = (Spinner) main.findViewById(R.id.rotor1position); this.rotor2PositionView = (Spinner) main.findViewById(R.id.rotor2position); this.rotor3PositionView = (Spinner) main.findViewById(R.id.rotor3position); this.rotor4PositionView = (Spinner) main.findViewById(R.id.thin_rotor_position); + this.reflectorView = (Spinner) main.findViewById(R.id.reflector); this.plugboardView = (EditText) main.findViewById(R.id.plugboard); - this.inputView = (EditText) main.findViewById(R.id.input); - this.outputView = (EditText) main.findViewById(R.id.output); - initialize(); - reset(); - } - - @Override - void initialize() - { Character[] rotorPositionArray = new Character[26]; for(int i=0; i<26; i++) {rotorPositionArray[i] = (char) (65+i); /**Fill with A..Z*/} @@ -79,19 +78,23 @@ public class LayoutContainer_M4 extends LayoutContainer android.R.layout.simple_spinner_item); rotor1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); rotor1View.setAdapter(rotor1Adapter); + ArrayAdapter rotor2Adapter = ArrayAdapter.createFromResource(main, R.array.rotors_1_8, android.R.layout.simple_spinner_item); rotor2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); rotor2View.setAdapter(rotor2Adapter); + ArrayAdapter rotor3Adapter = ArrayAdapter.createFromResource(main, R.array.rotors_1_8, android.R.layout.simple_spinner_item); rotor3Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); rotor3View.setAdapter(rotor3Adapter); + ArrayAdapter rotor4Adapter = ArrayAdapter.createFromResource(main, R.array.rotors_beta_gamma, android.R.layout.simple_spinner_item); rotor4Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); rotor4View.setAdapter(rotor4Adapter); + ArrayAdapter reflectorAdapter = ArrayAdapter.createFromResource(main, R.array.reflectors_b_c, android.R.layout.simple_spinner_item); reflectorAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); @@ -102,16 +105,19 @@ public class LayoutContainer_M4 extends LayoutContainer rotor1PositionAdapter.setDropDownViewResource( android.R.layout.simple_spinner_dropdown_item); rotor1PositionView.setAdapter(rotor1PositionAdapter); + ArrayAdapter rotor2PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(), android.R.layout.simple_spinner_item,rotorPositionArray); rotor2PositionAdapter.setDropDownViewResource( android.R.layout.simple_spinner_dropdown_item); rotor2PositionView.setAdapter(rotor2PositionAdapter); + ArrayAdapter rotor3PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(), android.R.layout.simple_spinner_item,rotorPositionArray); rotor3PositionAdapter.setDropDownViewResource( android.R.layout.simple_spinner_dropdown_item); rotor3PositionView.setAdapter(rotor3PositionAdapter); + ArrayAdapter rotor4PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(), android.R.layout.simple_spinner_item,rotorPositionArray); rotor4PositionAdapter.setDropDownViewResource( @@ -120,135 +126,51 @@ public class LayoutContainer_M4 extends LayoutContainer } @Override - public void reset() - { - rotor1View.setSelection(0); //I - rotor2View.setSelection(1); //II - rotor3View.setSelection(2); //III - rotor4View.setSelection(0); //Beta - reflectorView.setSelection(0); //B - rotor1PositionView.setSelection(0); //0 - rotor2PositionView.setSelection(0); //0 - rotor3PositionView.setSelection(0); //0 - rotor4PositionView.setSelection(0); //0 - ringSettings = new int[]{0,0,0,0}; - inputView.setText(""); + public void resetLayout() { + enigma = new Enigma_M4(); + setLayoutState(enigma.getState()); outputView.setText(""); - plugboardView.setText(""); - enigma.setConfiguration(createConfiguration()); - enigma.setPlugboard(new Plugboard()); + inputView.setText(""); } @Override - public void updateLayout() - { - int[] conf = enigma.getConfiguration(); - rotor1View.setSelection(conf[0]-1); - rotor2View.setSelection(conf[1]-1); - rotor3View.setSelection(conf[2]-1); - rotor4View.setSelection(conf[3]-9); - reflectorView.setSelection(conf[4]-4); - rotor1PositionView.setSelection(conf[5]); - rotor2PositionView.setSelection(conf[6]); - rotor3PositionView.setSelection(conf[7]); - rotor4PositionView.setSelection(conf[8]); - ringSettings[0] = conf[9]; - ringSettings[1] = conf[10]; - ringSettings[2] = conf[11]; - ringSettings[3] = conf[12]; + protected void setLayoutState(EnigmaStateBundle state) { + this.state = state; + this.rotor1View.setSelection(state.getTypeRotor1()-1); + this.rotor2View.setSelection(state.getTypeRotor2() - 1); + this.rotor3View.setSelection(state.getTypeRotor3() - 1); + this.rotor4View.setSelection(state.getTypeRotor4() - 9); + this.reflectorView.setSelection(state.getTypeReflector() - 4); + this.rotor1PositionView.setSelection(state.getRotationRotor1()); + this.rotor2PositionView.setSelection(state.getRotationRotor2()); + this.rotor3PositionView.setSelection(state.getRotationRotor3()); + this.rotor4PositionView.setSelection(state.getRotationRotor4()); + this.plugboardView.setText(state.getConfigurationPlugboard()); } @Override - public int[] createConfiguration() - { - int[] conf = new int[13]; - //Rotors 1..4 - conf[0] = rotor1View.getSelectedItemPosition() + 1; - conf[1] = rotor2View.getSelectedItemPosition() + 1; - conf[2] = rotor3View.getSelectedItemPosition() + 1; - conf[3] = rotor4View.getSelectedItemPosition() + 9; //Beta is rotor #9 - //Reflector - conf[4] = reflectorView.getSelectedItemPosition() + 4; //thinB is reflector #4 - - conf[5] = rotor1PositionView.getSelectedItemPosition(); - conf[6] = rotor2PositionView.getSelectedItemPosition(); - conf[7] = rotor3PositionView.getSelectedItemPosition(); - conf[8] = rotor4PositionView.getSelectedItemPosition(); - - conf[9] = ringSettings[0]; - conf[10] = ringSettings[1]; - conf[11] = ringSettings[2]; - conf[12] = ringSettings[3]; - - return conf; - } - - @Override - public int[][] createPlugboardConfiguration() { - return Plugboard.parseConfigurationString(plugboardView.getText().toString()); + protected void refreshState() { + state.setTypeRotor1(rotor1View.getSelectedItemPosition()+1); + state.setTypeRotor2(rotor2View.getSelectedItemPosition()+1); + state.setTypeRotor3(rotor3View.getSelectedItemPosition()+1); + state.setTypeRotor4(rotor4View.getSelectedItemPosition()+9); + state.setTypeReflector(reflectorView.getSelectedItemPosition()+4); + state.setRotationRotor1(rotor1PositionView.getSelectedItemPosition()); + state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition()); + state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition()); + state.setRotationRotor4(rotor4PositionView.getSelectedItemPosition()); + state.setConfigurationPlugboard(plugboardView.getText().toString()); } @Override public void showRingSettingsDialog() { - Integer[] ringArray = new Integer[26]; - for(int i=1; i<=26; i++) {ringArray[i-1] = i;} - View ringSettingsView = View.inflate(main, R.layout.dialog_ringsettings_m4, null); - final Spinner ring1 = (Spinner) ringSettingsView.findViewById(R.id.rotor1ring); - ArrayAdapter ring1Adapter = new ArrayAdapter<>(main, - android.R.layout.simple_spinner_item,ringArray); - ring1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - ring1.setAdapter(ring1Adapter); - ring1.setSelection(ringSettings[0]); + new RingSettingsDialogBuilder.RingSettingsDialogBuilderRotRotRotRot(). + createRingSettingsDialog(state); + } - final Spinner ring2 = (Spinner) ringSettingsView.findViewById(R.id.rotor2ring); - ArrayAdapter ring2Adapter = new ArrayAdapter<>(main, - android.R.layout.simple_spinner_item,ringArray); - ring2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - ring2.setAdapter(ring2Adapter); - ring2.setSelection(ringSettings[1]); - - final Spinner ring3 = (Spinner) ringSettingsView.findViewById(R.id.rotor3ring); - ArrayAdapter ring3Adapter = new ArrayAdapter<>(main, - android.R.layout.simple_spinner_item,ringArray); - ring3Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - ring3.setAdapter(ring3Adapter); - ring3.setSelection(ringSettings[2]); - - final Spinner ring4 = (Spinner) ringSettingsView.findViewById(R.id.rotor4ring); - ArrayAdapter ring4Adapter = new ArrayAdapter<>(main, - android.R.layout.simple_spinner_item, ringArray); - ring4Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - ring4.setAdapter(ring4Adapter); - ring4.setSelection(ringSettings[3]); - - AlertDialog.Builder builder = new AlertDialog.Builder(main); - builder.setTitle(R.string.title_ringsetting); - builder.setView(ringSettingsView) - .setCancelable(true) - .setPositiveButton(R.string.dialog_positiv, new DialogInterface.OnClickListener() - { - public void onClick(DialogInterface dialog, int id) - { - ringSettings[0] = ring1.getSelectedItemPosition(); - ringSettings[1] = ring2.getSelectedItemPosition(); - ringSettings[2] = ring3.getSelectedItemPosition(); - ringSettings[3] = ring4.getSelectedItemPosition(); - String message = main.getResources().getString( - R.string.dialog_ringsettings_success) + " " + - (ringSettings[3]+1) + ", " + - (ringSettings[2]+1) + ", " + - (ringSettings[1]+1) + ", " + - (ringSettings[0]+1) + "."; - Toast.makeText(main, message, Toast.LENGTH_LONG).show(); - } - }) - .setNegativeButton(R.string.dialog_negativ, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - dialog.cancel(); - Toast.makeText(main, R.string.dialog_ringsettings_abort, - Toast.LENGTH_SHORT).show(); - } - }).show(); + @Override + protected boolean isValidConfiguration() { + return true; //TODO: } } \ No newline at end of file diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/layout/RingSettingsDialogBuilder.java b/app/src/main/java/de/vanitasvitae/enigmandroid/layout/RingSettingsDialogBuilder.java new file mode 100644 index 0000000..775703b --- /dev/null +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/layout/RingSettingsDialogBuilder.java @@ -0,0 +1,379 @@ +package de.vanitasvitae.enigmandroid.layout; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.util.Log; +import android.view.View; +import android.widget.ArrayAdapter; +import android.widget.Spinner; +import android.widget.TextView; +import android.widget.Toast; + +import de.vanitasvitae.enigmandroid.MainActivity; +import de.vanitasvitae.enigmandroid.R; +import de.vanitasvitae.enigmandroid.enigma.EnigmaStateBundle; + +/** + * Builder for the dialog that is used to get settings for the rings + * Copyright (C) 2015 Paul Schaub + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * @author vanitasvitae + */ +public abstract class RingSettingsDialogBuilder +{ + protected abstract void showDialog(EnigmaStateBundle stateBundle, ArrayAdapter[] adapters, int[] rIDs, Actions actions); + public abstract void createRingSettingsDialog(EnigmaStateBundle stateBundle); + + public static ArrayAdapter createAdapter(Integer[] array) + { + ArrayAdapter adapter = new ArrayAdapter<>( + MainActivity.ActivitySingleton.getInstance().getActivity(), + android.R.layout.simple_spinner_item, array); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + return adapter; + } + + public static ArrayAdapter createAdapter1_26() + { + Integer[] ringArray = new Integer[26]; + for(int i=1; i<=26; i++) {ringArray[i-1] = i;} + return createAdapter(ringArray); + } + + + + public static class RingSettingsDialogBuilderRotRotRot extends RingSettingsDialogBuilder + { + public void createRingSettingsDialog(final EnigmaStateBundle state) + { + this.showDialog(state, + new ArrayAdapter[]{ + createAdapter1_26(), + createAdapter1_26(), + createAdapter1_26()}, + new int[]{ + R.string.hint_rotor1, + R.string.hint_rotor2, + R.string.hint_rotor3}, + new Actions3(state) { + @Override + protected void firstSpinnerItemSelected(int pos) { + state.setRingSettingRotor1(pos); + } + + @Override + protected void secondSpinnerItemSelected(int pos) { + state.setRingSettingRotor2(pos); + } + + @Override + protected void thirdSpinnerItemSelected(int pos) { + state.setRingSettingRotor3(pos); + } + + @Override + protected int getFirstValueFromBundle() { + return state.getRingSettingRotor1(); + } + + @Override + protected int getSecondValueFromBundle() { + return state.getRingSettingRotor2(); + } + + @Override + protected int getThirdValueFromBundle() { + return state.getRingSettingRotor3(); + } + }); + } + + @Override + protected void showDialog(EnigmaStateBundle stateBundle, ArrayAdapter[] adapters, int[] rIDs, Actions actions) + { + if(adapters.length != 3 || rIDs.length != 3) + { + Log.d("Enigm|RingSettings", "Length of adapters array or length of rIDs array not equal to 3!"); + } + final Actions3 action = (Actions3) actions; + final MainActivity main = (MainActivity) MainActivity.ActivitySingleton.getInstance().getActivity(); + View ringSettingsView = View.inflate(main, R.layout.dialog_ringsettings_3, null); + + TextView ring1Title = (TextView) ringSettingsView.findViewById(R.id.dialog_text_rotor1); + ring1Title.setText(rIDs[0]); + TextView ring2Title = (TextView) ringSettingsView.findViewById(R.id.dialog_text_rotor2); + ring2Title.setText(rIDs[1]); + TextView ring3Title = (TextView) ringSettingsView.findViewById(R.id.dialog_text_rotor3); + ring3Title.setText(rIDs[2]); + + final Spinner ring1 = (Spinner) ringSettingsView.findViewById(R.id.rotor1ring); + ring1.setAdapter(adapters[0]); + ring1.setSelection(action.getFirstValueFromBundle()); + + final Spinner ring2 = (Spinner) ringSettingsView.findViewById(R.id.rotor2ring); + ring2.setAdapter(adapters[1]); + ring2.setSelection(action.getSecondValueFromBundle()); + + final Spinner ring3 = (Spinner) ringSettingsView.findViewById(R.id.rotor3ring); + ring3.setAdapter(adapters[2]); + ring3.setSelection(action.getThirdValueFromBundle()); + + AlertDialog.Builder builder = new AlertDialog.Builder(main); + builder.setTitle(R.string.title_ringsetting); + builder.setView(ringSettingsView) + .setCancelable(true) + .setPositiveButton(R.string.dialog_positiv, new DialogInterface.OnClickListener() + { + public void onClick(DialogInterface dialog, int id) + { + action.firstSpinnerItemSelected(ring1.getSelectedItemPosition()); + action.secondSpinnerItemSelected(ring2.getSelectedItemPosition()); + action.thirdSpinnerItemSelected(ring3.getSelectedItemPosition()); + String message = main.getResources().getString( + R.string.dialog_ringsettings_success) + " " + + (ring1.getSelectedItemPosition()+1) + ", " + + (ring2.getSelectedItemPosition()+1) + ", " + + (ring3.getSelectedItemPosition()+1) + "."; + Toast.makeText(main, message, Toast.LENGTH_LONG).show(); + } + }) + .setNegativeButton(R.string.dialog_negativ, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + dialog.cancel(); + Toast.makeText(main, R.string.dialog_ringsettings_abort, + Toast.LENGTH_SHORT).show(); + } + }).show(); + } + } + + public static class RingSettingsDialogBuilderRotRotRotRef extends RingSettingsDialogBuilder + { + @Override + public void createRingSettingsDialog(final EnigmaStateBundle state) { + this.showDialog(state, + new ArrayAdapter[]{ + createAdapter1_26(), + createAdapter1_26(), + createAdapter1_26(), + createAdapter1_26()}, + new int[]{ + R.string.hint_rotor1, + R.string.hint_rotor2, + R.string.hint_rotor3, + R.string.hint_reflector}, + new Actions4(state) { + + @Override + protected void firstSpinnerItemSelected(int pos) { + state.setRingSettingRotor1(pos); + } + + @Override + protected void secondSpinnerItemSelected(int pos) { + state.setRingSettingRotor2(pos); + } + + @Override + protected void thirdSpinnerItemSelected(int pos) { + state.setRingSettingRotor3(pos); + } + + @Override + protected int getFirstValueFromBundle() { + return state.getRingSettingRotor1(); + } + + @Override + protected int getSecondValueFromBundle() { + return state.getRingSettingRotor2(); + } + + @Override + protected int getThirdValueFromBundle() { + return state.getRingSettingRotor3(); + } + + @Override + protected void fourthSpinnerItemSelected(int pos) { + state.setRingSettingReflector(pos); + } + + @Override + protected int getFourthValueFromBundle() { + return state.getRingSettingReflector(); + } + }); + } + @Override + protected void showDialog(EnigmaStateBundle stateBundle, ArrayAdapter[] adapters, int[] rIDs, Actions actions) { + if(adapters.length != 4 || rIDs.length != 4) + { + Log.d("Enigm|RingSettings", "Length of adapters array or length of rIDs array not equal to 4!"); + } + final Actions4 action = (Actions4) actions; + final MainActivity main = (MainActivity) MainActivity.ActivitySingleton.getInstance().getActivity(); + View ringSettingsView = View.inflate(main, R.layout.dialog_ringsettings_4, null); + + TextView ring1Title = (TextView) ringSettingsView.findViewById(R.id.dialog_text_rotor1); + ring1Title.setText(rIDs[0]); + TextView ring2Title = (TextView) ringSettingsView.findViewById(R.id.dialog_text_rotor2); + ring2Title.setText(rIDs[1]); + TextView ring3Title = (TextView) ringSettingsView.findViewById(R.id.dialog_text_rotor3); + ring3Title.setText(rIDs[2]); + TextView ring4Title = (TextView) ringSettingsView.findViewById(R.id.dialog_text_rotor4); + ring4Title.setText(rIDs[3]); + + final Spinner ring1 = (Spinner) ringSettingsView.findViewById(R.id.rotor1ring); + ring1.setAdapter(adapters[0]); + ring1.setSelection(action.getFirstValueFromBundle()); + + final Spinner ring2 = (Spinner) ringSettingsView.findViewById(R.id.rotor2ring); + ring2.setAdapter(adapters[1]); + ring2.setSelection(action.getSecondValueFromBundle()); + + final Spinner ring3 = (Spinner) ringSettingsView.findViewById(R.id.rotor3ring); + ring3.setAdapter(adapters[2]); + ring3.setSelection(action.getThirdValueFromBundle()); + + final Spinner ring4 = (Spinner) ringSettingsView.findViewById(R.id.rotor4ring); + ring4.setAdapter(adapters[3]); + ring4.setSelection(action.getFourthValueFromBundle()); + + AlertDialog.Builder builder = new AlertDialog.Builder(main); + builder.setTitle(R.string.title_ringsetting); + builder.setView(ringSettingsView) + .setCancelable(true) + .setPositiveButton(R.string.dialog_positiv, new DialogInterface.OnClickListener() + { + public void onClick(DialogInterface dialog, int id) + { + action.firstSpinnerItemSelected(ring1.getSelectedItemPosition()); + action.secondSpinnerItemSelected(ring2.getSelectedItemPosition()); + action.thirdSpinnerItemSelected(ring3.getSelectedItemPosition()); + action.fourthSpinnerItemSelected(ring4.getSelectedItemPosition()); + String message = main.getResources().getString( + R.string.dialog_ringsettings_success) + " " + + (ring1.getSelectedItemPosition()+1) + ", " + + (ring2.getSelectedItemPosition()+1) + ", " + + (ring3.getSelectedItemPosition()+1) + ", " + + (ring4.getSelectedItemPosition()+1) + "."; + Toast.makeText(main, message, Toast.LENGTH_LONG).show(); + } + }) + .setNegativeButton(R.string.dialog_negativ, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + dialog.cancel(); + Toast.makeText(main, R.string.dialog_ringsettings_abort, + Toast.LENGTH_SHORT).show(); + } + }).show(); + } + } + + public static class RingSettingsDialogBuilderRotRotRotRot extends RingSettingsDialogBuilderRotRotRotRef + { + @Override + public void createRingSettingsDialog(final EnigmaStateBundle state) { + this.showDialog(state, + new ArrayAdapter[]{ + createAdapter1_26(), + createAdapter1_26(), + createAdapter1_26(), + createAdapter1_26()}, + new int[]{ + R.string.hint_rotor1, + R.string.hint_rotor2, + R.string.hint_rotor3, + R.string.hint_thin_rotor}, + new Actions4(state) { + + @Override + protected void firstSpinnerItemSelected(int pos) { + state.setRingSettingRotor1(pos); + } + + @Override + protected void secondSpinnerItemSelected(int pos) { + state.setRingSettingRotor2(pos); + } + + @Override + protected void thirdSpinnerItemSelected(int pos) { + state.setRingSettingRotor3(pos); + } + + @Override + protected int getFirstValueFromBundle() { + return state.getRingSettingRotor1(); + } + + @Override + protected int getSecondValueFromBundle() { + return state.getRingSettingRotor2(); + } + + @Override + protected int getThirdValueFromBundle() { + return state.getRingSettingRotor3(); + } + + @Override + protected void fourthSpinnerItemSelected(int pos) { + state.setRingSettingRotor4(pos); + } + + @Override + protected int getFourthValueFromBundle() { + return state.getRingSettingRotor4(); + } + }); + } + } + + public static abstract class Actions + { + protected EnigmaStateBundle stateBundle; + public Actions(EnigmaStateBundle bundle) + { + this.stateBundle = bundle; + } + } + + public static abstract class Actions3 extends Actions + { + public Actions3(EnigmaStateBundle bundle) + { + super(bundle); + } + protected abstract void firstSpinnerItemSelected(int pos); + protected abstract void secondSpinnerItemSelected(int pos); + protected abstract void thirdSpinnerItemSelected(int pos); + protected abstract int getFirstValueFromBundle(); + protected abstract int getSecondValueFromBundle(); + protected abstract int getThirdValueFromBundle(); + } + + public static abstract class Actions4 extends Actions3 + { + public Actions4(EnigmaStateBundle bundle) + { + super(bundle); + } + protected abstract void fourthSpinnerItemSelected(int pos); + protected abstract int getFourthValueFromBundle(); + } +} \ No newline at end of file diff --git a/app/src/main/res/layout-land/activity_main_d.xml b/app/src/main/res/layout-land/activity_main_d.xml new file mode 100755 index 0000000..cfabe8e --- /dev/null +++ b/app/src/main/res/layout-land/activity_main_d.xml @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + +