Improved documentation and changed fully translated method names to english.

This commit is contained in:
vanitasvitae 2015-02-11 20:56:43 +01:00
parent 9ecfec4fb4
commit efd86933b3
6 changed files with 140 additions and 98 deletions

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.vanitasvitae.enigmandroid" package="de.vanitasvitae.enigmandroid"
android:versionCode="00002" android:versionCode="00003"
android:versionName="05.02.2015-beta"> android:versionName="11.02.2015-beta">
<application <application
android:allowBackup="true" android:allowBackup="true"

View File

@ -10,60 +10,63 @@ public class Enigma
{ {
private Plugboard plugboard; private Plugboard plugboard;
//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
private Rotor ukw; private Rotor reflector;
//Standard configuration (rotors 1-3, reflector A, all three rotors set to position 1)
private static final int[] STANDARD_CONFIGURATION = {1,2,3,1,1,1,1}; private static final int[] STANDARD_CONFIGURATION = {1,2,3,1,1,1,1};
private boolean showSteps;
private boolean verbose = false;
private String output = null;
/** /**
* @param pbconf two-dimensional Array with plugs, that need to be switched * Create new Enigma with given configuration.
* @param conf Configuration of the enigma * If pbconf == null no plugs will be set (no scrambling in the plugboard).
* 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)
*/ */
public Enigma(char[][] pbconf, int[] conf) throws Plugboard.PlugAlreadyUsedException public Enigma(char[][] pbconf, int[] conf) throws Plugboard.PlugAlreadyUsedException
{ {
if(conf!=null) konfiguration(conf); if(conf!=null) setConfiguration(conf);
else konfiguration(Enigma.STANDARD_CONFIGURATION); else setConfiguration(Enigma.STANDARD_CONFIGURATION);
this.setPlugboard(pbconf); this.setPlugboard(pbconf);
} }
/** /**
* Encrypts / Decrypts a given String * Encrypt / Decrypt a given String
* @param w Text to decrypt/encrypt * @param w Text to decrypt/encrypt
* @return * @return encrypted/decrypted string
*/ */
public String encrypt(String w) public String encrypt(String w)
{ {
String k=w; //output string
String c = ""; String c = "";
//for each char x in k //for each char x in k
for(int i=0; i<k.length(); i++) for(int i=0; i<w.length(); i++)
{ {
char x = k.charAt(i); char x = w.charAt(i);
//encrypt char
c = c + this.encryptChar(x); c = c + this.encryptChar(x);
} }
//return en-/decrypted string
return c; return c;
} }
/** /**
* Verschlüssele den übergebenen char k. * Perform crypto on char.
* Zähle danach Konfiguration hoch. * Beforehand rotate rotors..
* @param k zu verschlüsselnder char * @param k input char
* @return verschlüsselter char * @return output char
*/ */
public char encryptChar(char k) public char encryptChar(char k)
{ {
//Move rotors //Rotate rotors
r1.incrementCounter(); r1.incrementCounter();
if(r1.getCounter() == r1.getRingsetting()) { if(r1.isAtTurnoverPosition()) {
r2.incrementCounter(); r2.incrementCounter();
if (r2.getCounter() == r2.getRingsetting()) { if (r2.isAtTurnoverPosition()) {
r3.incrementCounter(); r3.incrementCounter();
} }
} }
@ -81,7 +84,7 @@ public class Enigma
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 = ukw.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;
@ -127,36 +130,45 @@ public class Enigma
/** /**
* 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.
* Dont do things such as 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 * @param p String
* @return Array * @return Array containing plugboard configuration
*/ */
public static char[][] parsePlugs(String p) throws InvalidPlugboardConfigurationFormatException public static char[][] parsePlugs(String p) throws InvalidPlugboardConfigurationFormatException
{ {
//Check, if empty
if(p.length()==0) if(p.length()==0)
{ {
return null; return null;
} }
//Ensure uppercase and split string
String[] in = p.toUpperCase().split(","); String[] in = p.toUpperCase().split(",");
//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)
if(in.length!=(p.length()+1)/3) if(in.length!=(p.length()+1)/3)
{ {
throw new InvalidPlugboardConfigurationFormatException("Fehler beim Parsen der Plugs: Fehlercode 1"); throw new InvalidPlugboardConfigurationFormatException("Error parsing plugs! Maybe you missed a ','?");
} }
else else
{ {
//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
int i=0; int i=0;
for(String x:in) for(String x:in)
{ {
//Check, whether string is not representing a pair
if(x.length()!=2) if(x.length()!=2)
{ {
throw new InvalidPlugboardConfigurationFormatException("Fehler beim Parsen der Plugs: Fehlercode 2"); throw new InvalidPlugboardConfigurationFormatException("Error parsing plugs! Maybe you didn't enter a pair somewhere?");
} }
//If it does
else else
{ {
//add it to the array
plugs[i] = x.toCharArray(); plugs[i] = x.toCharArray();
i++; i++;
} }
@ -165,154 +177,166 @@ public class Enigma
} }
} }
/**
* Set the plugboard to a new created object and give it the configuration
* @param c configuration
* @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)
{ {
for(int i=0; i<c.length; i++) //Set each plug pair
for(char[] x : c)
{ {
plugboard.setPlug(c[i][0], c[i][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 konfiguration(int[] conf) public void setConfiguration(int[] conf)
{ {
if(conf.length!=7) if(conf.length!=7)
{ {
konfiguration(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 ukwN = conf[3]; int ref = conf[3];
int r1stand = 26+conf[4]-1; int r1rot = 26+conf[4]-1;
int r2stand = 26+conf[5]-1; int r2rot = 26+conf[5]-1;
int r3stand = 26+conf[6]-1; int r3rot = 26+conf[6]-1;
//Lege erste Walze fest //Set first rotor
switch(ro1) switch(ro1)
{ {
case 1: case 1:
{ {
r1 = new Rotor('1',(r1stand)%26,0); r1 = new Rotor('1',(r1rot)%26,0);
break; break;
} }
case 2: case 2:
{ {
r1 = new Rotor('2',(r1stand)%26,0); r1 = new Rotor('2',(r1rot)%26,0);
break; break;
} }
case 3: case 3:
{ {
r1 = new Rotor('3',(r1stand)%26,0); r1 = new Rotor('3',(r1rot)%26,0);
break; break;
} }
case 4: case 4:
{ {
r1 = new Rotor('4',(r1stand)%26,0); r1 = new Rotor('4',(r1rot)%26,0);
break; break;
} }
case 5: case 5:
{ {
r1 = new Rotor('5',(r1stand)%26,0); r1 = new Rotor('5',(r1rot)%26,0);
break; break;
} }
} }
//Lege zweite Walze fest //Set second rotor
switch(ro2) switch(ro2)
{ {
case 1: case 1:
{ {
r2 = new Rotor('1',(r2stand)%26,0); r2 = new Rotor('1',(r2rot)%26,0);
break; break;
} }
case 2: case 2:
{ {
r2 = new Rotor('2',(r2stand)%26,0); r2 = new Rotor('2',(r2rot)%26,0);
break; break;
} }
case 3: case 3:
{ {
r2 = new Rotor('3',(r2stand)%26,0); r2 = new Rotor('3',(r2rot)%26,0);
break; break;
} }
case 4: case 4:
{ {
r2 = new Rotor('4',(r2stand)%26,0); r2 = new Rotor('4',(r2rot)%26,0);
break; break;
} }
case 5: case 5:
{ {
r2 = new Rotor('5',(r2stand)%26,0); r2 = new Rotor('5',(r2rot)%26,0);
break; break;
} }
} }
//Lege dritte Walze fest //Set third rotor
switch(ro3) switch(ro3)
{ {
case 1: case 1:
{ {
r3 = new Rotor('1',(r3stand)%26,0); r3 = new Rotor('1',(r3rot)%26,0);
break; break;
} }
case 2: case 2:
{ {
r3 = new Rotor('2',(r3stand)%26,0); r3 = new Rotor('2',(r3rot)%26,0);
break; break;
} }
case 3: case 3:
{ {
r3 = new Rotor('3',(r3stand)%26,0); r3 = new Rotor('3',(r3rot)%26,0);
break; break;
} }
case 4: case 4:
{ {
r3 = new Rotor('4',(r3stand)%26,0); r3 = new Rotor('4',(r3rot)%26,0);
break; break;
} }
case 5: case 5:
{ {
r3 = new Rotor('5',(r3stand)%26,0); r3 = new Rotor('5',(r3rot)%26,0);
break; break;
} }
} }
//Lege Umkehrwalze fest //Set reflector
switch(ukwN) switch(ref)
{ {
case 1: case 1:
{ {
ukw = new Rotor('A',0,0); reflector = new Rotor('A',0,0);
break; break;
} }
case 2: case 2:
{ {
ukw = new Rotor('B',0,0); reflector = new Rotor('B',0,0);
break; break;
} }
case 3: case 3:
{ {
ukw = new Rotor('C',0,0); reflector = new Rotor('C',0,0);
break; break;
} }
} }
} }
} }
public int[] getKonfiguration()
/**
* Return the configuration, the enigma machine is in right NOW
* @return array containing configuration
*/
public int[] getConfiguration()
{ {
int[] c = new int[7]; int[] c = new int[7];
{ {
c[0] = r1.getType(); c[0] = r1.getType();
c[1] = r2.getType(); c[1] = r2.getType();
c[2] = r3.getType(); c[2] = r3.getType();
c[3] = ukw.getType(); c[3] = reflector.getType();
c[4] = r1.getCounter(); c[4] = r1.getCounter();
c[5] = r2.getCounter(); c[5] = r2.getCounter();
c[6] = r3.getCounter(); c[6] = r3.getCounter();

View File

@ -25,18 +25,19 @@ public class MainActivity extends Activity
private Enigma enigma; private Enigma enigma;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
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. // Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu); this.getMenuInflater().inflate(R.menu.main, menu);
return true; return true;
} }
@ -48,13 +49,13 @@ public class MainActivity extends Activity
int id = item.getItemId(); int id = item.getItemId();
if (id == R.id.action_version) if (id == R.id.action_version)
{ {
Toast.makeText(getApplicationContext(), R.string.version, Toast.makeText(this.getApplicationContext(), R.string.version,
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)
{ {
reset(); this.reset();
} }
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
@ -92,7 +93,7 @@ public class MainActivity extends Activity
} }
try try
{ {
enigma.konfiguration(conf); enigma.setConfiguration(conf);
enigma.setPlugboard(pbconf); enigma.setPlugboard(pbconf);
} }
@ -110,7 +111,7 @@ public class MainActivity extends Activity
m = Enigma.prepare(m); m = Enigma.prepare(m);
input.setText(m); input.setText(m);
output.setText(enigma.encrypt(m)); output.setText(enigma.encrypt(m));
updateSpinner(enigma.getKonfiguration()); updateSpinner(enigma.getConfiguration());
} }

View File

@ -1,8 +1,8 @@
package de.vanitasvitae.enigmandroid; package de.vanitasvitae.enigmandroid;
/** /**
* Klasse für das Steckerbrett der Enigma * Class representing the plugboard
* @author vanitas * @author vanitasvitae
* *
*/ */
public class Plugboard public class Plugboard
@ -12,12 +12,12 @@ public class Plugboard
// 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 für die Steckerverbindungen //Array containing plugged pairs
int[] pb; int[] pb;
//Vergleichsarray (Keine Stecker) //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};
/** /**
* Erzeuge neues Plugboard ohne Steckverbindungen * Create new plugboard without any plugged pairs. (empty, no scrambling here)
*/ */
public Plugboard() public Plugboard()
{ {
@ -26,9 +26,9 @@ public class Plugboard
} }
/** /**
* Verschlüssele den gegebenen Buchstaben, den Regeln des Plugboard folgend * En-/decrypt a char following the connections on the plugboard
* @param x zu verschlüsselndes Zeichen * @param x char to perform crypto on
* @return Verschlüsseltes Zeichen * @return en-/decrypted char
*/ */
public int encrypt(int x) public int encrypt(int x)
{ {
@ -36,38 +36,43 @@ public class Plugboard
} }
/** /**
* Setze das Plugboard in den Standardzustand (Keine Stecker) * Reset the plugboard (no plugged pairs)
*/ */
public void resetPlugboard() 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}; 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
* @param p configuration
* @throws PlugAlreadyUsedException
*/
public void setPlugs(char[][] p) throws PlugAlreadyUsedException public void setPlugs(char[][] p) throws PlugAlreadyUsedException
{ {
for(int i=0; i<p.length; i++) for(char[] x : p)
{ {
if(p[i]!=null) if(x!=null)
{ {
this.setPlug(p[i][0], p[i][1]); this.setPlugPair(x[0], x[1]);
} }
} }
} }
/** /**
* Steckere Buchstaben a und b auf dem Plugboard * Set a pair of plugs on the plugboard
* @param a first Plug * @param a first Plug
* @param b second Plug * @param b second Plug
*/ */
public void setPlug(char a, char b) throws PlugAlreadyUsedException public void setPlugPair(char a, char b) throws PlugAlreadyUsedException
{ {
//Verhindere, dass Buchstabe mit sich selbst gesteckert wird //prevent to plug a plug to itself
if(a==b) 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 steckered //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!");
@ -76,8 +81,10 @@ public class Plugboard
{ {
throw new PlugAlreadyUsedException("Plug " + b + " used twice!"); throw new PlugAlreadyUsedException("Plug " + b + " used twice!");
} }
else //Steckere um //If everything is correct
else
{ {
//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;

View File

@ -31,14 +31,15 @@ public class Rotor
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 reversing 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[] reversingRotorA = {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[] reversingRotorB = {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[] reversingRotorC = {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
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[] rrotor; //choose one of backwardsRotor1-5
private int ringsetting; private int ringsetting; //TODO: Add functionality to this.
private int counter; private int counter;
private String name; private String name;
private int type; private int type;
@ -100,7 +101,7 @@ public class Rotor
} }
case 'A': case 'A':
{ {
this.rotor = reversingRotorA; this.rotor = reflectorA;
this.rrotor = null; this.rrotor = null;
this.counter = 0; this.counter = 0;
this.name="A"; this.name="A";
@ -109,7 +110,7 @@ public class Rotor
} }
case 'B': case 'B':
{ {
this.rotor = reversingRotorB; this.rotor = reflectorB;
this.rrotor = null; this.rrotor = null;
this.counter = 0; this.counter = 0;
this.name="B"; this.name="B";
@ -118,7 +119,7 @@ public class Rotor
} }
case 'C': case 'C':
{ {
this.rotor = reversingRotorC; this.rotor = reflectorC;
this.rrotor = null; this.rrotor = null;
this.counter = 0; this.counter = 0;
this.name="C"; this.name="C";
@ -165,6 +166,15 @@ public class Rotor
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 boolean
*/
public boolean isAtTurnoverPosition()
{
return this.getCounter() == this.getRingsetting(); //Todo: this ist still wrong.
}
/** /**
* Return the name of the rotor * Return the name of the rotor
* @return name * @return name
@ -184,8 +194,8 @@ public class Rotor
} }
/** /**
* Returns the integer, which was used to create this rotor. TODO: This is too resource hungry. * Returns the integer, which was used to create this rotor.
* @return * @return the type of the rotor
*/ */
public int getType() public int getType()
{ {

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="version" translatable="false">0.1-05.02.2015</string> <string name="version" translatable="false">0.1-11.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>