Finally removed the "bug" with the bad encryption; It was a known anomaly in the historical enigma machine that I oversaw. So I added this "historical bug" as a feature to the enigma. Thanks to the author of the java script version of the enigma machine for the hint :)

This commit is contained in:
vanitasvitae 2015-02-18 21:51:40 +01:00
parent 2e891d8213
commit e3ea69fd3c
13 changed files with 873 additions and 630 deletions

View file

@ -59,7 +59,7 @@
<excludeFolder url="file://$MODULE_DIR$/build/intermediates" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates" />
<excludeFolder url="file://$MODULE_DIR$/build/outputs" /> <excludeFolder url="file://$MODULE_DIR$/build/outputs" />
</content> </content>
<orderEntry type="jdk" jdkName="Android API 20 Platform" jdkType="Android SDK" /> <orderEntry type="jdk" jdkName="Android API 21 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
</component> </component>
</module> </module>

View file

@ -1,15 +1,15 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
android { android {
compileSdkVersion 20 compileSdkVersion 21
buildToolsVersion "20.0.0" buildToolsVersion "20.0.0"
defaultConfig { defaultConfig {
applicationId "de.vanitasvitae.enigmandroid" applicationId "de.vanitasvitae.enigmandroid"
minSdkVersion 15 minSdkVersion 15
targetSdkVersion 20 targetSdkVersion 21
versionCode 5 versionCode 6
versionName "17.02.2015-beta" versionName "0.1.1-18.02.2015-beta"
} }
buildTypes { buildTypes {
release { release {

View file

@ -3,149 +3,153 @@ package de.vanitasvitae.enigmandroid;
/** /**
* Enigma-machine * Enigma-machine
* @author vanitasvitae
* *
* @author vanitasvitae
*/ */
public class Enigma public class Enigma
{ {
private Plugboard plugboard; private Plugboard plugboard;
//Slots for the rotors //Slots for the rotors
private Rotor r1; private Rotor r1;
private Rotor r2; private Rotor r2;
private Rotor r3; private Rotor r3;
//Slot for the reflector //Slot for the reflector
private Rotor reflector; private Rotor reflector;
private boolean anomaly; private boolean anomaly;
//Standard configuration (rotors 1-3, reflector B, all three rotors set to position 1) //Standard configuration (rotors 1-3, reflector B, all three rotors set to position 1, rings too)
private static final int[] STANDARD_CONFIGURATION = {1,2,3,2,1,1,1}; public static final int[] STANDARD_CONFIGURATION = {1, 2, 3, 2, 1, 1, 1, 0, 0, 0};
/** /**
* Create new Enigma with given configuration. * Create new Enigma with given configuration.
* If pbconf == null no plugs will be set (no scrambling in the plugboard). * If pbconf == null no plugs will be set (no scrambling in the plugboard).
* If conf == null the enigma will be set to STANDARD_CONFIGURATION. * If conf == null the enigma will be set to STANDARD_CONFIGURATION.
* @param pbconf two-dimensional array containing the chars symbolizing plugs that need to be switched over. *
* @param conf configuration of the enigma (a,b,c,d,e,f,g - a-c rotors, d reflector, e-g positions of the rotors) * @param pbconf two-dimensional array containing the chars symbolizing plugs that need to be switched over.
*/ * @param conf configuration of the enigma (a,b,c,d,e,f,g - a-c rotors, d reflector, e-g positions of the rotors)
public Enigma(char[][] pbconf, int[] conf) throws Plugboard.PlugAlreadyUsedException */
{ public Enigma(char[][] pbconf, int[] conf) throws Plugboard.PlugAlreadyUsedException
if(conf!=null) setConfiguration(conf); {
else setConfiguration(Enigma.STANDARD_CONFIGURATION); if (conf != null) setConfiguration(conf);
else setConfiguration(Enigma.STANDARD_CONFIGURATION);
this.setPlugboard(pbconf); this.setPlugboard(pbconf);
} }
/** /**
* Encrypt / Decrypt a given String * Encrypt / Decrypt a given String
* @param w Text to decrypt/encrypt *
* @return encrypted/decrypted string * @param w Text to decrypt/encrypt
*/ * @return encrypted/decrypted string
public String encrypt(String w) */
{ public String encrypt(String w)
{
//output string //output string
String c = ""; String c = "";
//for each char x in k //for each char x in k
for(int i=0; i<w.length(); i++) for (int i = 0; i < w.length(); i++)
{ {
char x = w.charAt(i); char x = w.charAt(i);
//encrypt char //encrypt char
c = c + this.encryptChar(x); c = c + this.encryptChar(x);
} }
//return en-/decrypted string //return en-/decrypted string
return c; return c;
} }
/** /**
* Perform crypto on char. * Perform crypto on char.
* Beforehand rotate rotors. Also implement the rotor anomaly. * Beforehand rotate rotors. Also implement the rotor anomaly.
* @param k input char *
* @return output char * @param k input char
*/ * @return output char
public char encryptChar(char k) */
{ public char encryptChar(char k)
//Rotate rotors {
r1.incrementCounter(); //Rotate rotors
if(r1.isAtTurnoverPosition() || this.anomaly) r1.incrementCounter();
if (r1.isAtTurnoverPosition() || this.anomaly)
{ {
r2.incrementCounter(); r2.incrementCounter();
//Handle Anomaly //Handle Anomaly
this.anomaly = false; this.anomaly = r2.doubleTurnAnomaly();
if(r2.getCounter() == r2.getTurnOver()-1) this.anomaly=true;
if (r2.isAtTurnoverPosition()) if (r2.isAtTurnoverPosition())
{ {
r3.incrementCounter(); r3.incrementCounter();
} }
} }
int x = (int) k; int x = (int) k;
x = x-65; //Remove Unicode Offset (A=65 in Unicode.) x = x - 65; //Remove Unicode Offset (A=65 in Unicode.)
//Encryption //Encryption
//forward direction //forward direction
x = plugboard.encrypt(x); x = plugboard.encrypt(x);
x =(x + r1.getCounter())%26; x = (x + r1.getCounter()) % 26;
x = r1.encryptForward(x); x = r1.encryptForward(x);
x = (x + r2.getCounter()- r1.getCounter())%26; x = (x + r2.getCounter() - r1.getCounter()) % 26;
x = r2.encryptForward(x); x = r2.encryptForward(x);
x = (x + r3.getCounter()- r2.getCounter())%26; x = (x + r3.getCounter() - r2.getCounter()) % 26;
x = r3.encryptForward(x); x = r3.encryptForward(x);
x = (26 + x - r3.getCounter())%26; x = (26 + x - r3.getCounter()) % 26;
//backward direction //backward direction
x = reflector.encryptForward(x); x = reflector.encryptForward(x);
x = (26 + x + r3.getCounter())%26; x = (26 + x + r3.getCounter()) % 26;
x = r3.encryptBackward(x); x = r3.encryptBackward(x);
x = (26 + x - r3.getCounter()+ r2.getCounter())%26; x = (26 + x - r3.getCounter() + r2.getCounter()) % 26;
x = r2.encryptBackward(x); x = r2.encryptBackward(x);
x = (26 + x - r2.getCounter()+ r1.getCounter())%26; x = (26 + x - r2.getCounter() + r1.getCounter()) % 26;
x = r1.encryptBackward(x); x = r1.encryptBackward(x);
x = (26 + x - r1.getCounter())%26; x = (26 + x - r1.getCounter()) % 26;
x = plugboard.encrypt(x); x = plugboard.encrypt(x);
return (char) (x+65); //Add Offset return (char) (x + 65); //Add Offset
} }
/** /**
* Prepare String for encryption via enigma * Prepare String for encryption via enigma
* Replace . , ! ? : with X * Replace . , ! ? : with X
* Remove all other chars that are not A..Z * Remove all other chars that are not A..Z
* @param word string *
* @return prepared string * @param word string
*/ * @return prepared string
public static String prepare(String word) */
{ public static String prepare(String word)
String w = word.toUpperCase(); {
String w = word.toUpperCase();
String c = ""; String c = "";
for(int i=0; i<w.length(); i++) for (int i = 0; i < w.length(); i++)
{ {
char x = w.charAt(i); char x = w.charAt(i);
if(x>=65 && x<=90) //If x in [A..Z] if (x >= 65 && x <= 90) //If x in [A..Z]
{ {
c = c + x; //Append to String c = c + x; //Append to String
} }
//if x is special symbol //if x is special symbol
else else
{ {
if(x == '.' || x == ',' || x == '!' || x == '?' || x == ':') if (x == '.' || x == ',' || x == '!' || x == '?' || x == ':')
{ {
//replace x with X and encrypt //replace x with X and encrypt
c = c + 'X'; c = c + 'X';
} }
} }
} }
return c; return c;
} }
/** /**
* Create Plugboard configuration from String. * Create Plugboard configuration from String.
* String must be in format XY,AZ and so on. * String must be in format XY,AZ and so on.
* X and Y are plugs, that will be switched over. * X and Y are plugs, that will be switched over.
* Don't use plugs twice such as in AA or AB,CA. This will cause Exceptions. * Don't use plugs twice such as in AA or AB,CA. This will cause Exceptions.
* @param p String *
* @return Array containing plugboard configuration * @param p String
*/ * @return Array containing plugboard configuration
public static char[][] parsePlugs(String p) throws InvalidPlugboardConfigurationFormatException */
{ public static char[][] parsePlugs(String p) throws InvalidPlugboardConfigurationFormatException
{
//Check, if empty //Check, if empty
if(p.length()==0) if (p.length() == 0)
{ {
return null; return null;
} }
@ -154,20 +158,19 @@ public class Enigma
//Check, whether input have had a correct length. Length+1 divided by 3 should be exactly how much fields there are in the array. //Check, whether input have had a correct length. Length+1 divided by 3 should be exactly how much fields there are in the array.
//(2 chars or 2 chars followed by any times a comma and two chars) //(2 chars or 2 chars followed by any times a comma and two chars)
if(in.length!=(p.length()+1)/3) if (in.length != (p.length() + 1) / 3)
{ {
throw new InvalidPlugboardConfigurationFormatException("Error parsing plugs! Maybe you missed a ','?"); throw new InvalidPlugboardConfigurationFormatException("Error parsing plugs! Maybe you missed a ','?");
} } else
else
{ {
//Create new 2 dimensional array for pairs of plugs //Create new 2 dimensional array for pairs of plugs
char[][] plugs = new char[(p.length()+1)/3][2]; char[][] plugs = new char[(p.length() + 1) / 3][2];
//Fill the array //Fill the array
int i=0; int i = 0;
for(String x:in) for (String x : in)
{ {
//Check, whether string is not representing a pair //Check, whether string is not representing a pair
if(x.length()!=2) if (x.length() != 2)
{ {
throw new InvalidPlugboardConfigurationFormatException("Error parsing plugs! Maybe you didn't enter a pair somewhere?"); throw new InvalidPlugboardConfigurationFormatException("Error parsing plugs! Maybe you didn't enter a pair somewhere?");
} }
@ -181,163 +184,167 @@ public class Enigma
} }
return plugs; return plugs;
} }
} }
/** /**
* Set the plugboard to a new created object and give it the configuration * Set the plugboard to a new created object and give it the configuration
*
* @param c configuration * @param c configuration
* @throws Plugboard.PlugAlreadyUsedException * @throws Plugboard.PlugAlreadyUsedException
*/ */
public void setPlugboard(char[][] c) throws Plugboard.PlugAlreadyUsedException public void setPlugboard(char[][] c) throws Plugboard.PlugAlreadyUsedException
{ {
plugboard = new Plugboard(); plugboard = new Plugboard();
if(c!=null) if (c != null)
{ {
//Set each plug pair //Set each plug pair
for(char[] x : c) for (char[] x : c)
{ {
plugboard.setPlugPair(x[0],x[1]); plugboard.setPlugPair(x[0], x[1]);
} }
} }
} }
/** /**
* Set config of the enigma * Set config of the enigma
* TODO: Can't this be done in a more elegant way? *
* @param conf configuration * @param conf configuration
*/ */
public void setConfiguration(int[] conf) public void setConfiguration(int[] conf)
{ {
if(conf.length!=7) if (conf.length != 10)
{ {
setConfiguration(Enigma.STANDARD_CONFIGURATION); setConfiguration(Enigma.STANDARD_CONFIGURATION);
} } else
else {
{ int ro1 = conf[0];
int ro1 = conf[0]; int ro2 = conf[1];
int ro2 = conf[1]; int ro3 = conf[2];
int ro3 = conf[2]; int ref = conf[3];
int ref = conf[3]; int r1rot = 26 + conf[4] - 1;
int r1rot = 26+conf[4]-1; int r2rot = 26 + conf[5] - 1;
int r2rot = 26+conf[5]-1; int r3rot = 26 + conf[6] - 1;
int r3rot = 26+conf[6]-1; int ro1Ring = conf[7];
int ro2Ring = conf[8];
int ro3Ring = conf[9];
//Set first rotor //Set first rotor
switch(ro1) switch (ro1)
{ {
case 1: case 1:
{ {
r1 = new Rotor('1',(r1rot)%26,0); r1 = new Rotor('1', (r1rot) % 26, ro1Ring);
break; break;
} }
case 2: case 2:
{ {
r1 = new Rotor('2',(r1rot)%26,0); r1 = new Rotor('2', (r1rot) % 26, ro1Ring);
break; break;
} }
case 3: case 3:
{ {
r1 = new Rotor('3',(r1rot)%26,0); r1 = new Rotor('3', (r1rot) % 26, ro1Ring);
break; break;
} }
case 4: case 4:
{ {
r1 = new Rotor('4',(r1rot)%26,0); r1 = new Rotor('4', (r1rot) % 26, ro1Ring);
break; break;
} }
case 5: case 5:
{ {
r1 = new Rotor('5',(r1rot)%26,0); r1 = new Rotor('5', (r1rot) % 26, ro1Ring);
break; break;
} }
} }
//Set second rotor //Set second rotor
switch(ro2) switch (ro2)
{ {
case 1: case 1:
{ {
r2 = new Rotor('1',(r2rot)%26,0); r2 = new Rotor('1', (r2rot) % 26, ro2Ring);
break; break;
} }
case 2: case 2:
{ {
r2 = new Rotor('2',(r2rot)%26,0); r2 = new Rotor('2', (r2rot) % 26, ro2Ring);
break; break;
} }
case 3: case 3:
{ {
r2 = new Rotor('3',(r2rot)%26,0); r2 = new Rotor('3', (r2rot) % 26, ro2Ring);
break; break;
} }
case 4: case 4:
{ {
r2 = new Rotor('4',(r2rot)%26,0); r2 = new Rotor('4', (r2rot) % 26, ro2Ring);
break; break;
} }
case 5: case 5:
{ {
r2 = new Rotor('5',(r2rot)%26,0); r2 = new Rotor('5', (r2rot) % 26, ro2Ring);
break; break;
} }
} }
//Set third rotor //Set third rotor
switch(ro3) switch (ro3)
{ {
case 1: case 1:
{ {
r3 = new Rotor('1',(r3rot)%26,0); r3 = new Rotor('1', (r3rot) % 26, ro3Ring);
break; break;
} }
case 2: case 2:
{ {
r3 = new Rotor('2',(r3rot)%26,0); r3 = new Rotor('2', (r3rot) % 26, ro3Ring);
break; break;
} }
case 3: case 3:
{ {
r3 = new Rotor('3',(r3rot)%26,0); r3 = new Rotor('3', (r3rot) % 26, ro3Ring);
break; break;
} }
case 4: case 4:
{ {
r3 = new Rotor('4',(r3rot)%26,0); r3 = new Rotor('4', (r3rot) % 26, ro3Ring);
break; break;
} }
case 5: case 5:
{ {
r3 = new Rotor('5',(r3rot)%26,0); r3 = new Rotor('5', (r3rot) % 26, ro3Ring);
break; break;
} }
} }
//Set reflector //Set reflector
switch(ref) switch (ref)
{ {
case 1: case 1:
{ {
reflector = new Rotor('A',0,0); reflector = new Rotor('A', 0, 0);
break; break;
} }
case 2: case 2:
{ {
reflector = new Rotor('B',0,0); reflector = new Rotor('B', 0, 0);
break; break;
} }
case 3: case 3:
{ {
reflector = new Rotor('C',0,0); reflector = new Rotor('C', 0, 0);
break; break;
} }
} }
} }
} }
/** /**
* Return the configuration, the enigma machine is in right NOW * Return the configuration, the enigma machine is in right NOW
*
* @return array containing configuration * @return array containing configuration
*/ */
public int[] getConfiguration() public int[] getConfiguration()
{ {
int[] c = new int[7]; int[] c = new int[10];
{ {
c[0] = r1.getType(); c[0] = r1.getType();
c[1] = r2.getType(); c[1] = r2.getType();
@ -346,6 +353,9 @@ public class Enigma
c[4] = r1.getCounter(); c[4] = r1.getCounter();
c[5] = r2.getCounter(); c[5] = r2.getCounter();
c[6] = r3.getCounter(); c[6] = r3.getCounter();
c[7] = r1.getRingsetting();
c[8] = r2.getRingsetting();
c[9] = r3.getRingsetting();
} }
return c; return c;
} }

View file

@ -1,6 +1,8 @@
package de.vanitasvitae.enigmandroid; package de.vanitasvitae.enigmandroid;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.view.View;
import android.view.Menu; import android.view.Menu;
@ -12,40 +14,44 @@ import android.widget.Toast;
public class MainActivity extends Activity public class MainActivity extends Activity
{ {
private Spinner w1; private Spinner rotor1;
private Spinner w2; private Spinner rotor2;
private Spinner w3; private Spinner rotor3;
private Spinner reversingRotor; private Spinner reversingRotor;
private Spinner w1pos; private Spinner rotor1Position;
private Spinner w2pos; private Spinner rotor2Position;
private Spinner w3pos; private Spinner rotor3Position;
private EditText plugboard; private EditText plugboard;
private EditText input; private EditText input;
private EditText output; private EditText output;
private Enigma enigma; private Enigma enigma;
//memory for the ringsettings
private int[] ringsettings = {0,0,0};
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
this.setContentView(R.layout.activity_main); this.setContentView(R.layout.activity_main);
this.initLayout(); this.initLayout();
this.reset(); this.reset();
} }
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu)
// Inflate the menu; this adds items to the action bar if it is present. {
this.getMenuInflater().inflate(R.menu.main, menu); this.getMenuInflater().inflate(R.menu.main, menu);
return true; return true;
} }
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { /**
// Handle action bar item clicks here. The action bar will * Handle Options menu clicks
// automatically handle clicks on the Home/Up button, so long */
// as you specify a parent activity in AndroidManifest.xml. public boolean onOptionsItemSelected(MenuItem item)
{
int id = item.getItemId(); int id = item.getItemId();
if (id == R.id.action_version) if (id == R.id.action_version)
{ {
@ -53,60 +59,79 @@ public class MainActivity extends Activity
Toast.LENGTH_SHORT).show(); Toast.LENGTH_SHORT).show();
return true; return true;
} }
else if(id == R.id.action_reset) else if (id == R.id.action_reset)
{ {
this.reset(); this.reset();
Toast.makeText(getApplicationContext(), R.string.message_reset,
Toast.LENGTH_SHORT).show();
return true;
}
else if (id == R.id.action_choose_ringstellung)
{
showRingsettingsDialog();
return true;
} }
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
public void setEnigma(View v) /**
* Updates the enigma to the chosen rotors and plugboard
*
* @param v View
*/
public void updateEnigma(View v)
{ {
int[] conf = new int[7]; int[] conf = new int[10];
conf[0] = w1.getSelectedItemPosition()+1; conf[0] = rotor1.getSelectedItemPosition() + 1;
conf[1] = w2.getSelectedItemPosition()+1; conf[1] = rotor2.getSelectedItemPosition() + 1;
conf[2] = w3.getSelectedItemPosition()+1; conf[2] = rotor3.getSelectedItemPosition() + 1;
conf[3] = reversingRotor.getSelectedItemPosition()+1; conf[3] = reversingRotor.getSelectedItemPosition() + 1;
conf[4] = w1pos.getSelectedItemPosition()+1; conf[4] = rotor1Position.getSelectedItemPosition() + 1;
conf[5] = w2pos.getSelectedItemPosition()+1; conf[5] = rotor2Position.getSelectedItemPosition() + 1;
conf[6] = w3pos.getSelectedItemPosition()+1; conf[6] = rotor3Position.getSelectedItemPosition() + 1;
conf[7] = ringsettings[0];
conf[8] = ringsettings[1];
conf[9] = ringsettings[2];
try try
{ {
enigma = new Enigma(null,null); enigma = new Enigma(null, null);
} } catch (Plugboard.PlugAlreadyUsedException e)
catch(Plugboard.PlugAlreadyUsedException e)
{ {
//There is nothing that could possibly go wrong here. //There is nothing that could possibly go wrong here.
} }
char[][] pbconf = null; char[][] plugboardConfiguration = null;
try try
{ {
pbconf = Enigma.parsePlugs(plugboard.getText().toString()); plugboardConfiguration = Enigma.parsePlugs(plugboard.getText().toString());
} } catch (Enigma.InvalidPlugboardConfigurationFormatException e)
catch(Enigma.InvalidPlugboardConfigurationFormatException e)
{ {
String error = this.getResources().getString(R.string.error_parsing_plugs)+": "+e.getMessage(); String error = this.getResources().getString(R.string.error_parsing_plugs) + ": " + e.getMessage();
Toast.makeText(getApplicationContext(), error, Toast.makeText(getApplicationContext(), error,
Toast.LENGTH_SHORT).show(); Toast.LENGTH_LONG).show();
} }
try try
{ {
enigma.setConfiguration(conf); enigma.setConfiguration(conf);
enigma.setPlugboard(pbconf); enigma.setPlugboard(plugboardConfiguration);
} } catch (Plugboard.PlugAlreadyUsedException e)
catch(Plugboard.PlugAlreadyUsedException e)
{ {
Toast.makeText(this.getApplicationContext(), e.getMessage(), Toast.makeText(this.getApplicationContext(), e.getMessage(),
Toast.LENGTH_SHORT).show(); Toast.LENGTH_LONG).show();
} }
} }
public void crypto(View v) /**
* Set the chosen Configuration to the enigma, get the input string from the input textbox and prepare it,
* set the input to the prepared text, encrypt the prepared input and set the encrypted string to the
* output textbox and update the spinners to their new positions.
* @param v View
*/
public void doCrypto(View v)
{ {
setEnigma(null); updateEnigma(null);
String m = input.getText().toString(); String m = input.getText().toString();
m = Enigma.prepare(m); m = Enigma.prepare(m);
input.setText(m); input.setText(m);
@ -115,64 +140,72 @@ public class MainActivity extends Activity
} }
/**
* Reset all the spinners and textboxes and the ringsettings memory
*/
private void reset() private void reset()
{ {
w1.setSelection(0); rotor1.setSelection(0);
w2.setSelection(1); rotor2.setSelection(1);
w3.setSelection(2); rotor3.setSelection(2);
reversingRotor.setSelection(1); reversingRotor.setSelection(1);
w1pos.setSelection(0); rotor1Position.setSelection(0);
w2pos.setSelection(0); rotor2Position.setSelection(0);
w3pos.setSelection(0); rotor3Position.setSelection(0);
ringsettings = new int[]{0,0,0};
plugboard.setText(""); plugboard.setText("");
input.setText(""); input.setText("");
output.setText(""); output.setText("");
} }
/**
* Initialize the Layout
*/
private void initLayout() private void initLayout()
{ {
w1 = (Spinner) findViewById(R.id.w1); rotor1 = (Spinner) findViewById(R.id.rotor1);
ArrayAdapter<CharSequence> w1adapter = ArrayAdapter.createFromResource(this, ArrayAdapter<CharSequence> rotor1Adapter = ArrayAdapter.createFromResource(this,
R.array.enigma_walzen, android.R.layout.simple_spinner_item); R.array.enigma_rotors, android.R.layout.simple_spinner_item);
w1adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); rotor1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
w1.setAdapter(w1adapter); rotor1.setAdapter(rotor1Adapter);
w2 = (Spinner) findViewById(R.id.w2); rotor2 = (Spinner) findViewById(R.id.rotor2);
ArrayAdapter<CharSequence> w2adapter = ArrayAdapter.createFromResource(this, ArrayAdapter<CharSequence> rotor2Adapter = ArrayAdapter.createFromResource(this,
R.array.enigma_walzen, android.R.layout.simple_spinner_item); R.array.enigma_rotors, android.R.layout.simple_spinner_item);
w2adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); rotor2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
w2.setAdapter(w2adapter); rotor2.setAdapter(rotor2Adapter);
w3 = (Spinner) findViewById(R.id.w3); rotor3 = (Spinner) findViewById(R.id.rotor3);
ArrayAdapter<CharSequence> w3adapter = ArrayAdapter.createFromResource(this, ArrayAdapter<CharSequence> rotor3Adapter = ArrayAdapter.createFromResource(this,
R.array.enigma_walzen, android.R.layout.simple_spinner_item); R.array.enigma_rotors, android.R.layout.simple_spinner_item);
w3adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); rotor3Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
w3.setAdapter(w3adapter); rotor3.setAdapter(rotor3Adapter);
reversingRotor = (Spinner) findViewById(R.id.ukw); reversingRotor = (Spinner) findViewById(R.id.reflector);
ArrayAdapter<CharSequence> ukwadapter = ArrayAdapter.createFromResource(this, ArrayAdapter<CharSequence> relfectorAdapter = ArrayAdapter.createFromResource(this,
R.array.enigma_ukw, android.R.layout.simple_spinner_item); R.array.enigma_reflectors, android.R.layout.simple_spinner_item);
ukwadapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); relfectorAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
reversingRotor.setAdapter(ukwadapter); reversingRotor.setAdapter(relfectorAdapter);
w1pos = (Spinner) findViewById(R.id.w1pos); rotor1Position = (Spinner) findViewById(R.id.rotor1position);
ArrayAdapter<CharSequence> w1posadapter = ArrayAdapter.createFromResource(this, ArrayAdapter<CharSequence> rotor1PositionAdapter = ArrayAdapter.createFromResource(this,
R.array.positions, android.R.layout.simple_spinner_item); R.array.rotor_positions, android.R.layout.simple_spinner_item);
w1posadapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); rotor1PositionAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
w1pos.setAdapter(w1posadapter); rotor1Position.setAdapter(rotor1PositionAdapter);
w2pos = (Spinner) findViewById(R.id.w2pos); rotor2Position = (Spinner) findViewById(R.id.rotor2position);
ArrayAdapter<CharSequence> w2posadapter = ArrayAdapter.createFromResource(this, ArrayAdapter<CharSequence> rotor2PositionAdapter = ArrayAdapter.createFromResource(this,
R.array.positions, android.R.layout.simple_spinner_item); R.array.rotor_positions, android.R.layout.simple_spinner_item);
w2posadapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); rotor2PositionAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
w2pos.setAdapter(w2posadapter); rotor2Position.setAdapter(rotor2PositionAdapter);
w3pos = (Spinner) findViewById(R.id.w3pos); rotor3Position = (Spinner) findViewById(R.id.rotor3position);
ArrayAdapter<CharSequence> w3posadapter = ArrayAdapter.createFromResource(this, ArrayAdapter<CharSequence> rotor3PositionAdapter = ArrayAdapter.createFromResource(this,
R.array.positions, android.R.layout.simple_spinner_item); R.array.rotor_positions, android.R.layout.simple_spinner_item);
w3posadapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); rotor3PositionAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
w3pos.setAdapter(w3posadapter); rotor3Position.setAdapter(rotor3PositionAdapter);
plugboard = (EditText) findViewById(R.id.plugboard); plugboard = (EditText) findViewById(R.id.plugboard);
input = (EditText) findViewById(R.id.input); input = (EditText) findViewById(R.id.input);
@ -181,13 +214,67 @@ public class MainActivity extends Activity
input.requestFocus(); input.requestFocus();
} }
/**
* Update the Spinners to their new Positions
* @param c Configuration
*/
public void updateSpinner(int[] c) public void updateSpinner(int[] c)
{ {
w1.setSelection(c[0]-1); rotor1.setSelection(c[0] - 1);
w2.setSelection(c[1]-1); rotor2.setSelection(c[1] - 1);
w3.setSelection(c[2]-1); rotor3.setSelection(c[2] - 1);
w1pos.setSelection(c[4]); rotor1Position.setSelection(c[4]);
w2pos.setSelection(c[5]); rotor2Position.setSelection(c[5]);
w3pos.setSelection(c[6]); rotor3Position.setSelection(c[6]);
}
/**
* Show the dialog where the user can pick the ringsettings and set them if the user doesnt abort.
*/
public void showRingsettingsDialog()
{
View ringsettingsView = View.inflate(this, R.layout.dialog_ringsettings, null);
final Spinner ring1 = (Spinner) ringsettingsView.findViewById(R.id.rotor1ring);
ArrayAdapter<CharSequence> ring1Adapter = ArrayAdapter.createFromResource(this, R.array.ring_positions, android.R.layout.simple_spinner_item);
ring1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
ring1.setAdapter(ring1Adapter);
ring1.setSelection(ringsettings[0]);
final Spinner ring2 = (Spinner) ringsettingsView.findViewById(R.id.rotor2ring);
ArrayAdapter<CharSequence> ring2Adapter = ArrayAdapter.createFromResource(this, R.array.ring_positions, android.R.layout.simple_spinner_item);
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<CharSequence> ring3Adapter = ArrayAdapter.createFromResource(this, R.array.ring_positions, android.R.layout.simple_spinner_item);
ring3Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
ring3.setAdapter(ring3Adapter);
ring3.setSelection(ringsettings[2]);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
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 = new int[]{ring1.getSelectedItemPosition(), ring2.getSelectedItemPosition(), ring3.getSelectedItemPosition()};
String message = getResources().getString(R.string.dialog_ringsettings_success) + " " + (ringsettings[2]+1) + ", " + (ringsettings[1]+1) + ", " + (ringsettings[0]+1) + ".";
Toast.makeText(getApplicationContext(), message,
Toast.LENGTH_LONG).show();
}
})
.setNegativeButton(R.string.dialog_negativ, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
dialog.cancel();
Toast.makeText(getApplicationContext(), R.string.dialog_ringsettings_abort,
Toast.LENGTH_SHORT).show();
}
}).show();
} }
} }

