mirror of
https://github.com/vanitasvitae/EnigmAndroid.git
synced 2024-11-24 21:32:06 +01:00
Update 0.1.5 Added Enigma Models I,M3,M4, fixed ring settings
This commit is contained in:
parent
2e405429cf
commit
9258c72daa
31 changed files with 2388 additions and 687 deletions
|
@ -1,10 +1,12 @@
|
|||
CHANGELOG ENIGMANDROID
|
||||
|
||||
v0.1.5-not.yet.released<
|
||||
*added missing licenses to class files
|
||||
*Added proper documentation
|
||||
*Extended input interpretation (number spelling in different languages, any unknown special
|
||||
character now becomes 'X'
|
||||
*Added french number spelling
|
||||
*Added Enigma Models M3, M4
|
||||
*Added option to select different enigma models into options menu
|
||||
*Added developer class for simple rotor creation (not a feature in the app)
|
||||
*Fixed broken ring settings
|
||||
*Fixed false reset of ring settings when switching from/to landscape mode
|
||||
|
||||
|
||||
v0.1.4-15.08.2015<
|
||||
|
@ -12,6 +14,10 @@ v0.1.4-15.08.2015<
|
|||
*Fixed some layout issues
|
||||
*Fixed anomaly for step by step inputs
|
||||
*Added send/receive text functionality
|
||||
*added missing licenses to class files
|
||||
*Added proper documentation
|
||||
*Extended input interpretation (number spelling in different languages, any unknown special
|
||||
character now becomes 'X'
|
||||
|
||||
v0.1.3-14.03.2015<
|
||||
*Added About Dialog with ChangeLog-Button
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/22.2.1/jars" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/23.0.0/jars" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
|
||||
|
@ -87,9 +87,9 @@
|
|||
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Android API 22 Platform (1)" jdkType="Android SDK" />
|
||||
<orderEntry type="jdk" jdkName="Android API 23 Platform" jdkType="Android SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" exported="" name="support-v4-22.2.1" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-annotations-22.2.1" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-v4-23.0.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-annotations-23.0.0" level="project" />
|
||||
</component>
|
||||
</module>
|
|
@ -1,15 +1,15 @@
|
|||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 22
|
||||
compileSdkVersion 23
|
||||
buildToolsVersion "22.0.1"
|
||||
|
||||
defaultConfig {
|
||||
applicationId "de.vanitasvitae.enigmandroid"
|
||||
minSdkVersion 15
|
||||
targetSdkVersion 22
|
||||
versionCode 10
|
||||
versionName "0.1.4-15.08.2015-beta"
|
||||
targetSdkVersion 23
|
||||
versionCode 11
|
||||
versionName "0.1.5-27.08.2015-beta"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
|
@ -19,5 +19,5 @@ android {
|
|||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
compile 'com.android.support:support-v4:22.2.1'
|
||||
compile 'com.android.support:support-v4:23.0.0'
|
||||
}
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
package de.vanitasvitae.enigmandroid;
|
||||
|
||||
import android.app.Application;
|
||||
import android.test.ApplicationTestCase;
|
||||
|
||||
/**
|
||||
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
|
||||
*/
|
||||
public class ApplicationTest extends ApplicationTestCase<Application> {
|
||||
public ApplicationTest() {
|
||||
super(Application.class);
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@
|
|||
android:theme="@style/AppTheme" >
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:label="@string/app_name" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
|
|
@ -1,242 +0,0 @@
|
|||
package de.vanitasvitae.enigmandroid;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.rotors.Reflector;
|
||||
import de.vanitasvitae.enigmandroid.rotors.Rotor;
|
||||
|
||||
/**
|
||||
* Main component of the Enigma machine
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* @author vanitasvitae
|
||||
*/
|
||||
public class Enigma
|
||||
{
|
||||
private Plugboard plugboard;
|
||||
|
||||
//Slots for the rotors
|
||||
private Rotor r1;
|
||||
private Rotor r2;
|
||||
private Rotor r3;
|
||||
|
||||
//Slot for the reflector
|
||||
private Reflector reflector;
|
||||
|
||||
private boolean doAnomaly = false; //Has the time come to handle an anomaly?
|
||||
|
||||
private boolean prefAnomaly; //Do you WANT to simulate the anomaly?
|
||||
private InputPreparator inputPreparator;
|
||||
|
||||
/**
|
||||
* Create new Enigma with standard configuration.
|
||||
* Empty Plugboard, reflector B, rotors I,II,III, Positions 0,0,0
|
||||
*/
|
||||
public Enigma()
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
|
||||
private void initialize()
|
||||
{
|
||||
this.r1 = Rotor.createRotorI(0, 0);
|
||||
this.r2 = Rotor.createRotorII(0, 0);
|
||||
this.r3 = Rotor.createRotorIII(0, 0);
|
||||
this.reflector = Reflector.createReflectorB();
|
||||
plugboard = new Plugboard();
|
||||
prefAnomaly = true; //TODO: Is this necessary?
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt / Decrypt a given String w.
|
||||
* w must be prepared using prepare(w) beforehand.
|
||||
* Doing so changes the state of the rotors but not the state of the plugboard and the
|
||||
* ringSettings
|
||||
*
|
||||
* @param w Text to decrypt/encrypt
|
||||
* @return encrypted/decrypted string
|
||||
*/
|
||||
public String encrypt(String w)
|
||||
{
|
||||
//output string
|
||||
String output = "";
|
||||
//for each char x in k
|
||||
for (char x : w.toCharArray())
|
||||
{
|
||||
output = output + this.encryptChar(x);
|
||||
}
|
||||
//return en-/decrypted string
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Substitute char k by sending the signal through the enigma.
|
||||
* This rotates the first rotor and eventually also the second/third beforehand.
|
||||
* Also this method handles the anomaly in case it should happen
|
||||
*
|
||||
* @param k input char
|
||||
* @return substituted output char
|
||||
*/
|
||||
public char encryptChar(char k)
|
||||
{
|
||||
//Rotate rotors
|
||||
r1.rotate();
|
||||
//Eventually turn next rotor (usual turnOver or anomaly)
|
||||
if (r1.isAtTurnoverPosition() || (this.doAnomaly && prefAnomaly))
|
||||
{
|
||||
r2.rotate();
|
||||
//Set doAnomaly for next call of encryptChar
|
||||
this.doAnomaly = r2.doubleTurnAnomaly();
|
||||
//Eventually rotate next rotor
|
||||
if (r2.isAtTurnoverPosition())
|
||||
{
|
||||
r3.rotate();
|
||||
}
|
||||
}
|
||||
int x = ((int) k)-65; //Cast to int and remove Unicode Offset (A=65 in Unicode.)
|
||||
|
||||
//Encryption
|
||||
//forward direction
|
||||
x = plugboard.encrypt(x);
|
||||
x = normalize(x + r1.getRotation());
|
||||
x = r1.encryptForward(x);
|
||||
x = normalize(x + r2.getRotation() - r1.getRotation());
|
||||
x = r2.encryptForward(x);
|
||||
x = normalize(x + r3.getRotation() - r2.getRotation());
|
||||
x = r3.encryptForward(x);
|
||||
x = normalize(x - r3.getRotation());
|
||||
//backward direction
|
||||
x = reflector.encrypt(x);
|
||||
x = normalize(x + r3.getRotation());
|
||||
x = r3.encryptBackward(x);
|
||||
x = normalize(x - r3.getRotation() + r2.getRotation());
|
||||
x = r2.encryptBackward(x);
|
||||
x = normalize(x - r2.getRotation() + r1.getRotation());
|
||||
x = r1.encryptBackward(x);
|
||||
x = normalize(x - r1.getRotation());
|
||||
x = plugboard.encrypt(x);
|
||||
|
||||
return (char) (x + 65); //Add Offset again and cast back to char
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize the input.
|
||||
* Normalizing means keeping the input via modulo in the range from 0 to n-1, where n is equal
|
||||
* to the size of the rotors (in this case fixed to 26, TODO?).
|
||||
* This is necessary since java allows negative modulo values,
|
||||
* which can break this implementation
|
||||
* @param input input signal
|
||||
* @return "normalized" input signal
|
||||
*/
|
||||
public int normalize(int input)
|
||||
{
|
||||
return (26+input)%26;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set config of the enigma
|
||||
*
|
||||
* @param conf configuration
|
||||
*/
|
||||
public void setConfiguration(int[] conf)
|
||||
{
|
||||
if (conf == null || conf.length != 10)
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
else
|
||||
{
|
||||
int ro1 = conf[0];
|
||||
int ro2 = conf[1];
|
||||
int ro3 = conf[2];
|
||||
int ref = conf[3];
|
||||
int ro1rot = normalize(conf[4] - 1);
|
||||
int ro2rot = normalize(conf[5] - 1);
|
||||
int ro3rot = normalize(conf[6] - 1);
|
||||
int ro1Ring = conf[7];
|
||||
int ro2Ring = conf[8];
|
||||
int ro3Ring = conf[9];
|
||||
|
||||
//Set rotors
|
||||
r1 = Rotor.createRotor(ro1, ro1Ring, ro1rot);
|
||||
r2 = Rotor.createRotor(ro2, ro2Ring, ro2rot);
|
||||
r3 = Rotor.createRotor(ro3, ro3Ring, ro3rot);
|
||||
|
||||
//Set reflector
|
||||
reflector = Reflector.createReflector(ref);
|
||||
|
||||
//catch double turn anomaly on step by step basis
|
||||
this.doAnomaly = r2.doubleTurnAnomaly();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the plugboard
|
||||
* @param p Plugboard
|
||||
*/
|
||||
public void setPlugboard(Plugboard p)
|
||||
{
|
||||
this.plugboard = p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the configuration, the enigma machine is in right NOW
|
||||
*
|
||||
* @return array containing configuration
|
||||
*/
|
||||
public int[] getConfiguration()
|
||||
{
|
||||
int[] configuration = new int[10];
|
||||
{
|
||||
configuration[0] = r1.getType();
|
||||
configuration[1] = r2.getType();
|
||||
configuration[2] = r3.getType();
|
||||
configuration[3] = reflector.getType();
|
||||
configuration[4] = r1.getRotation();
|
||||
configuration[5] = r2.getRotation();
|
||||
configuration[6] = r3.getRotation();
|
||||
configuration[7] = r1.getRingSetting();
|
||||
configuration[8] = r2.getRingSetting();
|
||||
configuration[9] = r3.getRingSetting();
|
||||
}
|
||||
return configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the inputPreparator
|
||||
* @param preparator concrete InputPreparator
|
||||
*/
|
||||
public void setInputPreparator(InputPreparator preparator)
|
||||
{
|
||||
this.inputPreparator = preparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the inputPreparator
|
||||
* @return inputPreparator
|
||||
*/
|
||||
public InputPreparator getInputPreparator()
|
||||
{
|
||||
return this.inputPreparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* set prefAnomaly variable
|
||||
* @param b boolean
|
||||
*/
|
||||
public void setPrefAnomaly(boolean b)
|
||||
{
|
||||
this.prefAnomaly = b;
|
||||
}
|
||||
}
|
|
@ -5,16 +5,19 @@ import android.app.AlertDialog;
|
|||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.view.View;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.enigma.Plugboard;
|
||||
import de.vanitasvitae.enigmandroid.enigma.inputPreparer.InputPreparer;
|
||||
import de.vanitasvitae.enigmandroid.layout.LayoutContainer;
|
||||
|
||||
/**
|
||||
* Main Android Activity of the app
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
|
@ -36,41 +39,27 @@ import android.widget.Toast;
|
|||
*/
|
||||
public class MainActivity extends Activity
|
||||
{
|
||||
private Spinner rotor1View;
|
||||
private Spinner rotor2View;
|
||||
private Spinner rotor3View;
|
||||
private Spinner reflectorView;
|
||||
private Spinner rotor1PositionView;
|
||||
private Spinner rotor2PositionView;
|
||||
private Spinner rotor3PositionView;
|
||||
|
||||
private EditText plugboardView;
|
||||
private EditText inputView;
|
||||
private EditText outputView;
|
||||
|
||||
private static final int RESULT_SETTINGS = 1;
|
||||
private static final String URI_CHANGELOG = "https://github.com/vanitasvitae/EnigmAndroid/blob/master/CHANGELOG.txt";
|
||||
private static final String URI_CHANGELOG =
|
||||
"https://github.com/vanitasvitae/EnigmAndroid/blob/master/CHANGELOG.txt";
|
||||
|
||||
private Enigma enigma;
|
||||
//memory for the ringSettings
|
||||
private int[] ringSettings = {0,0,0};
|
||||
private boolean prefAnomaly;
|
||||
private String prefNumericLanguage;
|
||||
LayoutContainer layoutContainer;
|
||||
protected String prefMachineType;
|
||||
protected boolean prefAnomaly;
|
||||
protected String prefNumericLanguage;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
this.setContentView(R.layout.activity_main);
|
||||
this.initLayout();
|
||||
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
this.prefAnomaly = sharedPreferences.getBoolean("prefAnomaly", true);
|
||||
this.prefNumericLanguage = sharedPreferences.getString("prefNumericLanguage",getResources().
|
||||
getStringArray(R.array.pref_alias_numeric_spelling_language)[0]);
|
||||
this.resetLayout();
|
||||
this.prefMachineType = sharedPreferences.getString("prefMachineType", getResources().
|
||||
getStringArray(R.array.pref_list_machine_type)[0]);
|
||||
ActivitySingleton singleton = ActivitySingleton.getInstance();
|
||||
singleton.setActivity(this);
|
||||
|
||||
updateContentView();
|
||||
layoutContainer = LayoutContainer.createLayoutContainer(prefMachineType);
|
||||
updatePreferenceValues();
|
||||
//Handle shared text
|
||||
Intent intent = getIntent();
|
||||
String action = intent.getAction();
|
||||
|
@ -82,12 +71,102 @@ public class MainActivity extends Activity
|
|||
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
|
||||
if (sharedText != null)
|
||||
{
|
||||
inputView.setText(sharedText);
|
||||
layoutContainer.getInputView().setText(sharedText);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
}
|
||||
|
||||
private void updateContentView()
|
||||
{
|
||||
switch (prefMachineType)
|
||||
{
|
||||
case "M4":
|
||||
this.setContentView(R.layout.activity_main_m4);
|
||||
break;
|
||||
case "M3":
|
||||
this.setContentView(R.layout.activity_main_i_m3);
|
||||
break;
|
||||
default:
|
||||
this.setContentView(R.layout.activity_main_i_m3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void updatePreferenceValues()
|
||||
{
|
||||
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
this.setPrefMachineType(sharedPreferences.getString("prefMachineType", getResources().
|
||||
getStringArray(R.array.pref_list_machine_type)[0]));
|
||||
this.setPrefAnomaly(sharedPreferences.getBoolean("prefAnomaly", true));
|
||||
this.setPrefNumericLanguage(sharedPreferences.getString("prefNumericLanguage", getResources().
|
||||
getStringArray(R.array.pref_alias_numeric_spelling_language)[0]));
|
||||
}
|
||||
|
||||
public void setPrefMachineType(String type)
|
||||
{
|
||||
if(prefMachineType == null || !prefMachineType.equals(type))
|
||||
{
|
||||
prefMachineType = type;
|
||||
String savedInput = "";
|
||||
if(layoutContainer != null)
|
||||
{
|
||||
savedInput = layoutContainer.getInputView().getText().toString();
|
||||
}
|
||||
updateContentView();
|
||||
layoutContainer = LayoutContainer.createLayoutContainer(prefMachineType);
|
||||
layoutContainer.getInputView().setText(savedInput);
|
||||
}
|
||||
}
|
||||
|
||||
public String getPrefMachineType()
|
||||
{
|
||||
if(prefMachineType != null) return prefMachineType;
|
||||
else
|
||||
{
|
||||
updatePreferenceValues();
|
||||
return prefMachineType;
|
||||
}
|
||||
}
|
||||
|
||||
public void setPrefAnomaly(boolean anomaly)
|
||||
{
|
||||
if(prefAnomaly !=anomaly)
|
||||
{
|
||||
prefAnomaly = anomaly;
|
||||
layoutContainer.getEnigma().setPrefAnomaly(anomaly);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getPrefAnomaly()
|
||||
{
|
||||
return prefAnomaly;
|
||||
}
|
||||
|
||||
public void setPrefNumericLanguage(String lang)
|
||||
{
|
||||
if(prefNumericLanguage == null || !prefNumericLanguage.equals(lang))
|
||||
{
|
||||
prefNumericLanguage = lang;
|
||||
layoutContainer.getEnigma().setInputPreparer(InputPreparer.createInputPreparer(lang));
|
||||
}
|
||||
}
|
||||
|
||||
public String getPrefNumericLanguage()
|
||||
{
|
||||
if(prefNumericLanguage != null) return prefNumericLanguage;
|
||||
else
|
||||
{
|
||||
updatePreferenceValues();
|
||||
return prefNumericLanguage;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu)
|
||||
{
|
||||
|
@ -104,14 +183,14 @@ public class MainActivity extends Activity
|
|||
int id = item.getItemId();
|
||||
if (id == R.id.action_reset)
|
||||
{
|
||||
this.resetLayout();
|
||||
layoutContainer.reset();
|
||||
Toast.makeText(getApplicationContext(), R.string.message_reset,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
}
|
||||
else if (id == R.id.action_choose_ringstellung)
|
||||
{
|
||||
showRingSettingsDialog();
|
||||
layoutContainer.showRingSettingsDialog();
|
||||
return true;
|
||||
}
|
||||
else if (id == R.id.action_settings)
|
||||
|
@ -126,7 +205,7 @@ public class MainActivity extends Activity
|
|||
}
|
||||
else if (id == R.id.action_send)
|
||||
{
|
||||
if(outputView.getText().length() == 0)
|
||||
if(layoutContainer.getOutputView().getText().length() == 0)
|
||||
{
|
||||
Toast.makeText(this, R.string.error_no_text_to_send, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
@ -134,7 +213,7 @@ public class MainActivity extends Activity
|
|||
{
|
||||
Intent sendIntent = new Intent();
|
||||
sendIntent.setAction(Intent.ACTION_SEND);
|
||||
sendIntent.putExtra(Intent.EXTRA_TEXT, outputView.getText().toString());
|
||||
sendIntent.putExtra(Intent.EXTRA_TEXT, layoutContainer.getOutputView().getText().toString());
|
||||
sendIntent.setType("text/plain");
|
||||
startActivity(Intent.createChooser(sendIntent, getResources().getText(R.string.send_to)));
|
||||
}
|
||||
|
@ -142,36 +221,6 @@ public class MainActivity extends Activity
|
|||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the enigma to the chosen rotors and plugboard
|
||||
*
|
||||
* @param v View
|
||||
*/
|
||||
public void updateEnigma(View v)
|
||||
{
|
||||
int[] conf = new int[10];
|
||||
conf[0] = rotor1View.getSelectedItemPosition() + 1;
|
||||
conf[1] = rotor2View.getSelectedItemPosition() + 1;
|
||||
conf[2] = rotor3View.getSelectedItemPosition() + 1;
|
||||
conf[3] = reflectorView.getSelectedItemPosition() + 1;
|
||||
conf[4] = rotor1PositionView.getSelectedItemPosition() + 1;
|
||||
conf[5] = rotor2PositionView.getSelectedItemPosition() + 1;
|
||||
conf[6] = rotor3PositionView.getSelectedItemPosition() + 1;
|
||||
conf[7] = ringSettings[0];
|
||||
conf[8] = ringSettings[1];
|
||||
conf[9] = ringSettings[2];
|
||||
|
||||
enigma = new Enigma();
|
||||
|
||||
int[][] plugboardConfiguration;
|
||||
plugboardView.setText(plugboardView.getText().toString().toUpperCase());
|
||||
plugboardConfiguration = Plugboard.parseConfigurationString(plugboardView.getText().toString());
|
||||
enigma.setConfiguration(conf);
|
||||
enigma.setPlugboard(new Plugboard(plugboardConfiguration));
|
||||
enigma.setPrefAnomaly(prefAnomaly);
|
||||
enigma.setInputPreparator(InputPreparator.createInputPreparator(prefNumericLanguage));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -180,174 +229,21 @@ public class MainActivity extends Activity
|
|||
*/
|
||||
public void doCrypto(View v)
|
||||
{
|
||||
if(inputView.getText().length()!=0) {
|
||||
updateEnigma(null);
|
||||
String m = inputView.getText().toString();
|
||||
m = enigma.getInputPreparator().prepareString(m);
|
||||
inputView.setText(m);
|
||||
outputView.setText(enigma.encrypt(m));
|
||||
updateSpinner(enigma.getConfiguration());
|
||||
if(layoutContainer.getInputView().getText().length()!=0) {
|
||||
layoutContainer.getEnigma().setConfiguration(layoutContainer.createConfiguration());
|
||||
layoutContainer.getEnigma().setPlugboard(new Plugboard(layoutContainer.createPlugboardConfiguration()));
|
||||
String m = layoutContainer.getInputView().getText().toString();
|
||||
m = layoutContainer.getEnigma().getInputPreparer().prepareString(m);
|
||||
layoutContainer.getInputView().setText(m);
|
||||
layoutContainer.getOutputView().setText(layoutContainer.getEnigma().encrypt(m));
|
||||
layoutContainer.updateLayout();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reset all the spinners and textboxes and the ringsettings memory
|
||||
*/
|
||||
private void resetLayout()
|
||||
{
|
||||
rotor1View.setSelection(0);
|
||||
rotor2View.setSelection(1);
|
||||
rotor3View.setSelection(2);
|
||||
reflectorView.setSelection(1);
|
||||
rotor1PositionView.setSelection(0);
|
||||
rotor2PositionView.setSelection(0);
|
||||
rotor3PositionView.setSelection(0);
|
||||
ringSettings = new int[]{0,0,0};
|
||||
plugboardView.setText("");
|
||||
inputView.setText("");
|
||||
outputView.setText("");
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the Layout
|
||||
* Show a Dialog containing information about the app, license, usage, author and a link
|
||||
* to the changelog
|
||||
*/
|
||||
private void initLayout()
|
||||
{
|
||||
Character[] charArray = new Character[26];
|
||||
for(int i=0; i<26; i++) {charArray[i] = (char) (65+i);}
|
||||
|
||||
rotor1View = (Spinner) findViewById(R.id.rotor1);
|
||||
ArrayAdapter<CharSequence> rotor1Adapter = ArrayAdapter.createFromResource(this,
|
||||
R.array.enigma_rotors, android.R.layout.simple_spinner_item);
|
||||
rotor1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor1View.setAdapter(rotor1Adapter);
|
||||
|
||||
|
||||
rotor2View = (Spinner) findViewById(R.id.rotor2);
|
||||
ArrayAdapter<CharSequence> rotor2Adapter = ArrayAdapter.createFromResource(this,
|
||||
R.array.enigma_rotors, android.R.layout.simple_spinner_item);
|
||||
rotor2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor2View.setAdapter(rotor2Adapter);
|
||||
|
||||
rotor3View = (Spinner) findViewById(R.id.rotor3);
|
||||
ArrayAdapter<CharSequence> rotor3Adapter = ArrayAdapter.createFromResource(this,
|
||||
R.array.enigma_rotors, android.R.layout.simple_spinner_item);
|
||||
rotor3Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor3View.setAdapter(rotor3Adapter);
|
||||
|
||||
reflectorView = (Spinner) findViewById(R.id.reflector);
|
||||
ArrayAdapter<CharSequence> relfectorAdapter = ArrayAdapter.createFromResource(this,
|
||||
R.array.enigma_reflectors, android.R.layout.simple_spinner_item);
|
||||
relfectorAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
reflectorView.setAdapter(relfectorAdapter);
|
||||
|
||||
rotor1PositionView = (Spinner) findViewById(R.id.rotor1position);
|
||||
ArrayAdapter<Character> rotor1PositionAdapter = new ArrayAdapter<>(this.getApplicationContext(),
|
||||
android.R.layout.simple_spinner_item,charArray);
|
||||
rotor1PositionAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor1PositionView.setAdapter(rotor1PositionAdapter);
|
||||
|
||||
rotor2PositionView = (Spinner) findViewById(R.id.rotor2position);
|
||||
ArrayAdapter<Character> rotor2PositionAdapter = new ArrayAdapter<>(this.getApplicationContext(),
|
||||
android.R.layout.simple_spinner_item,charArray);
|
||||
rotor2PositionAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor2PositionView.setAdapter(rotor2PositionAdapter);
|
||||
|
||||
rotor3PositionView = (Spinner) findViewById(R.id.rotor3position);
|
||||
ArrayAdapter<Character> rotor3PositionAdapter = new ArrayAdapter<>(this.getApplicationContext(),
|
||||
android.R.layout.simple_spinner_item,charArray);
|
||||
rotor3PositionAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor3PositionView.setAdapter(rotor3PositionAdapter);
|
||||
|
||||
plugboardView = (EditText) findViewById(R.id.plugboard);
|
||||
plugboardView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
||||
@Override
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
if (!hasFocus) {
|
||||
plugboardView.setText(plugboardView.getText().toString().toUpperCase());
|
||||
}
|
||||
}
|
||||
});
|
||||
inputView = (EditText) findViewById(R.id.input);
|
||||
outputView = (EditText) findViewById(R.id.output);
|
||||
|
||||
inputView.requestFocus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the Spinners to their new Positions
|
||||
* @param c Configuration
|
||||
*/
|
||||
public void updateSpinner(int[] c)
|
||||
{
|
||||
rotor1View.setSelection(c[0] - 1);
|
||||
rotor2View.setSelection(c[1] - 1);
|
||||
rotor3View.setSelection(c[2] - 1);
|
||||
rotor1PositionView.setSelection(c[4]);
|
||||
rotor2PositionView.setSelection(c[5]);
|
||||
rotor3PositionView.setSelection(c[6]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the dialog where the user can pick the ringsettings and set them if the user doesn't
|
||||
* abort.
|
||||
*/
|
||||
public void showRingSettingsDialog()
|
||||
{
|
||||
View ringSettingsView = View.inflate(this, R.layout.dialog_ringsettings, null);
|
||||
|
||||
Integer[] ringArray = new Integer[26];
|
||||
for(int i=1; i<=26; i++) {ringArray[i-1] = i;}
|
||||
|
||||
final Spinner ring1 = (Spinner) ringSettingsView.findViewById(R.id.rotor1ring);
|
||||
ArrayAdapter<Integer> ring1Adapter = new ArrayAdapter<>(this.getApplicationContext(),
|
||||
android.R.layout.simple_spinner_item,ringArray);
|
||||
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<Integer> ring2Adapter = new ArrayAdapter<>(this.getApplicationContext(),
|
||||
android.R.layout.simple_spinner_item,ringArray);
|
||||
ring2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
ring2.setAdapter(ring2Adapter);
|
||||
ring2.setSelection(ringSettings[1]);
|
||||
|
||||
final Spinner ring3 = (Spinner) ringSettingsView.findViewById(R.id.rotor3ring);
|
||||
ArrayAdapter<Integer> ring3Adapter = new ArrayAdapter<>(this.getApplicationContext(),
|
||||
android.R.layout.simple_spinner_item,ringArray);
|
||||
ring3Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
ring3.setAdapter(ring3Adapter);
|
||||
ring3.setSelection(ringSettings[2]);
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(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();
|
||||
}
|
||||
|
||||
public void showAboutDialog()
|
||||
{
|
||||
final View aboutView = View.inflate(this, R.layout.dialog_about, null);
|
||||
|
@ -373,6 +269,12 @@ public class MainActivity extends Activity
|
|||
}).show();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle preference changes
|
||||
* @param requestCode requestCode
|
||||
* @param resultCode resultCode (RESULT_SETTINGS is defined at the top)
|
||||
* @param data data (not important here)
|
||||
*/
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
||||
|
@ -380,45 +282,63 @@ public class MainActivity extends Activity
|
|||
case RESULT_SETTINGS:
|
||||
{
|
||||
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
this.prefAnomaly = sharedPrefs.getBoolean("prefAnomaly", true);
|
||||
this.prefNumericLanguage = sharedPrefs.getString("prefNumericLanguage",getResources().
|
||||
getStringArray(R.array.pref_alias_numeric_spelling_language)[0]);
|
||||
;
|
||||
this.setPrefMachineType(sharedPrefs.getString("prefMachineType", getResources()
|
||||
.getStringArray(R.array.pref_list_machine_type)[0]));
|
||||
this.setPrefAnomaly(sharedPrefs.getBoolean("prefAnomaly", true));
|
||||
this.setPrefNumericLanguage(this.prefNumericLanguage = sharedPrefs.getString("prefNumericLanguage", getResources().
|
||||
getStringArray(R.array.pref_alias_numeric_spelling_language)[0]));
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the web page with the URL url
|
||||
* @param url URL of the website
|
||||
*/
|
||||
public void openWebPage(String url) {
|
||||
Uri webpage = Uri.parse(url);
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, webpage);
|
||||
Uri webPage = Uri.parse(url);
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, webPage);
|
||||
if (intent.resolveActivity(getPackageManager()) != null) {
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ActivitySingleton
|
||||
{
|
||||
/**
|
||||
* Singleton that grants access to an Activity from anywhere within the app
|
||||
*/
|
||||
public static class ActivitySingleton
|
||||
{
|
||||
private static ActivitySingleton instance = null;
|
||||
private Activity activity;
|
||||
|
||||
//private constructor
|
||||
private ActivitySingleton(){}
|
||||
//Singleton method
|
||||
public static ActivitySingleton getInstance()
|
||||
{
|
||||
if(instance == null) instance = new ActivitySingleton();
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an Activity that the Singleton returns
|
||||
* @param activity activity that's stored
|
||||
*/
|
||||
public void setActivity(Activity activity)
|
||||
{
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the stored Activity
|
||||
* @return stored Activity
|
||||
*/
|
||||
public Activity getActivity()
|
||||
{
|
||||
return activity;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
168
app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma.java
Executable file
168
app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma.java
Executable file
|
@ -0,0 +1,168 @@
|
|||
package de.vanitasvitae.enigmandroid.enigma;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.enigma.inputPreparer.InputPreparer;
|
||||
|
||||
/**
|
||||
* Main component of the Enigma machine
|
||||
* This is the mostly abstract base of any enigma machine.
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* @author vanitasvitae
|
||||
*/
|
||||
public abstract class Enigma
|
||||
{
|
||||
protected static String machineType;
|
||||
protected boolean doAnomaly = false; //Has the time come to handle an anomaly?
|
||||
protected boolean prefAnomaly; //Do you WANT to simulate the anomaly?
|
||||
protected InputPreparer inputPreparer;
|
||||
|
||||
/**
|
||||
* Set the enigma to an initial state
|
||||
*/
|
||||
public abstract void initialize();
|
||||
|
||||
/**
|
||||
* Set the reflector of the enigma machine to one of type type.
|
||||
* @param type type indicator of the reflector
|
||||
* @return success (not every reflector fits in every machine)
|
||||
*/
|
||||
public abstract boolean setReflector(int type);
|
||||
|
||||
/**
|
||||
* Set the rotor on position pos to a rotor of type type with ring-setting ringSetting and
|
||||
* rotation rotation.
|
||||
* @param pos position of the rotor
|
||||
* @param type type indicator
|
||||
* @param ringSetting ringSetting
|
||||
* @param rotation rotation
|
||||
* @return success
|
||||
*/
|
||||
public abstract boolean setRotor(int pos, int type, int ringSetting, int rotation);
|
||||
|
||||
/**
|
||||
* Encrypt / Decrypt a given String w.
|
||||
* w must be prepared using prepare(w) beforehand.
|
||||
* Doing so changes the state of the rotors but not the state of the plugboard and the
|
||||
* ringSettings
|
||||
*
|
||||
* @param w Text to decrypt/encrypt
|
||||
* @return encrypted/decrypted string
|
||||
*/
|
||||
public String encrypt(String w)
|
||||
{
|
||||
//output string
|
||||
String output = "";
|
||||
//for each char x in k
|
||||
for (char x : w.toCharArray())
|
||||
{
|
||||
output = output + this.encryptChar(x);
|
||||
}
|
||||
//return en-/decrypted string
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the enigma into the next mechanical state.
|
||||
* This rotates the first rotor and eventually also the second/third.
|
||||
* Also this method handles the anomaly in case it should happen.
|
||||
*/
|
||||
public abstract void nextState();
|
||||
|
||||
/**
|
||||
* Substitute char k by sending the signal through the enigma.
|
||||
* The signal passes the plugboard, the rotors and returns back after going through the
|
||||
* reflector wheel.
|
||||
*
|
||||
* @param k input char
|
||||
* @return substituted output char
|
||||
*/
|
||||
public abstract char encryptChar(char k);
|
||||
|
||||
/**
|
||||
* Normalize the input.
|
||||
* Normalizing means keeping the input via modulo in the range from 0 to n-1, where n is equal
|
||||
* to the size of the rotors.
|
||||
* This is necessary since java allows negative modulo values,
|
||||
* which can break this implementation
|
||||
* @param input input signal
|
||||
* @return "normalized" input signal
|
||||
*/
|
||||
public abstract int normalize(int input);
|
||||
|
||||
/**
|
||||
* Set config of the enigma
|
||||
*
|
||||
* @param conf configuration
|
||||
*/
|
||||
public abstract void setConfiguration(int[] conf);
|
||||
|
||||
/**
|
||||
* Set the plugboard
|
||||
* @param p Plugboard
|
||||
*/
|
||||
public abstract void setPlugboard(Plugboard p);
|
||||
|
||||
/**
|
||||
* Return the configuration, the enigma machine is in right NOW
|
||||
*
|
||||
* @return array containing configuration
|
||||
*/
|
||||
public abstract int[] getConfiguration();
|
||||
|
||||
/**
|
||||
* Set the inputPreparer
|
||||
* @param preparer concrete InputPreparer
|
||||
*/
|
||||
public void setInputPreparer(InputPreparer preparer)
|
||||
{
|
||||
this.inputPreparer = preparer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return the inputPreparer
|
||||
* @return inputPreparer
|
||||
*/
|
||||
public InputPreparer getInputPreparer()
|
||||
{
|
||||
if(inputPreparer == null)
|
||||
{
|
||||
MainActivity main = (MainActivity) MainActivity.ActivitySingleton.getInstance().getActivity();
|
||||
inputPreparer = InputPreparer.createInputPreparer(main.getPrefNumericLanguage());
|
||||
}
|
||||
return this.inputPreparer;
|
||||
}
|
||||
|
||||
/**
|
||||
* set prefAnomaly variable
|
||||
* @param b boolean
|
||||
*/
|
||||
public void setPrefAnomaly(boolean b)
|
||||
{
|
||||
this.prefAnomaly = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type indicator of the enigma machine
|
||||
* @return type
|
||||
*/
|
||||
public String getMachineType()
|
||||
{
|
||||
return machineType;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
package de.vanitasvitae.enigmandroid.enigma;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.enigma.rotors.Reflector;
|
||||
import de.vanitasvitae.enigmandroid.enigma.rotors.Rotor;
|
||||
|
||||
/**
|
||||
* Concrete implementation of an enigma machine of type I
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* @author vanitasvitae
|
||||
*/
|
||||
public class Enigma_I extends Enigma {
|
||||
protected Rotor rotor1;
|
||||
protected Rotor rotor2;
|
||||
protected Rotor rotor3;
|
||||
|
||||
protected Reflector reflector;
|
||||
|
||||
protected Plugboard plugboard;
|
||||
|
||||
public Enigma_I() {
|
||||
machineType = "I";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize()
|
||||
{
|
||||
this.setPlugboard(new Plugboard());
|
||||
//I,II,III, A, 0,0,0, 0,0,0
|
||||
this.setConfiguration(new int[]{1,2,3,1,0,0,0,0,0,0});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextState()
|
||||
{
|
||||
rotor1.rotate();
|
||||
if (rotor1.isAtTurnoverPosition() || (this.doAnomaly && prefAnomaly))
|
||||
{
|
||||
rotor2.rotate();
|
||||
this.doAnomaly = rotor2.doubleTurnAnomaly();
|
||||
if (rotor2.isAtTurnoverPosition())
|
||||
{
|
||||
rotor3.rotate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public char encryptChar(char k)
|
||||
{
|
||||
nextState();
|
||||
int x = ((int) k)-65; //Cast to int and remove Unicode Offset (A=65 in Unicode.)
|
||||
//Encryption
|
||||
//forward direction
|
||||
x = plugboard.encrypt(x);
|
||||
x = normalize(x + rotor1.getRotation() - rotor1.getRingSetting());
|
||||
x = rotor1.encryptForward(x);
|
||||
x = normalize(x - rotor1.getRotation() + rotor1.getRingSetting() + rotor2.getRotation() - rotor2.getRingSetting());
|
||||
x = rotor2.encryptForward(x);
|
||||
x = normalize(x - rotor2.getRotation() + rotor2.getRingSetting() + rotor3.getRotation() - rotor3.getRingSetting());
|
||||
x = rotor3.encryptForward(x);
|
||||
x = normalize(x - rotor3.getRotation() + rotor3.getRingSetting());
|
||||
//TODO: CHECK
|
||||
//backward direction
|
||||
x = reflector.encrypt(x);
|
||||
x = normalize(x + rotor3.getRotation() - rotor3.getRingSetting());
|
||||
x = rotor3.encryptBackward(x);
|
||||
x = normalize(x + rotor2.getRotation() - rotor2.getRingSetting() - rotor3.getRotation() + rotor3.getRingSetting());
|
||||
x = rotor2.encryptBackward(x);
|
||||
x = normalize(x + rotor1.getRotation() - rotor1.getRingSetting() - rotor2.getRotation() + rotor2.getRingSetting());
|
||||
x = rotor1.encryptBackward(x);
|
||||
x = normalize(x - rotor1.getRotation() + rotor1.getRingSetting());
|
||||
x = plugboard.encrypt(x);
|
||||
return (char) (x + 65); //Add Offset again, cast back to char and return
|
||||
}
|
||||
|
||||
@Override
|
||||
public int normalize(int input) {
|
||||
return (input+26) % 26;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlugboard(Plugboard p)
|
||||
{
|
||||
this.plugboard = p;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getConfiguration()
|
||||
{
|
||||
int[] conf = new int[10];
|
||||
conf[0] = rotor1.getType();
|
||||
conf[1] = rotor2.getType();
|
||||
conf[2] = rotor3.getType();
|
||||
conf[3] = reflector.getType();
|
||||
conf[4] = rotor1.getRotation();
|
||||
conf[5] = rotor2.getRotation();
|
||||
conf[6] = rotor3.getRotation();
|
||||
conf[7] = rotor1.getRingSetting();
|
||||
conf[8] = rotor2.getRingSetting();
|
||||
conf[9] = rotor3.getRingSetting();
|
||||
return conf;
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* conf:
|
||||
* 0..2 -> rotor1..rotor3 type
|
||||
* 3 -> reflector type
|
||||
* 4..6 -> rotor1..rotor3 rotation
|
||||
* 7..9 -> rotor1..rotor3 ringSetting
|
||||
*/
|
||||
public void setConfiguration(int[] conf)
|
||||
{
|
||||
this.setRotor(1,conf[0],conf[7],conf[4]);
|
||||
this.setRotor(2,conf[1],conf[8],conf[5]);
|
||||
this.setRotor(3,conf[2],conf[9],conf[6]);
|
||||
this.setReflector(conf[3]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setRotor(int pos, int type, int ringSetting, int rotation)
|
||||
{
|
||||
if(pos >= 1 && pos <= 3) {
|
||||
if (type >= 1 && type <= 5) {
|
||||
Rotor rotor = Rotor.createRotor(type, ringSetting, rotation);
|
||||
switch (pos) {
|
||||
case 1:
|
||||
rotor1 = rotor;
|
||||
break;
|
||||
case 2:
|
||||
rotor2 = rotor;
|
||||
break;
|
||||
default:
|
||||
rotor3 = rotor;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Log.d("EnigmAndroid/M3/setRot", "Error: Type " + type + " at position " + pos);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setReflector(int type)
|
||||
{
|
||||
if(type >= 1 && type <= 3)
|
||||
{
|
||||
reflector = Reflector.createReflector(type);
|
||||
return true;
|
||||
}
|
||||
Log.d("EnigmAndroid/I/setRef", "Error: Can't set type "+type);
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package de.vanitasvitae.enigmandroid.enigma;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.enigma.rotors.Reflector;
|
||||
import de.vanitasvitae.enigmandroid.enigma.rotors.Rotor;
|
||||
|
||||
/**
|
||||
* Concrete implementation of an enigma machine model M3
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* @author vanitasvitae
|
||||
*/
|
||||
public class Enigma_M3 extends Enigma_I
|
||||
{
|
||||
public Enigma_M3()
|
||||
{
|
||||
machineType = "M3";
|
||||
}
|
||||
@Override
|
||||
public void initialize()
|
||||
{
|
||||
this.setPlugboard(new Plugboard());
|
||||
//I,II,III, B, 0,0,0, 0,0,0
|
||||
this.setConfiguration(new int[]{1,2,3,2,0,0,0,0,0,0});
|
||||
}
|
||||
@Override
|
||||
public boolean setRotor(int pos, int type, int ringSetting, int rotation)
|
||||
{
|
||||
if(pos >= 1 && pos <= 3) {
|
||||
if (type >= 1 && type <= 8) {
|
||||
Rotor rotor = Rotor.createRotor(type, ringSetting, rotation);
|
||||
switch (pos) {
|
||||
case 1:
|
||||
rotor1 = rotor;
|
||||
break;
|
||||
case 2:
|
||||
rotor2 = rotor;
|
||||
break;
|
||||
default:
|
||||
rotor3 = rotor;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Log.d("EnigmAndroid/M3/setRot", "Error: Type " + type + " at position " + pos);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setReflector(int type)
|
||||
{
|
||||
if(type >= 2 && type <= 3)
|
||||
{
|
||||
reflector = Reflector.createReflector(type);
|
||||
return true;
|
||||
}
|
||||
Log.d("EnigmAndroid/M3/setRef", "Error: Can't set type "+type);
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,214 @@
|
|||
package de.vanitasvitae.enigmandroid.enigma;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.enigma.rotors.Reflector;
|
||||
import de.vanitasvitae.enigmandroid.enigma.rotors.Rotor;
|
||||
|
||||
/**
|
||||
* Concrete Implementation of the Enigma Machine type M4 of the german Kriegsmarine
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* @author vanitasvitae
|
||||
*/
|
||||
public class Enigma_M4 extends Enigma
|
||||
{
|
||||
private Rotor rotor1;
|
||||
private Rotor rotor2;
|
||||
private Rotor rotor3;
|
||||
|
||||
private Rotor rotor4;
|
||||
private Reflector thinReflector;
|
||||
|
||||
private Plugboard plugboard;
|
||||
|
||||
public Enigma_M4()
|
||||
{
|
||||
machineType = "M4";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setRotor(int pos, int type, int ringSetting, int rotation)
|
||||
{
|
||||
if(pos >= 1 && pos <= 3)
|
||||
{
|
||||
if(type >= 1 && type <= 8)
|
||||
{
|
||||
Rotor rotor = Rotor.createRotor(type, ringSetting, rotation);
|
||||
switch (pos)
|
||||
{
|
||||
case 1: rotor1 = rotor;
|
||||
break;
|
||||
case 2: rotor2 = rotor;
|
||||
break;
|
||||
default: rotor3 = rotor;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.d("EnigmAndroid/M4/setRot", "Error: Type " + type + " at position " + pos);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//Thin rotor
|
||||
else if(pos == 4)
|
||||
{
|
||||
if(type >=9 && type <=10) {
|
||||
rotor4 = Rotor.createRotor(type, ringSetting, rotation);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Log.d("EnigmAndroid/M3/setRot", "Error: Type " + type + " at position " + pos);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setReflector(int type)
|
||||
{
|
||||
if(type >= 4 && type <=5)
|
||||
{
|
||||
this.thinReflector = Reflector.createReflector(type);
|
||||
return true;
|
||||
}
|
||||
Log.d("EnigmAndroid/M4/setRef","Error: Can't set type "+type);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize()
|
||||
{
|
||||
this.setPlugboard(new Plugboard());
|
||||
this.setConfiguration(new int[]{1,2,3,9,4,0,0,0,0,0,0,0,0});
|
||||
this.prefAnomaly = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Set the enigma into the next mechanical state.
|
||||
* This rotates the first rotor and eventually also the second/third.
|
||||
* Also this method handles the anomaly in case it should happen.
|
||||
*/
|
||||
public void nextState()
|
||||
{
|
||||
//Rotate rotors
|
||||
rotor1.rotate();
|
||||
//Eventually turn next rotor (usual turnOver or anomaly)
|
||||
if (rotor1.isAtTurnoverPosition() || (this.doAnomaly && prefAnomaly))
|
||||
{
|
||||
rotor2.rotate();
|
||||
//Set doAnomaly for next call of encryptChar
|
||||
this.doAnomaly = rotor2.doubleTurnAnomaly();
|
||||
//Eventually rotate next rotor
|
||||
if (rotor2.isAtTurnoverPosition())
|
||||
{
|
||||
rotor3.rotate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Substitute char k by sending the signal through the enigma.
|
||||
* The signal passes the plugboard, the rotors and returns back after going through the
|
||||
* reflector wheel.
|
||||
*
|
||||
* @param k input char
|
||||
* @return substituted output char
|
||||
*/
|
||||
public char encryptChar(char k)
|
||||
{
|
||||
nextState(); //Rotate rotors
|
||||
int x = ((int) k)-65; //Cast to int and remove Unicode Offset (A=65 in Unicode.)
|
||||
//Encryption
|
||||
//forward direction
|
||||
x = plugboard.encrypt(x);
|
||||
x = normalize(x + rotor1.getRotation() - rotor1.getRingSetting());
|
||||
x = rotor1.encryptForward(x);
|
||||
x = normalize(x - rotor1.getRotation() + rotor1.getRingSetting() + rotor2.getRotation() - rotor2.getRingSetting());
|
||||
x = rotor2.encryptForward(x);
|
||||
x = normalize(x - rotor2.getRotation() + rotor2.getRingSetting() + rotor3.getRotation() - rotor3.getRingSetting());
|
||||
x = rotor3.encryptForward(x);
|
||||
x = normalize(x - rotor3.getRotation() + rotor3.getRingSetting() + rotor4.getRotation() - rotor4.getRingSetting());
|
||||
x = rotor4.encryptForward(x);
|
||||
x = normalize(x - rotor4.getRotation() + rotor4.getRingSetting());
|
||||
//backward direction
|
||||
x = thinReflector.encrypt(x);
|
||||
x = normalize(x + rotor4.getRotation() - rotor4.getRingSetting());
|
||||
x = rotor4.encryptBackward(x);
|
||||
x = normalize(x + rotor3.getRotation() - rotor3.getRingSetting() - rotor4.getRotation() + rotor4.getRingSetting());
|
||||
x = rotor3.encryptBackward(x);
|
||||
x = normalize(x + rotor2.getRotation() - rotor2.getRingSetting() - rotor3.getRotation() + rotor3.getRingSetting());
|
||||
x = rotor2.encryptBackward(x);
|
||||
x = normalize(x + rotor1.getRotation() - rotor1.getRingSetting() - rotor2.getRotation() + rotor2.getRingSetting());
|
||||
x = rotor1.encryptBackward(x);
|
||||
x = normalize(x - rotor1.getRotation() + rotor1.getRingSetting());
|
||||
x = plugboard.encrypt(x);
|
||||
return (char) (x + 65); //Add Offset again and cast back to char
|
||||
}
|
||||
|
||||
@Override
|
||||
public int normalize(int input) {
|
||||
return (input + 26) % 26;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlugboard(Plugboard p)
|
||||
{
|
||||
this.plugboard = p;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getConfiguration() {
|
||||
int[] configuration = new int[13];
|
||||
configuration[0] = rotor1.getType();
|
||||
configuration[1] = rotor2.getType();
|
||||
configuration[2] = rotor3.getType();
|
||||
configuration[3] = rotor4.getType();
|
||||
|
||||
configuration[4] = thinReflector.getType();
|
||||
|
||||
configuration[5] = rotor1.getRotation();
|
||||
configuration[6] = rotor2.getRotation();
|
||||
configuration[7] = rotor3.getRotation();
|
||||
configuration[8] = rotor4.getRotation();
|
||||
|
||||
configuration[9] = rotor1.getRingSetting();
|
||||
configuration[10] = rotor2.getRingSetting();
|
||||
configuration[11] = rotor3.getRingSetting();
|
||||
|
||||
configuration[12] = rotor4.getRingSetting();
|
||||
return configuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConfiguration(int[] conf)
|
||||
{
|
||||
if(conf.length != 13)
|
||||
{
|
||||
Log.d("EnigmAndroid/M4/setCon", "Invalid conf array length. conf array length " +
|
||||
"should be 13 (is "+conf.length+")");
|
||||
}
|
||||
else
|
||||
{
|
||||
setRotor(1, conf[0], conf[9], conf[5]);
|
||||
setRotor(2, conf[1], conf[10], conf[6]);
|
||||
setRotor(3, conf[2], conf[11], conf[7]);
|
||||
setRotor(4, conf[3], conf[12], conf[8]);
|
||||
setReflector(conf[4]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +1,13 @@
|
|||
package de.vanitasvitae.enigmandroid;
|
||||
package de.vanitasvitae.enigmandroid.enigma;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.R;
|
||||
|
||||
/**
|
||||
* Plugboard of the enigma
|
||||
* Copyright (C) 2015 Paul Schaub
|
|
@ -1,9 +1,7 @@
|
|||
package de.vanitasvitae.enigmandroid;
|
||||
|
||||
import java.text.Normalizer;
|
||||
package de.vanitasvitae.enigmandroid.enigma.inputPreparer;
|
||||
|
||||
/**
|
||||
* Preparator class that prepares input text to only consist of [A..Z]
|
||||
* Preparer class that prepares input text to only consist of [A..Z]
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
@ -21,11 +19,11 @@ import java.text.Normalizer;
|
|||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* @author vanitasvitae
|
||||
*/
|
||||
public abstract class InputPreparator
|
||||
public abstract class InputPreparer
|
||||
{
|
||||
/**
|
||||
* Prepare the input String in a way that it only contains letters from [A..Z].
|
||||
* Replace special characters and spell numbers.
|
||||
* Replace special characters, remove spaces and spell numbers.
|
||||
* @param input String
|
||||
* @return prepared String
|
||||
*/
|
||||
|
@ -46,7 +44,7 @@ public abstract class InputPreparator
|
|||
output = output + replaceNumber(x);
|
||||
}
|
||||
//x is special symbol
|
||||
else
|
||||
else if (x != ' ')
|
||||
{
|
||||
output = output + 'X';
|
||||
}
|
||||
|
@ -62,24 +60,25 @@ public abstract class InputPreparator
|
|||
public abstract String replaceNumber(char input);
|
||||
|
||||
/**
|
||||
* Factory method that creates a specific InputPreparator
|
||||
* @param language language alias that specifies the language (de,en)
|
||||
* @return concrete InputPreparator
|
||||
* Factory method that creates a specific InputPreparer
|
||||
* @param language language alias that specifies the language (de,fr,en)
|
||||
* @return concrete InputPreparer
|
||||
*/
|
||||
public static InputPreparator createInputPreparator(String language)
|
||||
public static InputPreparer createInputPreparer(String language)
|
||||
{
|
||||
switch (language)
|
||||
{
|
||||
case "de": return new InputPreparatorGerman();
|
||||
default: return new InputPreparatorEnglish();
|
||||
case "de": return new InputPreparerGerman();
|
||||
case "fr": return new InputPreparerFrench();
|
||||
default: return new InputPreparerEnglish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of a german InputPreparator
|
||||
* Concrete implementation of a german InputPreparer
|
||||
*/
|
||||
class InputPreparatorGerman extends InputPreparator
|
||||
class InputPreparerGerman extends InputPreparer
|
||||
{
|
||||
@Override
|
||||
public String replaceNumber(char input) {
|
||||
|
@ -100,9 +99,9 @@ class InputPreparatorGerman extends InputPreparator
|
|||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of an english InputPreparator
|
||||
* Concrete implementation of an english InputPreparer
|
||||
*/
|
||||
class InputPreparatorEnglish extends InputPreparator
|
||||
class InputPreparerEnglish extends InputPreparer
|
||||
{
|
||||
@Override
|
||||
public String replaceNumber(char input)
|
||||
|
@ -121,3 +120,27 @@ class InputPreparatorEnglish extends InputPreparator
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of a french InputPreparer
|
||||
*/
|
||||
class InputPreparerFrench extends InputPreparer
|
||||
{
|
||||
|
||||
@Override
|
||||
public String replaceNumber(char input)
|
||||
{
|
||||
switch (input) {
|
||||
case '0': return "ZERO";
|
||||
case '1': return "UN";
|
||||
case '2': return "DEUX";
|
||||
case '3': return "TROIS";
|
||||
case '4': return "QUATRE";
|
||||
case '5': return "CINQ";
|
||||
case '6': return "SIX";
|
||||
case '7': return "SEPT";
|
||||
case '8': return "HUIT";
|
||||
default: return "NEUF";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package de.vanitasvitae.enigmandroid.rotors;
|
||||
package de.vanitasvitae.enigmandroid.enigma.rotors;
|
||||
|
||||
/**
|
||||
* Reflector of the enigma machine.
|
||||
|
@ -42,33 +42,6 @@ public class Reflector
|
|||
this.connections = connections;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a reflector of type A
|
||||
* @return ReflectorA
|
||||
*/
|
||||
public static Reflector createReflectorA()
|
||||
{
|
||||
return new ReflectorA();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a reflector of type B
|
||||
* @return ReflectorB
|
||||
*/
|
||||
public static Reflector createReflectorB()
|
||||
{
|
||||
return new ReflectorB();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a reflector of type C
|
||||
* @return ReflectorC
|
||||
*/
|
||||
public static Reflector createReflectorC()
|
||||
{
|
||||
return new ReflectorC();
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to create reflectors.
|
||||
* @param type type of the created reflector
|
||||
|
@ -81,9 +54,11 @@ public class Reflector
|
|||
{
|
||||
switch (type)
|
||||
{
|
||||
case 1: return createReflectorA();
|
||||
case 2: return createReflectorB();
|
||||
default: return createReflectorC();
|
||||
case 1: return new ReflectorA();
|
||||
case 2: return new ReflectorB();
|
||||
case 3: return new ReflectorC();
|
||||
case 4: return new ReflectorThinB();
|
||||
default: return new ReflectorThinC();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,34 +116,70 @@ public class Reflector
|
|||
|
||||
/**
|
||||
* Concrete implementation of ReflectorA
|
||||
* Used in Enigma I
|
||||
* AE BJ CM DZ FL GY HX IV KW NR OQ PU ST
|
||||
*/
|
||||
private static class ReflectorA extends Reflector
|
||||
{
|
||||
public ReflectorA()
|
||||
{
|
||||
super("A", 1, new Integer[]{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});
|
||||
super("A", 1, new Integer[]{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});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of ReflectorB
|
||||
* Used in Enigma I, M3
|
||||
* AY BR CU DH EQ FS GL IP JX KN MO TZ VW
|
||||
*/
|
||||
private static class ReflectorB extends Reflector
|
||||
{
|
||||
public ReflectorB()
|
||||
{
|
||||
super("B", 2, new Integer[]{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});
|
||||
super("B", 2, new Integer[]{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});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of ReflectorC
|
||||
* Used in Enigma I, M3
|
||||
* AF BV CP DJ EI GO HY KR LZ MX NW QT SU
|
||||
*/
|
||||
private static class ReflectorC extends Reflector
|
||||
{
|
||||
public ReflectorC()
|
||||
{
|
||||
super("C", 3, new Integer[]{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});
|
||||
super("C", 3, new Integer[]{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});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of thin reflector type b (not equal to normal type b!)
|
||||
* When used with Rotor Beta on rotation 0, the pair was equivalent to normal reflector B
|
||||
* S->Beta->ThinB->Beta'->X == X->UKWB->S
|
||||
* Used in Enigma M4
|
||||
* E N K Q A U Y W J I C O P B L M D X Z V F T H R G S
|
||||
*/
|
||||
private static class ReflectorThinB extends Reflector
|
||||
{
|
||||
public ReflectorThinB()
|
||||
{
|
||||
super("B", 4, new Integer[]{4,13,10,16,0,20,24,22,9,8,2,14,15,1,11,12,3,23,25,21,5,19,7,17,6,18});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of thin reflector type c (not equal to normal type c!)
|
||||
* When used with Rotor Gamma on rotation 0, the pair was equivalent to normal reflector C
|
||||
* S->Gamma->ThinC->Gamma'->X == X->UKWC->S
|
||||
* Used in Enigma M4
|
||||
* R D O B J N T K V E H M L F C W Z A X G Y I P S U Q
|
||||
*/
|
||||
private static class ReflectorThinC extends Reflector
|
||||
{
|
||||
public ReflectorThinC()
|
||||
{
|
||||
super("B", 5, new Integer[]{17,3,14,1,9,13,19,10,21,4,7,12,11,5,2,22,25,0,23,6,24,8,15,18,20,16});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package de.vanitasvitae.enigmandroid.rotors;
|
||||
package de.vanitasvitae.enigmandroid.enigma.rotors;
|
||||
|
||||
/**
|
||||
* Rotor super class and inner concrete implementations
|
||||
|
@ -30,7 +30,7 @@ public class Rotor
|
|||
protected int type;
|
||||
protected Integer[] connections;
|
||||
protected Integer[] reversedConnections;
|
||||
protected int turnOverNotch;
|
||||
protected Integer[] turnOverNotches;
|
||||
|
||||
protected int ringSetting;
|
||||
protected int rotation;
|
||||
|
@ -47,18 +47,18 @@ public class Rotor
|
|||
* @param reversedConnections inverse wiring used to encrypt in the opposite direction
|
||||
* (connections[reversedConnections[i]] = i
|
||||
* for all i in 0..getRotorSize()-1.
|
||||
* @param turnOverNotch Position of the turnover notch
|
||||
* @param turnOverNotches Position(s) of the turnover notch(es)
|
||||
* @param ringSetting setting of the ring that holds the letters
|
||||
* @param rotation rotation of the rotor
|
||||
*/
|
||||
protected Rotor(String name, int type, Integer[] connections, Integer[] reversedConnections,
|
||||
int turnOverNotch, int ringSetting, int rotation)
|
||||
Integer[] turnOverNotches, int ringSetting, int rotation)
|
||||
{
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.connections = connections;
|
||||
this.reversedConnections = reversedConnections;
|
||||
this.turnOverNotch = turnOverNotch;
|
||||
this.turnOverNotches = turnOverNotches;
|
||||
this.ringSetting = ringSetting;
|
||||
this.rotation = rotation;
|
||||
}
|
||||
|
@ -66,7 +66,9 @@ public class Rotor
|
|||
/**
|
||||
* Factory method that creates a rotor accordingly to the type.
|
||||
* Also initialize the rotor with ringSetting and rotation.
|
||||
* @param type type indicator (1..5)
|
||||
* @param type type indicator (1..10)
|
||||
* 1..8 -> I..VIII
|
||||
* 9,10 -> Beta, Gamma
|
||||
* @param ringSetting setting of the outer ring (0..25)
|
||||
* @param rotation rotation of the rotor
|
||||
* @return Concrete rotor
|
||||
|
@ -75,77 +77,28 @@ public class Rotor
|
|||
{
|
||||
switch (type)
|
||||
{
|
||||
case 1: return createRotorI(ringSetting, rotation);
|
||||
case 2: return createRotorII(ringSetting, rotation);
|
||||
case 3: return createRotorIII(ringSetting, rotation);
|
||||
case 4: return createRotorIV(ringSetting, rotation);
|
||||
default: return createRotorV(ringSetting, rotation);
|
||||
case 1: return new RotorI(ringSetting, rotation);
|
||||
case 2: return new RotorII(ringSetting, rotation);
|
||||
case 3: return new RotorIII(ringSetting, rotation);
|
||||
case 4: return new RotorIV(ringSetting, rotation);
|
||||
case 5: return new RotorV(ringSetting, rotation);
|
||||
case 6: return new RotorVI(ringSetting, rotation);
|
||||
case 7: return new RotorVII(ringSetting, rotation);
|
||||
case 8: return new RotorVIII(ringSetting, rotation);
|
||||
case 9: return new RotorBeta(ringSetting, rotation);
|
||||
default: return new RotorGamma(ringSetting, rotation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create concrete Rotor of type 1 (I) initialized with ringSetting and rotation
|
||||
* @param ringSetting setting of the outer ring
|
||||
* @param rotation rotation of the rotor
|
||||
* @return RotorI
|
||||
*/
|
||||
public static Rotor createRotorI(int ringSetting, int rotation)
|
||||
{
|
||||
return new RotorI(ringSetting, rotation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create concrete Rotor of type 2 (II) initialized with ringSetting and rotation
|
||||
* @param ringSetting setting of the outer ring
|
||||
* @param rotation rotation of the rotor
|
||||
* @return RotorI
|
||||
*/
|
||||
public static Rotor createRotorII(int ringSetting, int rotation)
|
||||
{
|
||||
return new RotorII(ringSetting, rotation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create concrete Rotor of type 3 (III) initialized with ringSetting and rotation
|
||||
* @param ringSetting setting of the outer ring
|
||||
* @param rotation rotation of the rotor
|
||||
* @return RotorI
|
||||
*/
|
||||
public static Rotor createRotorIII(int ringSetting, int rotation)
|
||||
{
|
||||
return new RotorIII(ringSetting, rotation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create concrete Rotor of type 4 (IV) initialized with ringSetting and rotation
|
||||
* @param ringSetting setting of the outer ring
|
||||
* @param rotation rotation of the rotor
|
||||
* @return RotorI
|
||||
*/
|
||||
public static Rotor createRotorIV(int ringSetting, int rotation)
|
||||
{
|
||||
return new RotorIV(ringSetting, rotation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create concrete Rotor of type 5 (V) initialized with ringSetting and rotation
|
||||
* @param ringSetting setting of the outer ring
|
||||
* @param rotation rotation of the rotor
|
||||
* @return RotorI
|
||||
*/
|
||||
public static Rotor createRotorV(int ringSetting, int rotation)
|
||||
{
|
||||
return new RotorV(ringSetting, rotation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt an input signal via the internal wiring in "forward" direction (using connections)
|
||||
* Encrypt an input signal via the internal wiring in "forward" direction towards the reflector
|
||||
* (using connections)
|
||||
* @param input signal
|
||||
* @return encrypted signal
|
||||
*/
|
||||
public int encryptForward(int input)
|
||||
{
|
||||
return this.connections[normalize(input)];
|
||||
return this.connections[normalize(input)];// - this.ringSetting)];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -156,7 +109,7 @@ public class Rotor
|
|||
*/
|
||||
public int encryptBackward(int input)
|
||||
{
|
||||
return this.reversedConnections[normalize(input)];
|
||||
return this.reversedConnections[normalize(input)];// + this.ringSetting)];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -175,7 +128,7 @@ public class Rotor
|
|||
*/
|
||||
public int getRotation()
|
||||
{
|
||||
return this.rotation - this.getRingSetting();
|
||||
return this.rotation;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -192,7 +145,12 @@ public class Rotor
|
|||
*/
|
||||
public boolean isAtTurnoverPosition()
|
||||
{
|
||||
return this.rotation == this.turnOverNotch;
|
||||
for(int x : getTurnOverNotches())
|
||||
{
|
||||
//if(x == this.rotation + this.ringSetting) return true;
|
||||
if(x == this.rotation) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -206,16 +164,20 @@ public class Rotor
|
|||
*/
|
||||
public boolean doubleTurnAnomaly()
|
||||
{
|
||||
return this.rotation == this.getTurnOver() - 1;
|
||||
for(int x : getTurnOverNotches())
|
||||
{
|
||||
if(this.rotation == x-1) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position of the turnover notch
|
||||
* @return turnOverNotch
|
||||
* Returns the positions of the turnover notches in a array
|
||||
* @return turnOverNotches
|
||||
*/
|
||||
public int getTurnOver()
|
||||
public Integer[] getTurnOverNotches()
|
||||
{
|
||||
return this.turnOverNotch;
|
||||
return this.turnOverNotches;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -261,6 +223,8 @@ public class Rotor
|
|||
|
||||
/**
|
||||
* Concrete implementation of Rotor of type 1 (I)
|
||||
* Used in Enigma I, M3, M4
|
||||
* 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
|
||||
*/
|
||||
private static class RotorI extends Rotor
|
||||
{
|
||||
|
@ -269,12 +233,14 @@ public class Rotor
|
|||
super("I", 1,
|
||||
new Integer[]{4, 10, 12, 5, 11, 6, 3, 16, 21, 25, 13, 19, 14, 22, 24, 7, 23, 20, 18, 15, 0, 8, 1, 17, 2, 9},
|
||||
new Integer[]{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},
|
||||
17, ringSetting, rotation);
|
||||
new Integer[]{17}, ringSetting, rotation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of Rotor of type 2 (II)
|
||||
* Used in Enigma I, M3, M4
|
||||
* 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
|
||||
*/
|
||||
private static class RotorII extends Rotor
|
||||
{
|
||||
|
@ -283,12 +249,14 @@ public class Rotor
|
|||
super("II", 2,
|
||||
new Integer[]{0, 9, 3, 10, 18, 8, 17, 20, 23, 1, 11, 7, 22, 19, 12, 2, 16, 6, 25, 13, 15, 24, 5, 21, 14, 4},
|
||||
new Integer[]{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},
|
||||
5, ringSetting, rotation);
|
||||
new Integer[]{5}, ringSetting, rotation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of Rotor of type 3 (III)
|
||||
* Used in Enigma I, M3, M4
|
||||
* 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
|
||||
*/
|
||||
private static class RotorIII extends Rotor
|
||||
{
|
||||
|
@ -297,12 +265,14 @@ public class Rotor
|
|||
super("III", 3,
|
||||
new Integer[]{1, 3, 5, 7, 9, 11, 2, 15, 17, 19, 23, 21, 25, 13, 24, 4, 8, 22, 6, 0, 10, 12, 20, 18, 16, 14},
|
||||
new Integer[]{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},
|
||||
22, ringSetting, rotation);
|
||||
new Integer[]{22}, ringSetting, rotation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of Rotor of type 4 (IV)
|
||||
* Used in Enigma M3, M4
|
||||
* 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
|
||||
*/
|
||||
private static class RotorIV extends Rotor
|
||||
{
|
||||
|
@ -311,12 +281,14 @@ public class Rotor
|
|||
super("IV", 4,
|
||||
new Integer[]{4, 18, 14, 21, 15, 25, 9, 0, 24, 16, 20, 8, 17, 7, 23, 11, 13, 5, 19, 6, 10, 3, 2, 12, 22, 1},
|
||||
new Integer[]{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},
|
||||
10, ringSetting, rotation);
|
||||
new Integer[]{10}, ringSetting, rotation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of Rotor of type 5 (V)
|
||||
* Used in Enigma M3, M4
|
||||
* 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
|
||||
*/
|
||||
private static class RotorV extends Rotor
|
||||
{
|
||||
|
@ -325,7 +297,117 @@ public class Rotor
|
|||
super("V", 5,
|
||||
new Integer[]{21, 25, 1, 17, 6, 8, 19, 24, 20, 15, 18, 3, 13, 7, 11, 23, 0, 22, 12, 9, 16, 14, 5, 4, 2, 10},
|
||||
new Integer[]{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},
|
||||
0, ringSetting, rotation);
|
||||
new Integer[]{0}, ringSetting, rotation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of Rotor of type 6 (VI)
|
||||
* Used in Enigma M3, M4
|
||||
* J P G V O U M F Y Q B E N H Z R D K A S X L I C T W
|
||||
*/
|
||||
private static class RotorVI extends Rotor
|
||||
{
|
||||
public RotorVI(int ringSetting, int rotation)
|
||||
{
|
||||
super("VI", 6,
|
||||
new Integer[]{9,15,6,21,14,20,12,5,24,16,1,4,13,7,25,17,3,10,0,18,23,11,8,2,19,22},
|
||||
new Integer[]{18,10,23,16,11,7,2,13,22,0,17,21,6,12,4,1,9,15,19,24,5,3,25,20,8,14},
|
||||
new Integer[]{0,13}, ringSetting, rotation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of Rotor of type 7 (VII)
|
||||
* Used in Enigma M3, M4
|
||||
* N Z J H G R C X M Y S W B O U F A I V L P E K Q D T
|
||||
*/
|
||||
private static class RotorVII extends Rotor
|
||||
{
|
||||
public RotorVII(int ringSetting, int rotation)
|
||||
{
|
||||
super("VII", 7,
|
||||
new Integer[]{13,25,9,7,6,17,2,23,12,24,18,22,1,14,20,5,0,8,21,11,15,4,10,16,3,19},
|
||||
new Integer[]{16,12,6,24,21,15,4,3,17,2,22,19,8,0,13,20,23,5,10,25,14,18,11,7,9,1},
|
||||
new Integer[]{0,13}, ringSetting, rotation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of Rotor of type 8 (VIII)
|
||||
* Used in Enigma M3, M4
|
||||
* F K Q H T L X O C B J S P D Z R A M E W N I U Y G V
|
||||
*/
|
||||
private static class RotorVIII extends Rotor
|
||||
{
|
||||
public RotorVIII(int ringSetting, int rotation)
|
||||
{
|
||||
super("VIII", 8,
|
||||
new Integer[]{5,10,16,7,19,11,23,14,2,1,9,18,15,3,25,17,0,12,4,22,13,8,20,24,6,21},
|
||||
new Integer[]{16,9,8,13,18,0,24,3,21,10,1,5,17,20,7,12,2,15,11,4,22,25,19,6,23,14},
|
||||
new Integer[]{0,13}, ringSetting, rotation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of Rotor of type beta (Griechenwalze Beta)
|
||||
* Beta was used as a "thin" rotor in the M4. It was thinner than a "normal" rotor, so it
|
||||
* could be used together with one of the two thin reflectors as one rotor.
|
||||
* When used together with ReflectorThinB, Beta was equivalent to Reflector B (if rotation == 0)
|
||||
* That way the M4 was backwards compatible to the M3
|
||||
* Used in M4
|
||||
*/
|
||||
private static class RotorBeta extends Rotor
|
||||
{
|
||||
public RotorBeta(int ringSetting, int rotation)
|
||||
{
|
||||
super("Beta",9,
|
||||
new Integer[]{11,4,24,9,21,2,13,8,23,22,15,1,16,12,3,17,19,0,10,25,6,5,20,7,14,18},
|
||||
new Integer[]{17,11,5,14,1,21,20,23,7,3,18,0,13,6,24,10,12,15,25,16,22,4,9,8,2,19},
|
||||
new Integer[]{}, ringSetting, rotation);
|
||||
}
|
||||
@Override
|
||||
public void rotate()
|
||||
{
|
||||
//Thin rotors are fixed in position, so they dont rotate
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doubleTurnAnomaly()
|
||||
{
|
||||
//Nope, no anomaly
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of Rotor of type gamma (Griechenwalze Gamma)
|
||||
* Gamma was used as a "thin" rotor in the M4. It was thinner than a "normal" rotor, so it
|
||||
* could be used together with one of the two thin reflectors as one rotor.
|
||||
* When used together with ReflectorThinC, Gamma is equivalent to Reflector C
|
||||
* (if rotation == 0). That way the M4 was backwards compatible to the M3
|
||||
* Used in M4
|
||||
*/
|
||||
private static class RotorGamma extends Rotor
|
||||
{
|
||||
public RotorGamma(int ringSetting, int rotation)
|
||||
{
|
||||
super("Gamma",10,
|
||||
new Integer[]{5,18,14,10,0,13,20,4,17,7,12,1,19,8,24,2,22,11,16,15,25,23,21,6,9,3},
|
||||
new Integer[]{4,11,15,25,7,0,23,9,13,24,3,17,10,5,2,19,18,8,1,12,6,22,16,21,14,20},
|
||||
new Integer[]{}, ringSetting, rotation);
|
||||
}
|
||||
@Override
|
||||
public void rotate()
|
||||
{
|
||||
//Thin rotors are fixed in position, so they don't rotate
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doubleTurnAnomaly()
|
||||
{
|
||||
//Thin rotors don't do such weird stuff, they're normal just like you and me.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
package de.vanitasvitae.enigmandroid.enigma.util;
|
||||
|
||||
/**
|
||||
* Used to create wiring arrays from strings
|
||||
* Use strings like "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" as input
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* @author vanitasvitae
|
||||
*/
|
||||
public class RotorMaker
|
||||
{
|
||||
public static final int l = 26;
|
||||
public static void main(String[] args)
|
||||
{
|
||||
if(args.length == l) makeRotor(args);
|
||||
else if(args.length == 1) makeRotor(prepare(args[0]));
|
||||
else System.out.println("wrong input format!");
|
||||
}
|
||||
|
||||
public static void makeRotor(String input)
|
||||
{
|
||||
makeRotor(prepare(input));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the string (add spaces)
|
||||
* @param in input string
|
||||
* @return prepared string
|
||||
*/
|
||||
public static String[] prepare(String in)
|
||||
{
|
||||
String[] out = new String[l];
|
||||
int pos = 0;
|
||||
for(char x : in.toCharArray())
|
||||
{
|
||||
if(x != ' ')
|
||||
{
|
||||
try
|
||||
{
|
||||
out[pos] = ""+x;
|
||||
}
|
||||
catch (ArrayIndexOutOfBoundsException e)
|
||||
{
|
||||
System.out.println("String too long!");
|
||||
return null;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
if(pos!=l)
|
||||
{
|
||||
System.out.println("String too short!");
|
||||
return null;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate Array initializer for the given rotor configuration
|
||||
* @param input String describing the rotor
|
||||
*/
|
||||
public static void makeRotor(String[] input)
|
||||
{
|
||||
if(input.length != l) System.out.println("Wrong length! Input must have length "+l+"!");
|
||||
else
|
||||
{
|
||||
Integer[] out1 = new Integer[l];
|
||||
for(int i=0; i<l; i++)
|
||||
{
|
||||
String x = input[i].toUpperCase();
|
||||
char xc = x.charAt(0);
|
||||
int xint = (int) xc;
|
||||
xint = xint - 65;
|
||||
out1[i] = xint;
|
||||
}
|
||||
Integer[] out2 = new Integer[l];
|
||||
for(int i=0; i<l; i++)
|
||||
{
|
||||
out2[out1[i]] = i;
|
||||
}
|
||||
String output1 = "{";
|
||||
String output2 = "{";
|
||||
for(int i=0; i<l; i++)
|
||||
{
|
||||
output1 = output1 + out1[i]+",";
|
||||
output2 = output2 + out2[i]+",";
|
||||
}
|
||||
output1 = output1.substring(0,output1.length()-1) + "}";
|
||||
output2 = output2.substring(0,output2.length()-1) + "}";
|
||||
System.out.println("connections :" + output1);
|
||||
System.out.println("revConnects :" + output2);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
package de.vanitasvitae.enigmandroid.layout;
|
||||
|
||||
import android.widget.EditText;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.enigma.Enigma;
|
||||
|
||||
/**
|
||||
* Abstract LayoutContainer for Enigma machines
|
||||
* This class contains the layout and controls the layout elements such as spinners and stuff
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* @author vanitasvitae
|
||||
*/
|
||||
public abstract class LayoutContainer
|
||||
{
|
||||
protected MainActivity main;
|
||||
protected Enigma enigma;
|
||||
|
||||
protected EditText inputView;
|
||||
protected EditText outputView;
|
||||
|
||||
protected int[] ringSettings;
|
||||
|
||||
public LayoutContainer()
|
||||
{
|
||||
this.main = (MainActivity) MainActivity.ActivitySingleton.getInstance().getActivity();
|
||||
}
|
||||
|
||||
abstract void initialize();
|
||||
public abstract void reset();
|
||||
public abstract void updateLayout();
|
||||
public abstract int[] createConfiguration();
|
||||
public abstract int[][] createPlugboardConfiguration();
|
||||
public abstract void showRingSettingsDialog();
|
||||
|
||||
public Enigma getEnigma()
|
||||
{
|
||||
return enigma;
|
||||
}
|
||||
|
||||
public EditText getInputView()
|
||||
{
|
||||
return this.inputView;
|
||||
}
|
||||
|
||||
public EditText getOutputView()
|
||||
{
|
||||
return this.outputView;
|
||||
}
|
||||
|
||||
public static LayoutContainer createLayoutContainer(String type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case "M4":
|
||||
return new LayoutContainer_M4();
|
||||
case "M3":
|
||||
return new LayoutContainer_M3();
|
||||
default:
|
||||
return new LayoutContainer_I();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,224 @@
|
|||
package de.vanitasvitae.enigmandroid.layout;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.Toast;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.R;
|
||||
import de.vanitasvitae.enigmandroid.enigma.Enigma_I;
|
||||
import de.vanitasvitae.enigmandroid.enigma.Plugboard;
|
||||
|
||||
/**
|
||||
* Concrete LayoutContainer for the Enigma I layout.
|
||||
* This class contains the layout and controls the layout elements such as spinners and stuff
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* @author vanitasvitae
|
||||
*/
|
||||
public class LayoutContainer_I extends LayoutContainer
|
||||
{
|
||||
protected Spinner rotor1View;
|
||||
protected Spinner rotor2View;
|
||||
protected Spinner rotor3View;
|
||||
protected Spinner reflectorView;
|
||||
protected Spinner rotor1PositionView;
|
||||
protected Spinner rotor2PositionView;
|
||||
protected Spinner rotor3PositionView;
|
||||
|
||||
protected EditText plugboardView;
|
||||
|
||||
public LayoutContainer_I()
|
||||
{
|
||||
super();
|
||||
main.setTitle("I - EnigmAndroid");
|
||||
this.enigma = new Enigma_I();
|
||||
this.ringSettings = new int[]{0,0,0};
|
||||
this.rotor1View = (Spinner) main.findViewById(R.id.rotor1);
|
||||
this.rotor2View = (Spinner) main.findViewById(R.id.rotor2);
|
||||
this.rotor3View = (Spinner) main.findViewById(R.id.rotor3);
|
||||
this.reflectorView = (Spinner) main.findViewById(R.id.reflector);
|
||||
this.rotor1PositionView = (Spinner) main.findViewById(R.id.rotor1position);
|
||||
this.rotor2PositionView = (Spinner) main.findViewById(R.id.rotor2position);
|
||||
this.rotor3PositionView = (Spinner) main.findViewById(R.id.rotor3position);
|
||||
this.plugboardView = (EditText) main.findViewById(R.id.plugboard);
|
||||
this.inputView = (EditText) main.findViewById(R.id.input);
|
||||
this.outputView = (EditText) main.findViewById(R.id.output);
|
||||
|
||||
initialize();
|
||||
reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
void initialize()
|
||||
{
|
||||
Character[] rotorPositionArray = new Character[26];
|
||||
for(int i=0; i<26; i++) {rotorPositionArray[i] = (char) (65+i); /**Fill with A..Z*/}
|
||||
|
||||
ArrayAdapter<CharSequence> rotor1Adapter = ArrayAdapter.createFromResource(main, R.array.rotors_1_5,
|
||||
android.R.layout.simple_spinner_item);
|
||||
rotor1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor1View.setAdapter(rotor1Adapter);
|
||||
ArrayAdapter<CharSequence> rotor2Adapter = ArrayAdapter.createFromResource(main, R.array.rotors_1_5,
|
||||
android.R.layout.simple_spinner_item);
|
||||
rotor2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor2View.setAdapter(rotor2Adapter);
|
||||
ArrayAdapter<CharSequence> rotor3Adapter = ArrayAdapter.createFromResource(main, R.array.rotors_1_5,
|
||||
android.R.layout.simple_spinner_item);
|
||||
rotor3Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor3View.setAdapter(rotor3Adapter);
|
||||
|
||||
ArrayAdapter<CharSequence> reflectorAdapter = ArrayAdapter.createFromResource(main, R.array.reflectors_a_c,
|
||||
android.R.layout.simple_spinner_item);
|
||||
reflectorAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
reflectorView.setAdapter(reflectorAdapter);
|
||||
|
||||
ArrayAdapter<Character> rotor1PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(),
|
||||
android.R.layout.simple_spinner_item,rotorPositionArray);
|
||||
rotor1PositionAdapter.setDropDownViewResource(
|
||||
android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor1PositionView.setAdapter(rotor1PositionAdapter);
|
||||
ArrayAdapter<Character> rotor2PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(),
|
||||
android.R.layout.simple_spinner_item,rotorPositionArray);
|
||||
rotor2PositionAdapter.setDropDownViewResource(
|
||||
android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor2PositionView.setAdapter(rotor2PositionAdapter);
|
||||
ArrayAdapter<Character> rotor3PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(),
|
||||
android.R.layout.simple_spinner_item,rotorPositionArray);
|
||||
rotor3PositionAdapter.setDropDownViewResource(
|
||||
android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor3PositionView.setAdapter(rotor3PositionAdapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset()
|
||||
{
|
||||
rotor1View.setSelection(0); //I
|
||||
rotor2View.setSelection(1); //II
|
||||
rotor3View.setSelection(2); //III
|
||||
reflectorView.setSelection(0); //A
|
||||
rotor1PositionView.setSelection(0); //0
|
||||
rotor2PositionView.setSelection(0); //0
|
||||
rotor3PositionView.setSelection(0); //0
|
||||
this.ringSettings = new int[]{0,0,0};
|
||||
inputView.setText("");
|
||||
outputView.setText("");
|
||||
plugboardView.setText("");
|
||||
enigma.setConfiguration(createConfiguration());
|
||||
enigma.setPlugboard(new Plugboard());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLayout()
|
||||
{
|
||||
int[] conf = enigma.getConfiguration();
|
||||
rotor1View.setSelection(conf[0]-1);
|
||||
rotor2View.setSelection(conf[1]-1);
|
||||
rotor3View.setSelection(conf[2]-1);
|
||||
reflectorView.setSelection(conf[3]-1);
|
||||
rotor1PositionView.setSelection(conf[4]);
|
||||
rotor2PositionView.setSelection(conf[5]);
|
||||
rotor3PositionView.setSelection(conf[6]);
|
||||
ringSettings[0] = conf[7];
|
||||
ringSettings[1] = conf[8];
|
||||
ringSettings[2] = conf[9];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] createConfiguration()
|
||||
{
|
||||
int[] conf = new int[10];
|
||||
//Rotors 1..3
|
||||
conf[0] = rotor1View.getSelectedItemPosition() + 1;
|
||||
conf[1] = rotor2View.getSelectedItemPosition() + 1;
|
||||
conf[2] = rotor3View.getSelectedItemPosition() + 1;
|
||||
//Reflector
|
||||
conf[3] = reflectorView.getSelectedItemPosition() + 1;
|
||||
|
||||
conf[4] = rotor1PositionView.getSelectedItemPosition();
|
||||
conf[5] = rotor2PositionView.getSelectedItemPosition();
|
||||
conf[6] = rotor3PositionView.getSelectedItemPosition();
|
||||
|
||||
conf[7] = ringSettings[0];
|
||||
conf[8] = ringSettings[1];
|
||||
conf[9] = ringSettings[2];
|
||||
|
||||
return conf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[][] createPlugboardConfiguration() {
|
||||
return Plugboard.parseConfigurationString(plugboardView.getText().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showRingSettingsDialog()
|
||||
{
|
||||
Integer[] ringArray = new Integer[26];
|
||||
for(int i=1; i<=26; i++) {ringArray[i-1] = i;}
|
||||
View ringSettingsView = View.inflate(main, R.layout.dialog_ringsettings_i_m3, null);
|
||||
final Spinner ring1 = (Spinner) ringSettingsView.findViewById(R.id.rotor1ring);
|
||||
ArrayAdapter<Integer> ring1Adapter = new ArrayAdapter<>(main,
|
||||
android.R.layout.simple_spinner_item,ringArray);
|
||||
ring1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
ring1.setAdapter(ring1Adapter);
|
||||
ring1.setSelection(ringSettings[0]);
|
||||
|
||||
final Spinner ring2 = (Spinner) ringSettingsView.findViewById(R.id.rotor2ring);
|
||||
ArrayAdapter<Integer> ring2Adapter = new ArrayAdapter<>(main,
|
||||
android.R.layout.simple_spinner_item,ringArray);
|
||||
ring2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
ring2.setAdapter(ring2Adapter);
|
||||
ring2.setSelection(ringSettings[1]);
|
||||
|
||||
final Spinner ring3 = (Spinner) ringSettingsView.findViewById(R.id.rotor3ring);
|
||||
ArrayAdapter<Integer> ring3Adapter = new ArrayAdapter<>(main,
|
||||
android.R.layout.simple_spinner_item,ringArray);
|
||||
ring3Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
ring3.setAdapter(ring3Adapter);
|
||||
ring3.setSelection(ringSettings[2]);
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(main);
|
||||
builder.setTitle(R.string.title_ringsetting);
|
||||
builder.setView(ringSettingsView)
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(R.string.dialog_positiv, new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int id)
|
||||
{
|
||||
ringSettings[0] = ring1.getSelectedItemPosition();
|
||||
ringSettings[1] = ring2.getSelectedItemPosition();
|
||||
ringSettings[2] = ring3.getSelectedItemPosition();
|
||||
String message = main.getResources().getString(
|
||||
R.string.dialog_ringsettings_success) + " " +
|
||||
(ringSettings[2]+1) + ", " +
|
||||
(ringSettings[1]+1) + ", " +
|
||||
(ringSettings[0]+1) + ".";
|
||||
Toast.makeText(main, message, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.dialog_negativ, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
dialog.cancel();
|
||||
Toast.makeText(main, R.string.dialog_ringsettings_abort,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}).show();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
package de.vanitasvitae.enigmandroid.layout;
|
||||
|
||||
import android.widget.ArrayAdapter;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.R;
|
||||
import de.vanitasvitae.enigmandroid.enigma.Enigma_M3;
|
||||
|
||||
/**
|
||||
* Concrete LayoutContainer for the M3 layout.
|
||||
* This class contains the layout and controls the layout elements such as spinners and stuff
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* @author vanitasvitae
|
||||
*/
|
||||
public class LayoutContainer_M3 extends LayoutContainer_I
|
||||
{
|
||||
public LayoutContainer_M3()
|
||||
{
|
||||
super();
|
||||
main.setTitle("M3 - EnigmAndroid");
|
||||
this.enigma = new Enigma_M3();
|
||||
}
|
||||
|
||||
@Override
|
||||
void initialize()
|
||||
{
|
||||
Character[] rotorPositionArray = new Character[26];
|
||||
for(int i=0; i<26; i++) {rotorPositionArray[i] = (char) (65+i); /**Fill with A..Z*/}
|
||||
|
||||
ArrayAdapter<CharSequence> rotor1Adapter = ArrayAdapter.createFromResource(main, R.array.rotors_1_8,
|
||||
android.R.layout.simple_spinner_item);
|
||||
rotor1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor1View.setAdapter(rotor1Adapter);
|
||||
ArrayAdapter<CharSequence> rotor2Adapter = ArrayAdapter.createFromResource(main, R.array.rotors_1_8,
|
||||
android.R.layout.simple_spinner_item);
|
||||
rotor2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor2View.setAdapter(rotor2Adapter);
|
||||
ArrayAdapter<CharSequence> rotor3Adapter = ArrayAdapter.createFromResource(main, R.array.rotors_1_8,
|
||||
android.R.layout.simple_spinner_item);
|
||||
rotor3Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor3View.setAdapter(rotor3Adapter);
|
||||
|
||||
ArrayAdapter<CharSequence> reflectorAdapter = ArrayAdapter.createFromResource(main, R.array.reflectors_b_c,
|
||||
android.R.layout.simple_spinner_item);
|
||||
reflectorAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
reflectorView.setAdapter(reflectorAdapter);
|
||||
|
||||
ArrayAdapter<Character> rotor1PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(),
|
||||
android.R.layout.simple_spinner_item,rotorPositionArray);
|
||||
rotor1PositionAdapter.setDropDownViewResource(
|
||||
android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor1PositionView.setAdapter(rotor1PositionAdapter);
|
||||
ArrayAdapter<Character> rotor2PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(),
|
||||
android.R.layout.simple_spinner_item,rotorPositionArray);
|
||||
rotor2PositionAdapter.setDropDownViewResource(
|
||||
android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor2PositionView.setAdapter(rotor2PositionAdapter);
|
||||
ArrayAdapter<Character> rotor3PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(),
|
||||
android.R.layout.simple_spinner_item,rotorPositionArray);
|
||||
rotor3PositionAdapter.setDropDownViewResource(
|
||||
android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor3PositionView.setAdapter(rotor3PositionAdapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLayout()
|
||||
{
|
||||
int[] conf = enigma.getConfiguration();
|
||||
rotor1View.setSelection(conf[0]-1);
|
||||
rotor2View.setSelection(conf[1]-1);
|
||||
rotor3View.setSelection(conf[2]-1);
|
||||
reflectorView.setSelection(conf[3]-2); //B=2 -> 0
|
||||
rotor1PositionView.setSelection(conf[4]);
|
||||
rotor2PositionView.setSelection(conf[5]);
|
||||
rotor3PositionView.setSelection(conf[6]);
|
||||
ringSettings[0] = conf[7];
|
||||
ringSettings[1] = conf[8];
|
||||
ringSettings[2] = conf[9];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] createConfiguration()
|
||||
{
|
||||
int[] conf = new int[10];
|
||||
//Rotors 1..3
|
||||
conf[0] = rotor1View.getSelectedItemPosition() + 1;
|
||||
conf[1] = rotor2View.getSelectedItemPosition() + 1;
|
||||
conf[2] = rotor3View.getSelectedItemPosition() + 1;
|
||||
//Reflector
|
||||
conf[3] = reflectorView.getSelectedItemPosition() + 2; //M3 has no B
|
||||
|
||||
conf[4] = rotor1PositionView.getSelectedItemPosition();
|
||||
conf[5] = rotor2PositionView.getSelectedItemPosition();
|
||||
conf[6] = rotor3PositionView.getSelectedItemPosition();
|
||||
|
||||
conf[7] = ringSettings[0];
|
||||
conf[8] = ringSettings[1];
|
||||
conf[9] = ringSettings[2];
|
||||
|
||||
return conf;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,254 @@
|
|||
package de.vanitasvitae.enigmandroid.layout;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.Toast;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.R;
|
||||
import de.vanitasvitae.enigmandroid.enigma.Enigma_M4;
|
||||
import de.vanitasvitae.enigmandroid.enigma.Plugboard;
|
||||
|
||||
/**
|
||||
* Concrete LayoutContainer for the M4 layout.
|
||||
* This class contains the layout and controls the layout elements such as spinners and stuff
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* @author vanitasvitae
|
||||
*/
|
||||
public class LayoutContainer_M4 extends LayoutContainer
|
||||
{
|
||||
private Spinner rotor1View;
|
||||
private Spinner rotor2View;
|
||||
private Spinner rotor3View;
|
||||
private Spinner rotor4View;
|
||||
private Spinner reflectorView;
|
||||
private Spinner rotor1PositionView;
|
||||
private Spinner rotor2PositionView;
|
||||
private Spinner rotor3PositionView;
|
||||
private Spinner rotor4PositionView;
|
||||
|
||||
private EditText plugboardView;
|
||||
|
||||
public LayoutContainer_M4()
|
||||
{
|
||||
super();
|
||||
main.setTitle("M4 - EnigmAndroid");
|
||||
this.enigma = new Enigma_M4();
|
||||
this.ringSettings = new int[]{0,0,0,0};
|
||||
this.rotor1View = (Spinner) main.findViewById(R.id.rotor1);
|
||||
this.rotor2View = (Spinner) main.findViewById(R.id.rotor2);
|
||||
this.rotor3View = (Spinner) main.findViewById(R.id.rotor3);
|
||||
this.rotor4View = (Spinner) main.findViewById(R.id.thin_rotor);
|
||||
this.reflectorView = (Spinner) main.findViewById(R.id.reflector);
|
||||
this.rotor1PositionView = (Spinner) main.findViewById(R.id.rotor1position);
|
||||
this.rotor2PositionView = (Spinner) main.findViewById(R.id.rotor2position);
|
||||
this.rotor3PositionView = (Spinner) main.findViewById(R.id.rotor3position);
|
||||
this.rotor4PositionView = (Spinner) main.findViewById(R.id.thin_rotor_position);
|
||||
this.plugboardView = (EditText) main.findViewById(R.id.plugboard);
|
||||
this.inputView = (EditText) main.findViewById(R.id.input);
|
||||
this.outputView = (EditText) main.findViewById(R.id.output);
|
||||
|
||||
initialize();
|
||||
reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
void initialize()
|
||||
{
|
||||
Character[] rotorPositionArray = new Character[26];
|
||||
for(int i=0; i<26; i++) {rotorPositionArray[i] = (char) (65+i); /**Fill with A..Z*/}
|
||||
|
||||
ArrayAdapter<CharSequence> rotor1Adapter = ArrayAdapter.createFromResource(main, R.array.rotors_1_8,
|
||||
android.R.layout.simple_spinner_item);
|
||||
rotor1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor1View.setAdapter(rotor1Adapter);
|
||||
ArrayAdapter<CharSequence> rotor2Adapter = ArrayAdapter.createFromResource(main, R.array.rotors_1_8,
|
||||
android.R.layout.simple_spinner_item);
|
||||
rotor2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor2View.setAdapter(rotor2Adapter);
|
||||
ArrayAdapter<CharSequence> rotor3Adapter = ArrayAdapter.createFromResource(main, R.array.rotors_1_8,
|
||||
android.R.layout.simple_spinner_item);
|
||||
rotor3Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor3View.setAdapter(rotor3Adapter);
|
||||
ArrayAdapter<CharSequence> rotor4Adapter = ArrayAdapter.createFromResource(main, R.array.rotors_beta_gamma,
|
||||
android.R.layout.simple_spinner_item);
|
||||
rotor4Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor4View.setAdapter(rotor4Adapter);
|
||||
|
||||
ArrayAdapter<CharSequence> reflectorAdapter = ArrayAdapter.createFromResource(main, R.array.reflectors_b_c,
|
||||
android.R.layout.simple_spinner_item);
|
||||
reflectorAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
reflectorView.setAdapter(reflectorAdapter);
|
||||
|
||||
ArrayAdapter<Character> rotor1PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(),
|
||||
android.R.layout.simple_spinner_item,rotorPositionArray);
|
||||
rotor1PositionAdapter.setDropDownViewResource(
|
||||
android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor1PositionView.setAdapter(rotor1PositionAdapter);
|
||||
ArrayAdapter<Character> rotor2PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(),
|
||||
android.R.layout.simple_spinner_item,rotorPositionArray);
|
||||
rotor2PositionAdapter.setDropDownViewResource(
|
||||
android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor2PositionView.setAdapter(rotor2PositionAdapter);
|
||||
ArrayAdapter<Character> rotor3PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(),
|
||||
android.R.layout.simple_spinner_item,rotorPositionArray);
|
||||
rotor3PositionAdapter.setDropDownViewResource(
|
||||
android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor3PositionView.setAdapter(rotor3PositionAdapter);
|
||||
ArrayAdapter<Character> rotor4PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(),
|
||||
android.R.layout.simple_spinner_item,rotorPositionArray);
|
||||
rotor4PositionAdapter.setDropDownViewResource(
|
||||
android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor4PositionView.setAdapter(rotor4PositionAdapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset()
|
||||
{
|
||||
rotor1View.setSelection(0); //I
|
||||
rotor2View.setSelection(1); //II
|
||||
rotor3View.setSelection(2); //III
|
||||
rotor4View.setSelection(0); //Beta
|
||||
reflectorView.setSelection(0); //B
|
||||
rotor1PositionView.setSelection(0); //0
|
||||
rotor2PositionView.setSelection(0); //0
|
||||
rotor3PositionView.setSelection(0); //0
|
||||
rotor4PositionView.setSelection(0); //0
|
||||
ringSettings = new int[]{0,0,0,0};
|
||||
inputView.setText("");
|
||||
outputView.setText("");
|
||||
plugboardView.setText("");
|
||||
enigma.setConfiguration(createConfiguration());
|
||||
enigma.setPlugboard(new Plugboard());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLayout()
|
||||
{
|
||||
int[] conf = enigma.getConfiguration();
|
||||
rotor1View.setSelection(conf[0]-1);
|
||||
rotor2View.setSelection(conf[1]-1);
|
||||
rotor3View.setSelection(conf[2]-1);
|
||||
rotor4View.setSelection(conf[3]-9);
|
||||
reflectorView.setSelection(conf[4]-4);
|
||||
rotor1PositionView.setSelection(conf[5]);
|
||||
rotor2PositionView.setSelection(conf[6]);
|
||||
rotor3PositionView.setSelection(conf[7]);
|
||||
rotor4PositionView.setSelection(conf[8]);
|
||||
ringSettings[0] = conf[9];
|
||||
ringSettings[1] = conf[10];
|
||||
ringSettings[2] = conf[11];
|
||||
ringSettings[3] = conf[12];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] createConfiguration()
|
||||
{
|
||||
int[] conf = new int[13];
|
||||
//Rotors 1..4
|
||||
conf[0] = rotor1View.getSelectedItemPosition() + 1;
|
||||
conf[1] = rotor2View.getSelectedItemPosition() + 1;
|
||||
conf[2] = rotor3View.getSelectedItemPosition() + 1;
|
||||
conf[3] = rotor4View.getSelectedItemPosition() + 9; //Beta is rotor #9
|
||||
//Reflector
|
||||
conf[4] = reflectorView.getSelectedItemPosition() + 4; //thinB is reflector #4
|
||||
|
||||
conf[5] = rotor1PositionView.getSelectedItemPosition();
|
||||
conf[6] = rotor2PositionView.getSelectedItemPosition();
|
||||
conf[7] = rotor3PositionView.getSelectedItemPosition();
|
||||
conf[8] = rotor4PositionView.getSelectedItemPosition();
|
||||
|
||||
conf[9] = ringSettings[0];
|
||||
conf[10] = ringSettings[1];
|
||||
conf[11] = ringSettings[2];
|
||||
conf[12] = ringSettings[3];
|
||||
|
||||
return conf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[][] createPlugboardConfiguration() {
|
||||
return Plugboard.parseConfigurationString(plugboardView.getText().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showRingSettingsDialog()
|
||||
{
|
||||
Integer[] ringArray = new Integer[26];
|
||||
for(int i=1; i<=26; i++) {ringArray[i-1] = i;}
|
||||
View ringSettingsView = View.inflate(main, R.layout.dialog_ringsettings_m4, null);
|
||||
final Spinner ring1 = (Spinner) ringSettingsView.findViewById(R.id.rotor1ring);
|
||||
ArrayAdapter<Integer> ring1Adapter = new ArrayAdapter<>(main,
|
||||
android.R.layout.simple_spinner_item,ringArray);
|
||||
ring1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
ring1.setAdapter(ring1Adapter);
|
||||
ring1.setSelection(ringSettings[0]);
|
||||
|
||||
final Spinner ring2 = (Spinner) ringSettingsView.findViewById(R.id.rotor2ring);
|
||||
ArrayAdapter<Integer> ring2Adapter = new ArrayAdapter<>(main,
|
||||
android.R.layout.simple_spinner_item,ringArray);
|
||||
ring2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
ring2.setAdapter(ring2Adapter);
|
||||
ring2.setSelection(ringSettings[1]);
|
||||
|
||||
final Spinner ring3 = (Spinner) ringSettingsView.findViewById(R.id.rotor3ring);
|
||||
ArrayAdapter<Integer> ring3Adapter = new ArrayAdapter<>(main,
|
||||
android.R.layout.simple_spinner_item,ringArray);
|
||||
ring3Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
ring3.setAdapter(ring3Adapter);
|
||||
ring3.setSelection(ringSettings[2]);
|
||||
|
||||
final Spinner ring4 = (Spinner) ringSettingsView.findViewById(R.id.rotor4ring);
|
||||
ArrayAdapter<Integer> ring4Adapter = new ArrayAdapter<>(main,
|
||||
android.R.layout.simple_spinner_item, ringArray);
|
||||
ring4Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
ring4.setAdapter(ring4Adapter);
|
||||
ring4.setSelection(ringSettings[3]);
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(main);
|
||||
builder.setTitle(R.string.title_ringsetting);
|
||||
builder.setView(ringSettingsView)
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(R.string.dialog_positiv, new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int id)
|
||||
{
|
||||
ringSettings[0] = ring1.getSelectedItemPosition();
|
||||
ringSettings[1] = ring2.getSelectedItemPosition();
|
||||
ringSettings[2] = ring3.getSelectedItemPosition();
|
||||
ringSettings[3] = ring4.getSelectedItemPosition();
|
||||
String message = main.getResources().getString(
|
||||
R.string.dialog_ringsettings_success) + " " +
|
||||
(ringSettings[3]+1) + ", " +
|
||||
(ringSettings[2]+1) + ", " +
|
||||
(ringSettings[1]+1) + ", " +
|
||||
(ringSettings[0]+1) + ".";
|
||||
Toast.makeText(main, message, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.dialog_negativ, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
dialog.cancel();
|
||||
Toast.makeText(main, R.string.dialog_ringsettings_abort,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}).show();
|
||||
}
|
||||
}
|
202
app/src/main/res/layout-land/activity_main_m4.xml
Executable file
202
app/src/main/res/layout-land/activity_main_m4.xml
Executable file
|
@ -0,0 +1,202 @@
|
|||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<!-- Hints of the spinners-->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:id="@+id/lin_lay_names_1">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_reflector"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_thin_rotor"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor3"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor2"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor1"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_thin_rotor_position"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor3_position"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor2_position"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor1_position"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Spinners -->
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:id="@+id/lin_lay_1"
|
||||
android:layout_below="@+id/lin_lay_names_1">
|
||||
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/reflector">
|
||||
</Spinner>
|
||||
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/thin_rotor"/>
|
||||
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor3">
|
||||
</Spinner>
|
||||
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor2">
|
||||
</Spinner>
|
||||
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor1">
|
||||
</Spinner>
|
||||
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/thin_rotor_position">
|
||||
</Spinner>
|
||||
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor3position">
|
||||
</Spinner>
|
||||
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor2position">
|
||||
</Spinner>
|
||||
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor1position">
|
||||
</Spinner>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Plugboard and button-->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/buttons_lay"
|
||||
android:layout_below="@+id/lin_lay_1"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<EditText
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="75"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/plugboard"
|
||||
android:hint="@string/hint_enigma_plugboard">
|
||||
|
||||
</EditText>
|
||||
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="25"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/button_crypt"
|
||||
android:onClick="doCrypto"
|
||||
android:text="@string/button_crypt"
|
||||
android:background="@drawable/button"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Textboxes for input and output -->
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/buttons_lay"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:id="@+id/text_layer">
|
||||
|
||||
<EditText
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".50"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/input"
|
||||
android:hint="@string/hint_enigma_type_here" />
|
||||
|
||||
<EditText
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".50"
|
||||
android:layout_height="match_parent"
|
||||
android:inputType="none"
|
||||
android:textIsSelectable="true"
|
||||
android:id="@+id/output"
|
||||
android:hint="@string/hint_enigma_code"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
|
@ -159,7 +159,7 @@
|
|||
android:layout_weight=".50"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/input"
|
||||
android:inputType="textNoSuggestions"
|
||||
android:inputType="textNoSuggestions|textMultiLine"
|
||||
android:hint="@string/hint_enigma_type_here" />
|
||||
|
||||
<EditText
|
196
app/src/main/res/layout/activity_main_m4.xml
Executable file
196
app/src/main/res/layout/activity_main_m4.xml
Executable file
|
@ -0,0 +1,196 @@
|
|||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:id="@+id/lin_lay_names_1">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".20"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_reflector"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".20"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_thin_rotor"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".20"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor3"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".20"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor2"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".20"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor1"/>
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:id="@+id/lin_lay_1"
|
||||
android:layout_below="@+id/lin_lay_names_1">
|
||||
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".20"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/reflector">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".20"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/thin_rotor">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".20"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor3">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".20"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor2">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".20"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor1">
|
||||
</Spinner>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_below="@+id/lin_lay_1"
|
||||
android:id="@+id/lin_lay_names_2">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".25"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_thin_rotor_position"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".25"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor3_position"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".25"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor2_position"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".25"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor1_position"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:id="@+id/lin_lay_2"
|
||||
android:layout_below="@+id/lin_lay_names_2">
|
||||
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".25"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/thin_rotor_position">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".25"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor3position">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".25"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor2position">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".25"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor1position">
|
||||
</Spinner>
|
||||
</LinearLayout>
|
||||
|
||||
<EditText
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="30pt"
|
||||
android:id="@+id/plugboard"
|
||||
android:inputType="textNoSuggestions"
|
||||
android:hint="@string/hint_enigma_plugboard"
|
||||
android:layout_below="@+id/lin_lay_2"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/plugboard"
|
||||
android:layout_above="@+id/buttons_lay"
|
||||
android:id="@+id/text_layer">
|
||||
<EditText
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".50"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/input"
|
||||
android:inputType="textNoSuggestions|textMultiLine"
|
||||
android:hint="@string/hint_enigma_type_here" />
|
||||
|
||||
<EditText
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".50"
|
||||
android:layout_height="match_parent"
|
||||
android:inputType="none"
|
||||
android:textIsSelectable="true"
|
||||
android:id="@+id/output"
|
||||
android:hint="@string/hint_enigma_code"/>
|
||||
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/buttons_lay"
|
||||
android:layout_alignParentBottom="true">
|
||||
<Button
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/button_crypt"
|
||||
android:onClick="doCrypto"
|
||||
android:text="@string/button_crypt"
|
||||
android:background="@drawable/button"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
67
app/src/main/res/layout/dialog_ringsettings_m4.xml
Executable file
67
app/src/main/res/layout/dialog_ringsettings_m4.xml
Executable file
|
@ -0,0 +1,67 @@
|
|||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/ringsettings_layout_hint">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="25"
|
||||
android:text="@string/hint_thin_rotor"
|
||||
android:layout_height="wrap_content"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="25"
|
||||
android:text="@string/hint_rotor3"
|
||||
android:layout_height="wrap_content"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="25"
|
||||
android:text="@string/hint_rotor2"
|
||||
android:layout_height="wrap_content"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="25"
|
||||
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/ringsettings_layout_hint"
|
||||
android:id="@+id/ringsettings_layout">
|
||||
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="25"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor4ring">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="25"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor3ring">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="25"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor2ring">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="25"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor1ring">
|
||||
</Spinner>
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
|
@ -11,14 +11,16 @@
|
|||
<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_plugboard">Steckerbrett (AZ,BE...)</string>
|
||||
<string name="hint_enigma_plugboard">Steckerbrett (AZ,BE…)</string>
|
||||
<string name="hint_rotor1">Walze 1</string>
|
||||
<string name="hint_rotor2">Walze 2</string>
|
||||
<string name="hint_rotor3">Walze 3</string>
|
||||
<string name="hint_thin_rotor">Walze 4</string>
|
||||
<string name="hint_reflector">Umkehr-\nWalze</string>
|
||||
<string name="hint_rotor1_position">Position\nWalze 1</string>
|
||||
<string name="hint_rotor2_position">Position\nWalze 2</string>
|
||||
<string name="hint_rotor3_position">Position\nWalze 3</string>
|
||||
<string name="hint_thin_rotor_position">Position\nWalze 4</string>
|
||||
<string name="button_crypt">Ver-/Entschlüsseln</string>
|
||||
<string name="error_parsing_plugs">Fehler: Fehlerhafte Steckerbrettkonfiguration.</string>
|
||||
<string name="error_unable_to_plug_a_b">Kann Stecker nicht setzen: </string>
|
||||
|
@ -31,18 +33,4 @@
|
|||
<string name="dialog_ringsettings_abort">Keine Änderungen</string>
|
||||
<string name="message_reset">Enigma zurückgesetzt</string>
|
||||
|
||||
<string-array name="enigma_rotors">
|
||||
<item>I</item>
|
||||
<item>II</item>
|
||||
<item>III</item>
|
||||
<item>IV</item>
|
||||
<item>V</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="enigma_reflectors">
|
||||
<item>A</item>
|
||||
<item>B</item>
|
||||
<item>C</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -4,13 +4,24 @@
|
|||
|
||||
<string name="pref_header_simulation">Simulation</string>
|
||||
|
||||
<string name="pref_title_machine_type">Enigma Modell</string>
|
||||
<string name="pref_description_machine_type">Welches Modell soll simuliert werden?</string>
|
||||
<string-array translatable="false" name="pref_list_machine_type">
|
||||
<item>I</item>
|
||||
<item>M3</item>
|
||||
<item>M4</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_title_simulate_anomaly">Doppelschritt Anomalie</string>
|
||||
<string name="pref_description_simulate_anomaly">Die Doppelschritt Anomalie lässt die mittlere Walze zweimal rotieren, falls sie sich vor dem Übertragspunkt befindet.
|
||||
<string name="pref_description_simulate_anomaly">Die Doppelschritt Anomalie lässt die mittlere Walze zweimal rotieren,
|
||||
falls sie sich vor dem Übertragspunkt befindet.
|
||||
</string>
|
||||
|
||||
<string name="pref_title_numeric_spelling_language">Zahlenbuchstabiersprache</string>
|
||||
<string name="pref_description_numeric_spelling_language">Sprache in der Zahlen buchstabiert werden sollen.</string>
|
||||
<string-array name="pref_list_numeric_spelling_language">
|
||||
<item>Deutsch</item>
|
||||
<item>Französisch</item>
|
||||
<item>Englisch</item>
|
||||
</string-array>
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<string name="version" translatable="false">0.1.4-15.08.2015</string>
|
||||
<string name="version" translatable="false">0.1.5-27.08.2015</string>
|
||||
<string name="app_name">EnigmAndroid</string>
|
||||
<string name="action_version">Version</string>
|
||||
<string name="action_reset">Reset</string>
|
||||
|
@ -16,10 +16,12 @@
|
|||
<string name="hint_rotor1">Rotor 1</string>
|
||||
<string name="hint_rotor2">Rotor 2</string>
|
||||
<string name="hint_rotor3">Rotor 3</string>
|
||||
<string name="hint_thin_rotor">Rotor 4</string>
|
||||
<string name="hint_reflector">Reflector</string>
|
||||
<string name="hint_rotor1_position">Position\nRotor 1</string>
|
||||
<string name="hint_rotor2_position">Position\nRotor 2</string>
|
||||
<string name="hint_rotor3_position">Position\nRotor 3</string>
|
||||
<string name="hint_thin_rotor_position">Position\nRotor 4</string>
|
||||
<string name="button_crypt">En-/Decrypt!</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>
|
||||
|
@ -32,16 +34,35 @@
|
|||
<string name="dialog_ringsettings_abort">No changes</string>
|
||||
<string name="message_reset">Enigma reset</string>
|
||||
|
||||
<string-array name="enigma_rotors">
|
||||
<string-array translatable="false" name="rotors_1_5">
|
||||
<item>I</item>
|
||||
<item>II</item>
|
||||
<item>III</item>
|
||||
<item>IV</item>
|
||||
<item>V</item>
|
||||
</string-array>
|
||||
<string-array name="enigma_reflectors">
|
||||
<string-array translatable="false" name="rotors_1_8">
|
||||
<item>I</item>
|
||||
<item>II</item>
|
||||
<item>III</item>
|
||||
<item>IV</item>
|
||||
<item>V</item>
|
||||
<item>VI</item>
|
||||
<item>VII</item>
|
||||
<item>VIII</item>
|
||||
</string-array>
|
||||
<string-array translatable="false" name="reflectors_a_c">
|
||||
<item>A</item>
|
||||
<item>B</item>
|
||||
<item>C</item>
|
||||
</string-array>
|
||||
<string-array translatable="false" name="reflectors_b_c">
|
||||
<item>B</item>
|
||||
<item>C</item>
|
||||
</string-array>
|
||||
<string-array translatable="false" name="rotors_beta_gamma">
|
||||
<item>\u03B2</item>
|
||||
<item>\u03B3</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -4,18 +4,30 @@
|
|||
|
||||
<string name="pref_header_simulation">Simulation</string>
|
||||
|
||||
<string name="pref_title_machine_type">Enigma Model</string>
|
||||
<string name="pref_description_machine_type">Which model do you want to simulate?</string>
|
||||
<string-array translatable="false" name="pref_list_machine_type">
|
||||
<item>I</item>
|
||||
<item>M3</item>
|
||||
<item>M4</item>
|
||||
</string-array>
|
||||
|
||||
<string name="pref_title_simulate_anomaly">Simulate Anomaly</string>
|
||||
<string name="pref_description_simulate_anomaly">The double step anomaly causes the middle rotor
|
||||
to rotate twice, if it is one step before its turnover point.
|
||||
</string>
|
||||
|
||||
<string name="pref_title_numeric_spelling_language">Number spelling language</string>
|
||||
<string name="pref_description_numeric_spelling_language">Language, in which numbers are spelled.</string>
|
||||
<string-array name="pref_list_numeric_spelling_language">
|
||||
<item>German</item>
|
||||
<item>French</item>
|
||||
<item>English</item>
|
||||
</string-array>
|
||||
|
||||
<string-array translatable="false" name="pref_alias_numeric_spelling_language">
|
||||
<item>de</item>
|
||||
<item>fr</item>
|
||||
<item>en</item>
|
||||
</string-array>
|
||||
|
||||
|
|
|
@ -2,6 +2,13 @@
|
|||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<PreferenceCategory android:title="@string/pref_header_simulation">
|
||||
<ListPreference
|
||||
android:key="prefMachineType"
|
||||
android:title="@string/pref_title_machine_type"
|
||||
android:summary="@string/pref_description_machine_type"
|
||||
android:entries="@array/pref_list_machine_type"
|
||||
android:entryValues="@array/pref_list_machine_type"
|
||||
android:defaultValue="Enigma I"/>
|
||||
<CheckBoxPreference
|
||||
android:key="prefAnomaly"
|
||||
android:title="@string/pref_title_simulate_anomaly"
|
||||
|
|
Loading…
Reference in a new issue