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"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.vanitasvitae.enigmandroid"
android:versionCode="00002"
android:versionName="05.02.2015-beta">
android:versionCode="00003"
android:versionName="11.02.2015-beta">
<application
android:allowBackup="true"

View file

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

View file

@ -25,18 +25,19 @@ public class MainActivity extends Activity
private Enigma enigma;
@Override
protected void onCreate(Bundle savedInstanceState) {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.setContentView(R.layout.activity_main);
this.initLayout();
this.reset();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// 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;
}
@ -48,13 +49,13 @@ public class MainActivity extends Activity
int id = item.getItemId();
if (id == R.id.action_version)
{
Toast.makeText(getApplicationContext(), R.string.version,
Toast.makeText(this.getApplicationContext(), R.string.version,
Toast.LENGTH_SHORT).show();
return true;
}
else if(id == R.id.action_reset)
{
reset();
this.reset();
}
return super.onOptionsItemSelected(item);
}
@ -92,7 +93,7 @@ public class MainActivity extends Activity
}
try
{
enigma.konfiguration(conf);
enigma.setConfiguration(conf);
enigma.setPlugboard(pbconf);
}
@ -110,7 +111,7 @@ public class MainActivity extends Activity
m = Enigma.prepare(m);
input.setText(m);
output.setText(enigma.encrypt(m));
updateSpinner(enigma.getKonfiguration());
updateSpinner(enigma.getConfiguration());
}

View file

@ -1,8 +1,8 @@
package de.vanitasvitae.enigmandroid;
/**
* Klasse für das Steckerbrett der Enigma
* @author vanitas
* Class representing the plugboard
* @author vanitasvitae
*
*/
public class Plugboard
@ -12,12 +12,12 @@ public class Plugboard
// A S D F G H J K
// P Y X C V B N M L
//Array für die Steckerverbindungen
//Array containing plugged pairs
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};
/**
* Erzeuge neues Plugboard ohne Steckverbindungen
* Create new plugboard without any plugged pairs. (empty, no scrambling here)
*/
public Plugboard()
{
@ -26,9 +26,9 @@ public class Plugboard
}
/**
* Verschlüssele den gegebenen Buchstaben, den Regeln des Plugboard folgend
* @param x zu verschlüsselndes Zeichen
* @return Verschlüsseltes Zeichen
* 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)
{
@ -36,38 +36,43 @@ public class Plugboard
}
/**
* Setze das Plugboard in den Standardzustand (Keine Stecker)
* 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
* @param p configuration
* @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 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)
{
throw new PlugAlreadyUsedException("Unable to plug "+a +" to " +a);
}
int x = a-65;
int y = b-65;
//Check, if plugs already steckered
//Check, if plugs already plugged
if(pb[x]!=ref[x])
{
throw new PlugAlreadyUsedException("Plug " + a + " used twice!");
@ -76,8 +81,10 @@ public class Plugboard
{
throw new PlugAlreadyUsedException("Plug " + b + " used twice!");
}
else //Steckere um
//If everything is correct
else
{
//set the pair
int c =pb[x];
pb[x] = pb[y];
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[] 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
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[] 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[] 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};
//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[] 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};
//Atributes of the rotor
private Integer[] rotor; //choose one of rotor1-5
private Integer[] rrotor; //choose one of backwardsRotor1-5
private int ringsetting;
private int ringsetting; //TODO: Add functionality to this.
private int counter;
private String name;
private int type;
@ -100,7 +101,7 @@ public class Rotor
}
case 'A':
{
this.rotor = reversingRotorA;
this.rotor = reflectorA;
this.rrotor = null;
this.counter = 0;
this.name="A";
@ -109,7 +110,7 @@ public class Rotor
}
case 'B':
{
this.rotor = reversingRotorB;
this.rotor = reflectorB;
this.rrotor = null;
this.counter = 0;
this.name="B";
@ -118,7 +119,7 @@ public class Rotor
}
case 'C':
{
this.rotor = reversingRotorC;
this.rotor = reflectorC;
this.rrotor = null;
this.counter = 0;
this.name="C";
@ -165,6 +166,15 @@ public class Rotor
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 name
@ -184,8 +194,8 @@ public class Rotor
}
/**
* Returns the integer, which was used to create this rotor. TODO: This is too resource hungry.
* @return
* Returns the integer, which was used to create this rotor.
* @return the type of the rotor
*/
public int getType()
{

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<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="action_version">Version</string>
<string name="action_reset">Reset</string>