View file

@ -2,94 +2,81 @@ package de.vanitasvitae.enigmandroid;
/** /**
* Class representing the plugboard * Class representing the plugboard
* @author vanitasvitae
* *
* @author vanitasvitae
*/ */
public class Plugboard public class Plugboard
{ {
//Plugboard //Plugboard
// Q W E R T Z U I O // Q W E R T Z U I O
// A S D F G H J K // A S D F G H J K
// P Y X C V B N M L // P Y X C V B N M L
//Array containing plugged pairs //Array containing plugged pairs
int[] pb; int[] pb;
//Standard array to compare pb to. //Standard array to compare pb to.
public static final int[] ref = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25}; public static final int[] ref = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25};
/**
* Create new plugboard without any plugged pairs. (empty, no scrambling here)
*/
public Plugboard()
{
pb = new int[26];
resetPlugboard();
}
/**
* En-/decrypt a char following the connections on the plugboard
* @param x char to perform crypto on
* @return en-/decrypted char
*/
public int encrypt(int x)
{
return pb[x];
}
/**
* Reset the plugboard (no plugged pairs)
*/
public void resetPlugboard()
{
pb = new int[]{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25};
}
/** /**
* Set plugs given by 2 dimensional array * Create new plugboard without any plugged pairs. (empty, no scrambling here)
* @param p configuration
* @throws PlugAlreadyUsedException
*/ */
public void setPlugs(char[][] p) throws PlugAlreadyUsedException public Plugboard()
{ {
for(char[] x : p) pb = new int[26];
{ resetPlugboard();
if(x!=null) }
{
this.setPlugPair(x[0], x[1]); /**
} * En-/decrypt a char following the connections on the plugboard
} *
} * @param x char to perform crypto on
/** * @return en-/decrypted char
* Set a pair of plugs on the plugboard */
* @param a first Plug public int encrypt(int x)
* @param b second Plug {
*/ return pb[x];
public void setPlugPair(char a, char b) throws PlugAlreadyUsedException }
{
//prevent to plug a plug to itself /**
if(a==b) * Reset the plugboard (no plugged pairs)
*/
public void resetPlugboard()
{
pb = new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25};
}
/**
* Set a pair of plugs on the plugboard
*
* @param a first Plug
* @param b second Plug
*/
public void setPlugPair(char a, char b) throws PlugAlreadyUsedException
{
//prevent to plug a plug to itself
if (a == b)
{ {
throw new PlugAlreadyUsedException("Unable to plug "+a +" to " +a); throw new PlugAlreadyUsedException("Unable to plug " + a + " to " + a);
} }
int x = a-65; int x = a - 65;
int y = b-65; int y = b - 65;
//Check, if plugs already plugged //Check, if plugs already plugged
if(pb[x]!=ref[x]) if (pb[x] != ref[x])
{ {
throw new PlugAlreadyUsedException("Plug " + a + " used twice!"); throw new PlugAlreadyUsedException("Plug " + a + " used twice!");
} } else if (pb[y] != ref[y])
else if(pb[y]!=ref[y])
{ {
throw new PlugAlreadyUsedException("Plug " + b + " used twice!"); throw new PlugAlreadyUsedException("Plug " + b + " used twice!");
} }
//If everything is correct //If everything is correct
else else
{ {
//set the pair //set the pair
int c =pb[x]; int c = pb[x];
pb[x] = pb[y]; pb[x] = pb[y];
pb[y] = c; pb[y] = c;
} }
} }
public static class PlugAlreadyUsedException extends Exception public static class PlugAlreadyUsedException extends Exception
{ {

View file

@ -2,210 +2,237 @@ package de.vanitasvitae.enigmandroid;
/** /**
* Class representing a rotor of the Enigma machine (I-V,A-C) * Class representing a rotor of the Enigma machine (I-V,A-C)
* @author vanitas
* *
* @author vanitas
*/ */
public class Rotor public class Rotor
{ {
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
//ABC: 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z' //ABC: 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'
//Rotor1: 'E','K','M','F','L','G','D','Q','V','Z','N','T','O','W','Y','H','X','U','S','P','A','I','B','R','C','J' //Rotor1: 'E','K','M','F','L','G','D','Q','V','Z','N','T','O','W','Y','H','X','U','S','P','A','I','B','R','C','J'
//Rotor2: 'A','J','D','K','S','I','R','U','X','B','L','H','W','T','M','C','Q','G','Z','N','P','Y','F','V','O','E' //Rotor2: 'A','J','D','K','S','I','R','U','X','B','L','H','W','T','M','C','Q','G','Z','N','P','Y','F','V','O','E'
//Rotor3: 'B','D','F','H','J','L','C','P','R','T','X','V','Z','N','Y','E','I','W','G','A','K','M','U','S','Q','O' //Rotor3: 'B','D','F','H','J','L','C','P','R','T','X','V','Z','N','Y','E','I','W','G','A','K','M','U','S','Q','O'
//Rotor4: 'E','S','O','V','P','Z','J','A','Y','Q','U','I','R','H','X','L','N','F','T','G','K','D','C','M','W','B' //Rotor4: 'E','S','O','V','P','Z','J','A','Y','Q','U','I','R','H','X','L','N','F','T','G','K','D','C','M','W','B'
//Rotor5: 'V','Z','B','R','G','I','T','Y','U','P','S','D','N','H','L','X','A','W','M','J','Q','O','F','E','C','K' //Rotor5: 'V','Z','B','R','G','I','T','Y','U','P','S','D','N','H','L','X','A','W','M','J','Q','O','F','E','C','K'
//Reversing Rotor A: AE BJ CM DZ FL GY HX IV KW NR OQ PU ST //Reversing Rotor A: AE BJ CM DZ FL GY HX IV KW NR OQ PU ST
//Reversing Rotor B: AY BR CU DH EQ FS GL IP JX KN MO TZ VW //Reversing Rotor B: AY BR CU DH EQ FS GL IP JX KN MO TZ VW
//Reversing Rotor C: AF BV CP DJ EI GO HY KR LZ MX NW QT SU //Reversing Rotor C: AF BV CP DJ EI GO HY KR LZ MX NW QT SU
//Original rotors //Original rotors
public static final Integer[] rotor1 = {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}; public static final Integer[] rotor1 = {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};
public static final Integer[] rotor2 = {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}; public static final Integer[] rotor2 = {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};
public static final Integer[] rotor3 = {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}; public static final Integer[] rotor3 = {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};
public static final Integer[] rotor4 = {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}; public static final Integer[] rotor4 = {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};
public static final Integer[] rotor5 = {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}; public static final Integer[] rotor5 = {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};
//Original rotors backwards direction //Original rotors backwards direction
public static final Integer[] backwardsRotor1 = {20,22,24,6,0,3,5,15,21,25,1,4,2,10,12,19,7,23,18,11,17,8,13,16,14,9}; public static final Integer[] backwardsRotor1 = {20, 22, 24, 6, 0, 3, 5, 15, 21, 25, 1, 4, 2, 10, 12, 19, 7, 23, 18, 11, 17, 8, 13, 16, 14, 9};
public static final Integer[] backwardsRotor2 = {0,9,15,2,25,22,17,11,5,1,3,10,14,19,24,20,16,6,4,13,7,23,12,8,21,18}; public static final Integer[] backwardsRotor2 = {0, 9, 15, 2, 25, 22, 17, 11, 5, 1, 3, 10, 14, 19, 24, 20, 16, 6, 4, 13, 7, 23, 12, 8, 21, 18};
public static final Integer[] backwardsRotor3 = {19,0,6,1,15,2,18,3,16,4,20,5,21,13,25,7,24,8,23,9,22,11,17,10,14,12}; public static final Integer[] backwardsRotor3 = {19, 0, 6, 1, 15, 2, 18, 3, 16, 4, 20, 5, 21, 13, 25, 7, 24, 8, 23, 9, 22, 11, 17, 10, 14, 12};
public static final Integer[] backwardsRotor4 = {7,25,22,21,0,17,19,13,11,6,20,15,23,16,2,4,9,12,1,18,10,3,24,14,8,5}; public static final Integer[] backwardsRotor4 = {7, 25, 22, 21, 0, 17, 19, 13, 11, 6, 20, 15, 23, 16, 2, 4, 9, 12, 1, 18, 10, 3, 24, 14, 8, 5};
public static final Integer[] backwardsRotor5 = {16,2,24,11,23,22,4,13,5,19,25,14,18,12,21,9,20,3,10,6,8,0,17,15,7,1}; public static final Integer[] backwardsRotor5 = {16, 2, 24, 11, 23, 22, 4, 13, 5, 19, 25, 14, 18, 12, 21, 9, 20, 3, 10, 6, 8, 0, 17, 15, 7, 1};
//Original reflector rotors A,B,C, D, E,F, G, H, I, J,K, L,M,N, O, P, Q, R, S, T, U, V,W, X,Y,Z //Original reflector rotors A,B,C, D, E,F, G, H, I, J,K, L,M,N, O, P, Q, R, S, T, U, V,W, X,Y,Z
public static final Integer[] reflectorA = {4,9,12,25,0,11,24,23,21,1,22,5,2,17,16,20,14,13,19,18,15,8,10,7,6,3}; public static final Integer[] reflectorA = {4, 9, 12, 25, 0, 11, 24, 23, 21, 1, 22, 5, 2, 17, 16, 20, 14, 13, 19, 18, 15, 8, 10, 7, 6, 3};
public static final Integer[] reflectorB = {24,17,20,7,16,18,11,3,15,23,13,6,14,10,12,8,4,1,5,25,2,22,21,9,0,19}; public static final Integer[] reflectorB = {24, 17, 20, 7, 16, 18, 11, 3, 15, 23, 13, 6, 14, 10, 12, 8, 4, 1, 5, 25, 2, 22, 21, 9, 0, 19};
public static final Integer[] reflectorC = {5,21,15,9,8,0,14,24,4,3,17,25,23,22,6,2,19,10,20,16,18,1,13,12,7,11}; public static final Integer[] reflectorC = {5, 21, 15, 9, 8, 0, 14, 24, 4, 3, 17, 25, 23, 22, 6, 2, 19, 10, 20, 16, 18, 1, 13, 12, 7, 11};
//Atributes of the rotor //Attributes of the rotor
private Integer[] rotor; //choose one of rotor1-5 private Integer[] rotor; //choose one of rotor1-5
private Integer[] rrotor; //choose one of backwardsRotor1-5 private Integer[] backwardsRotor; //choose one of backwardsRotor1-5
private int ringsetting; private int ringsetting;
private int turnOver; private int turnOver;
private int counter; private int counter;
private String name; private String name;
private int type; private int type;
/** /**
* Create new Rotor (1 - 5 = normal rotor, -1 - -3 = reversing rotor) * Create new Rotor (1 - 5 = normal rotor, -1 - -3 = reversing rotor)
* @param type integer determines type *
* @param setting setting (rotation) of the rotor * @param type integer determines type
*/ * @param setting setting (rotation) of the rotor
public Rotor(char type, int setting, int ring) */
{ public Rotor(char type, int setting, int ring)
this.ringsetting = ring%26; {
switch(type) this.ringsetting = ring;
{ switch (type)
case '1': {
{ case '1':
this.rotor = rotor1; {
this.rrotor = backwardsRotor1; this.rotor = rotor1;
this.counter = setting; this.backwardsRotor = backwardsRotor1;
this.name="I"; this.counter = setting;
this.turnOver = 17; //"Royal" this.name = "I";
this.type = 1; this.turnOver = 17; //"Royal"
break; this.type = 1;
} break;
case '2': }
{ case '2':
this.rotor = rotor2; {
this.rrotor = backwardsRotor2; this.rotor = rotor2;
this.counter = setting; this.backwardsRotor = backwardsRotor2;
this.name="II"; this.counter = setting;
this.turnOver = 5; //"Flags" this.name = "II";
this.type = 2; this.turnOver = 5; //"Flags"
break; this.type = 2;
} break;
case '3': }
{ case '3':
this.rotor = rotor3; {
this.rrotor = backwardsRotor3; this.rotor = rotor3;
this.counter = setting; this.backwardsRotor = backwardsRotor3;
this.name="III"; this.counter = setting;
this.turnOver = 22; //"Wave" this.name = "III";
this.type = 3; this.turnOver = 22; //"Wave"
break; this.type = 3;
} break;
case '4': }
{ case '4':
this.rotor = rotor4; {
this.rrotor = backwardsRotor4; this.rotor = rotor4;
this.counter = setting; this.backwardsRotor = backwardsRotor4;
this.name="IV"; this.counter = setting;
this.turnOver = 10; //"Kings" this.name = "IV";
this.type = 4; this.turnOver = 10; //"Kings"
break; this.type = 4;
} break;
case '5': }
{ case '5':
this.rotor = rotor5; {
this.rrotor = backwardsRotor5; this.rotor = rotor5;
this.counter = setting; this.backwardsRotor = backwardsRotor5;
this.name="V"; this.counter = setting;
this.turnOver = 0; //"Above" this.name = "V";
this.type = 5; this.turnOver = 0; //"Above"
break; this.type = 5;
} break;
case 'A': }
{ case 'A':
this.rotor = reflectorA; {
this.rrotor = null; this.rotor = reflectorA;
this.counter = 0; this.backwardsRotor = null;
this.name="A"; this.counter = 0;
this.type = 1; this.name = "A";
break; this.type = 1;
} break;
case 'B': }
{ case 'B':
this.rotor = reflectorB; {
this.rrotor = null; this.rotor = reflectorB;
this.counter = 0; this.backwardsRotor = null;
this.name="B"; this.counter = 0;
this.type = 2; this.name = "B";
break; this.type = 2;
} break;
case 'C': }
{ case 'C':
this.rotor = reflectorC; {
this.rrotor = null; this.rotor = reflectorC;
this.counter = 0; this.backwardsRotor = null;
this.name="C"; this.counter = 0;
this.type = 3; this.name = "C";
break; this.type = 3;
} break;
} }
} }
}
/** /**
* encrypt in forward direction (forward means first half of the cycle through the rotors) * encrypt in forward direction (forward means first half of the cycle through the rotors)
* @param x incoming character *
* @return encrypted character * @param x incoming character
*/ * @return encrypted character
public int encryptForward(int x) */
{ public int encryptForward(int x)
return this.rotor[(26+x+ringsetting)%26]; {
} return this.rotor[(26 + x) % 26];
}
/**encrypt in backward direction (coming from the reversing rotor) /**
* @param x incoming character * encrypt in backward direction (coming from the reversing rotor)
* @return encrypted character *
*/ * @param x incoming character
public int encryptBackward(int x) * @return encrypted character
{ */
if(this.rrotor == null) return this.rotor[(26+x+ringsetting)%26]; public int encryptBackward(int x)
else return this.rrotor[(26+x)%26]; {
} if (this.backwardsRotor == null) return this.rotor[(26 + x) % 26];
else return this.backwardsRotor[(26 + x) % 26];
}
/** /**
* return rotation of the rotor * return rotation of the rotor - the ringsetting
* @return rotation *
*/ * @return rotation
public int getCounter() */
{ public int getCounter()
return this.counter; {
} return this.counter - this.getRingsetting();
}
/** /**
* increment rotation of the rotor by one. * increment rotation of the rotor by one.
*/ */
public void incrementCounter() public void incrementCounter()
{ {
this.counter = (this.counter+1)%26; this.counter = (this.counter + 1) % 26;
} }
/** /**
* Return true, if rotor is at a position, where it turns over the next rotor * Return true, if rotor is at a position, where it turns over the next rotor
*
* @return boolean * @return boolean
*/ */
public boolean isAtTurnoverPosition() public boolean isAtTurnoverPosition()
{ {
return this.getCounter() == this.turnOver; return this.counter == this.turnOver;
} }
/**
* The Double Turn Anomaly (deutsch: Doppelsprung Anomalie) is aa anomaly in the rotor movement caused by the mechanical implementation of the enigma.
* Whenever the rightmost rotor turns the middle rotor AND the middle rotor is only one move from turning the leftmost rotor, the middle rotor turns again with the next character.
* So technically there are only 26*25*26 possible rotor settings for any but firmly 3 rotors.
*
* @return boolean
*/
public boolean doubleTurnAnomaly()
{
return this.counter == this.turnOver - 1;
}
@SuppressWarnings("unused")
/**
* Returns the position of the turnover notch
*
* @return turnOver
*/
public int getTurnOver() public int getTurnOver()
{ {
return this.turnOver; return this.turnOver;
} }
@SuppressWarnings("unused")
/** /**
* Return the name of the rotor * Return the name of the rotor
* @return name * @return name
*/ */
public String getName() public String getName()
{ {
return name; return name;
} }
@SuppressWarnings("unused")
/** /**
* Return ringsettings of the rotor * Return ringsettings of the rotor
* @return ringsetting * @return ringsetting
*/ */
public int getRingsetting() public int getRingsetting()
{ {
return this.ringsetting; return this.ringsetting;
} }
/** /**
* Returns the integer, which was used to create this rotor. * Returns the integer, which was used to create this rotor.
*
* @return the type of the rotor * @return the type of the rotor
*/ */
public int getType() public int getType()

View file

@ -18,43 +18,43 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight="1" android:layout_weight="1"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/hint_ukw"/> android:text="@string/hint_reflector"/>
<TextView <TextView
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight="1" android:layout_weight="1"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/hint_w3"/> android:text="@string/hint_rotor3"/>
<TextView <TextView
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight="1" android:layout_weight="1"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/hint_w2"/> android:text="@string/hint_rotor2"/>
<TextView <TextView
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight="1" android:layout_weight="1"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/hint_w1"/> android:text="@string/hint_rotor1"/>
<TextView <TextView
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight="1" android:layout_weight="1"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/hint_w3pos"/> android:text="@string/hint_rotor3_position"/>
<TextView <TextView
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight="1" android:layout_weight="1"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/hint_w2pos"/> android:text="@string/hint_rotor2_position"/>
<TextView <TextView
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight="1" android:layout_weight="1"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/hint_w1pos"/> android:text="@string/hint_rotor1_position"/>
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
@ -68,49 +68,49 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight=".14" android:layout_weight=".14"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/ukw"> android:id="@+id/reflector">
</Spinner> </Spinner>
<Spinner <Spinner
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight=".14" android:layout_weight=".14"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/w3"> android:id="@+id/rotor3">
</Spinner> </Spinner>
<Spinner <Spinner
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight=".14" android:layout_weight=".14"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/w2"> android:id="@+id/rotor2">
</Spinner> </Spinner>
<Spinner <Spinner
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight=".14" android:layout_weight=".14"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/w1"> android:id="@+id/rotor1">
</Spinner> </Spinner>
<Spinner <Spinner
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight=".14" android:layout_weight=".14"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/w3pos"> android:id="@+id/rotor3position">
</Spinner> </Spinner>
<Spinner <Spinner
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight=".14" android:layout_weight=".14"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/w2pos"> android:id="@+id/rotor2position">
</Spinner> </Spinner>
<Spinner <Spinner
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight=".14" android:layout_weight=".14"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/w1pos"> android:id="@+id/rotor1position">
</Spinner> </Spinner>
</LinearLayout> </LinearLayout>
@ -136,7 +136,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/text_layer" android:layout_below="@+id/text_layer"
android:id="@+id/button_crypt" android:id="@+id/button_crypt"
android:onClick="crypto" android:onClick="doCrypto"
android:text="@string/button_crypt"/> android:text="@string/button_crypt"/>
</LinearLayout> </LinearLayout>
@ -151,7 +151,7 @@
android:layout_weight=".50" android:layout_weight=".50"
android:layout_height="match_parent" android:layout_height="match_parent"
android:id="@+id/input" android:id="@+id/input"
android:hint="@string/hint_enigma_usertype" /> android:hint="@string/hint_enigma_type_here" />
<EditText <EditText
android:layout_width="0dp" android:layout_width="0dp"

View file

@ -18,25 +18,25 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight=".25" android:layout_weight=".25"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/hint_ukw"/> android:text="@string/hint_reflector"/>
<TextView <TextView
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight=".25" android:layout_weight=".25"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/hint_w3"/> android:text="@string/hint_rotor3"/>
<TextView <TextView
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight=".25" android:layout_weight=".25"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/hint_w2"/> android:text="@string/hint_rotor2"/>
<TextView <TextView
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight=".25" android:layout_weight=".25"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/hint_w1"/> android:text="@string/hint_rotor1"/>
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -49,25 +49,25 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight=".25" android:layout_weight=".25"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/ukw"> android:id="@+id/reflector">
</Spinner> </Spinner>
<Spinner <Spinner
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight=".25" android:layout_weight=".25"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/w3"> android:id="@+id/rotor3">
</Spinner> </Spinner>
<Spinner <Spinner
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight=".25" android:layout_weight=".25"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/w2"> android:id="@+id/rotor2">
</Spinner> </Spinner>
<Spinner <Spinner
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight=".25" android:layout_weight=".25"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/w1"> android:id="@+id/rotor1">
</Spinner> </Spinner>
</LinearLayout> </LinearLayout>
@ -86,19 +86,19 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight=".25" android:layout_weight=".25"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/hint_w3pos"/> android:text="@string/hint_rotor3_position"/>
<TextView <TextView
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight=".25" android:layout_weight=".25"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/hint_w2pos"/> android:text="@string/hint_rotor2_position"/>
<TextView <TextView
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight=".25" android:layout_weight=".25"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/hint_w1pos"/> android:text="@string/hint_rotor1_position"/>
<Space <Space
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight=".125" android:layout_weight=".125"
@ -120,19 +120,19 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight=".25" android:layout_weight=".25"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/w3pos"> android:id="@+id/rotor3position">
</Spinner> </Spinner>
<Spinner <Spinner
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight=".25" android:layout_weight=".25"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/w2pos"> android:id="@+id/rotor2position">
</Spinner> </Spinner>
<Spinner <Spinner
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight=".25" android:layout_weight=".25"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/w1pos"> android:id="@+id/rotor1position">
</Spinner> </Spinner>
<Space <Space
android:layout_width="0dp" android:layout_width="0dp"
@ -158,7 +158,7 @@
android:layout_weight=".50" android:layout_weight=".50"
android:layout_height="match_parent" android:layout_height="match_parent"
android:id="@+id/input" android:id="@+id/input"
android:hint="@string/hint_enigma_usertype" /> android:hint="@string/hint_enigma_type_here" />
<EditText <EditText
android:layout_width="0dp" android:layout_width="0dp"
@ -180,7 +180,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/text_layer" android:layout_below="@+id/text_layer"
android:id="@+id/button_crypt" android:id="@+id/button_crypt"
android:onClick="crypto" android:onClick="doCrypto"
android:text="@string/button_crypt"/> android:text="@string/button_crypt"/>
</LinearLayout> </LinearLayout>

View file

@ -0,0 +1,55 @@
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/ringstellung_layout_hint">
<TextView
android:layout_width="0dp"
android:layout_weight="33"
android:text="@string/hint_rotor3"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="0dp"
android:layout_weight="33"
android:text="@string/hint_rotor2"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="0dp"
android:layout_weight="33"
android:text="@string/hint_rotor1"
android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/ringstellung_layout_hint"
android:id="@+id/ringstellung_layout">
<Spinner
android:layout_width="0dp"
android:layout_weight=".33"
android:layout_height="wrap_content"
android:id="@+id/rotor3ring">
</Spinner>
<Spinner
android:layout_width="0dp"
android:layout_weight=".33"
android:layout_height="wrap_content"
android:id="@+id/rotor2ring">
</Spinner>
<Spinner
android:layout_width="0dp"
android:layout_weight=".33"
android:layout_height="wrap_content"
android:id="@+id/rotor1ring">
</Spinner>
</LinearLayout>
</RelativeLayout>

View file

@ -7,7 +7,11 @@
android:orderInCategory="100" android:orderInCategory="100"
android:showAsAction="never" /> android:showAsAction="never" />
<item android:id="@+id/action_reset" <item android:id="@+id/action_reset"
android:orderInCategory="99" android:orderInCategory="98"
android:showAsAction="ifRoom" android:showAsAction="ifRoom"
android:title="@string/action_reset" /> android:title="@string/action_reset" />
<item android:id="@+id/action_choose_ringstellung"
android:title="@string/action_choose_ringsettings"
android:orderInCategory="99"
android:showAsAction="never" />
</menu> </menu>

View file

@ -5,34 +5,42 @@
<string name="action_version">Version</string> <string name="action_version">Version</string>
<string name="action_reset">Zurücksetzen</string> <string name="action_reset">Zurücksetzen</string>
<string name="action_settings">Version</string> <string name="action_settings">Version</string>
<string name="hint_enigma_usertype">Hier Tippen</string> <string name="action_choose_ringsettings">Ringstellung</string>
<string name="message_choose_ringsettings">Wähle die Ringstellungen für die Walzen:</string>
<string name="hint_enigma_type_here">Hier Tippen</string>
<string name="hint_enigma_code">Enigma-Code</string> <string name="hint_enigma_code">Enigma-Code</string>
<string name="hint_enigma_plugboard">Steckerbrett (AZ,BE...)</string> <string name="hint_enigma_plugboard">Steckerbrett (AZ,BE...)</string>
<string name="hint_w1">Walze 1</string> <string name="hint_rotor1">Walze 1</string>
<string name="hint_w2">Walze 2</string> <string name="hint_rotor2">Walze 2</string>
<string name="hint_w3">Walze 3</string> <string name="hint_rotor3">Walze 3</string>
<string name="hint_ukw">Umkehr-\nWalze</string> <string name="hint_reflector">Umkehr-\nWalze</string>
<string name="hint_w1pos">Position\nWalze 1</string> <string name="hint_rotor1_position">Position\nWalze 1</string>
<string name="hint_w2pos">Position\nWalze 2</string> <string name="hint_rotor2_position">Position\nWalze 2</string>
<string name="hint_w3pos">Position\nWalze 3</string> <string name="hint_rotor3_position">Position\nWalze 3</string>
<string name="button_crypt">Ver-/Entschlüsseln</string> <string name="button_crypt">Ver-/Entschlüsseln</string>
<string name="error_parsing_plugs">Fehler: Fehlerhafte Steckerbrettkonfiguration.</string> <string name="error_parsing_plugs">Fehler: Fehlerhafte Steckerbrettkonfiguration.</string>
<string name="error_unable_to_plug_a_b">Kann Stecker nicht setzen: </string> <string name="error_unable_to_plug_a_b">Kann Stecker nicht setzen: </string>
<string name="error_plug_already_in_use">Fehler: Einer oder mehrere dieser Stecker sind bereits in Benutzung: </string> <string name="error_plug_already_in_use">Fehler: Einer oder mehrere dieser Stecker sind bereits in Benutzung: </string>
<string name="title_ringsetting">Ringstellungen</string>
<string name="dialog_positiv">OK</string>
<string name="dialog_negativ">Abbrechen</string>
<string name="dialog_ringsettings_success">Setze Ringe auf</string>
<string name="dialog_ringsettings_abort">Keine Änderungen</string>
<string name="message_reset">Enigma zurückgesetzt</string>
<string-array name="enigma_walzen"> <string-array name="enigma_rotors">
<item>I</item> <item>I</item>
<item>II</item> <item>II</item>
<item>III</item> <item>III</item>
<item>IV</item> <item>IV</item>
<item>V</item> <item>V</item>
</string-array> </string-array>
<string-array name="enigma_ukw"> <string-array name="enigma_reflectors">
<item>A</item> <item>A</item>
<item>B</item> <item>B</item>
<item>C</item> <item>C</item>
</string-array> </string-array>
<string-array name="positions"> <string-array name="rotor_positions">
<item>A</item> <item>A</item>
<item>B</item> <item>B</item>
<item>C</item> <item>C</item>
@ -60,4 +68,33 @@
<item>Y</item> <item>Y</item>
<item>Z</item> <item>Z</item>
</string-array> </string-array>
<string-array name="ring_positions">
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
<item>6</item>
<item>7</item>
<item>8</item>
<item>9</item>
<item>10</item>
<item>11</item>
<item>12</item>
<item>13</item>
<item>14</item>
<item>15</item>
<item>16</item>
<item>17</item>
<item>18</item>
<item>19</item>
<item>20</item>
<item>21</item>
<item>22</item>
<item>23</item>
<item>24</item>
<item>25</item>
<item>26</item>
</string-array>
</resources> </resources>

View file

@ -1,38 +1,46 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="version" translatable="false">0.1-17.02.2015</string> <string name="version" translatable="false">0.1.1-18.02.2015</string>
<string name="app_name">EnigmAndroid</string> <string name="app_name">EnigmAndroid</string>
<string name="action_version">Version</string> <string name="action_version">Version</string>
<string name="action_reset">Reset</string> <string name="action_reset">Reset</string>
<string name="hint_enigma_usertype">Type here</string> <string name="action_choose_ringsettings">Ringsettings</string>
<string name="message_choose_ringsettings">Choose ringsettings for the rotors:</string>
<string name="hint_enigma_type_here">Type here</string>
<string name="hint_enigma_code">EnigmaCode</string> <string name="hint_enigma_code">EnigmaCode</string>
<string name="hint_enigma_plugboard">Plugboard (AZ,BE...)</string> <string name="hint_enigma_plugboard">Plugboard (AZ,BE...)</string>
<string name="hint_w1">R1</string> <string name="hint_rotor1">Rotor 1</string>
<string name="hint_w2">R2</string> <string name="hint_rotor2">Rotor 2</string>
<string name="hint_w3">R3</string> <string name="hint_rotor3">Rotor 3</string>
<string name="hint_ukw">RR</string> <string name="hint_reflector">Reflector</string>
<string name="hint_w1pos">PosR1</string> <string name="hint_rotor1_position">Position Rotor 1</string>
<string name="hint_w2pos">PosR2</string> <string name="hint_rotor2_position">Position Rotor 2</string>
<string name="hint_w3pos">PosR3</string> <string name="hint_rotor3_position">Position Rotor 3</string>
<string name="button_crypt">En-/Decrypt!</string> <string name="button_crypt">En-/Decrypt!</string>
<string name="error_parsing_plugs">Error: Can\'t interpret Plugboard Input.</string> <string name="error_parsing_plugs">Error: Can\'t interpret Plugboard Input.</string>
<string name="error_unable_to_plug_a_b">Unable to plug </string> <string name="error_unable_to_plug_a_b">Unable to plug </string>
<string name="error_plug_already_in_use">Error: One or more of these Plugs are already in use: </string> <string name="error_plug_already_in_use">Error: One or more of these Plugs are already in use: </string>
<string name="title_ringsetting">Ringsettings</string>
<string name="dialog_positiv">OK</string>
<string name="dialog_negativ">Cancel</string>
<string name="dialog_ringsettings_success">Set Ringsettings to</string>
<string name="dialog_ringsettings_abort">No changes</string>
<string name="message_reset">Enigma reset</string>
<string-array name="enigma_walzen"> <string-array name="enigma_rotors">
<item>I</item> <item>I</item>
<item>II</item> <item>II</item>
<item>III</item> <item>III</item>
<item>IV</item> <item>IV</item>
<item>V</item> <item>V</item>
</string-array> </string-array>
<string-array name="enigma_ukw"> <string-array name="enigma_reflectors">
<item>A</item> <item>A</item>
<item>B</item> <item>B</item>
<item>C</item> <item>C</item>
</string-array> </string-array>
<string-array name="positions"> <string-array name="rotor_positions">
<item>A</item> <item>A</item>
<item>B</item> <item>B</item>
<item>C</item> <item>C</item>
@ -60,4 +68,32 @@
<item>Y</item> <item>Y</item>
<item>Z</item> <item>Z</item>
</string-array> </string-array>
<string-array name="ring_positions">
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
<item>6</item>
<item>7</item>
<item>8</item>
<item>9</item>
<item>10</item>
<item>11</item>
<item>12</item>
<item>13</item>
<item>14</item>
<item>15</item>
<item>16</item>
<item>17</item>
<item>18</item>
<item>19</item>
<item>20</item>
<item>21</item>
<item>22</item>
<item>23</item>
<item>24</item>
<item>25</item>
<item>26</item>
</string-array>
</resources> </resources>

Binary file not shown.