mirror of
https://github.com/vanitasvitae/EnigmAndroid.git
synced 2024-11-24 13:22:07 +01:00
Added missing license headers, extended documentation, extended input interpretation and added numeric spelling in different languages (TODO: improve implementation, this is experimental)
This commit is contained in:
parent
980b7e8c7d
commit
2e405429cf
29 changed files with 563 additions and 303 deletions
|
@ -1 +0,0 @@
|
||||||
EnigmAndroid
|
|
|
@ -1,23 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="CompilerConfiguration">
|
|
||||||
<option name="DEFAULT_COMPILER" value="Javac" />
|
|
||||||
<resourceExtensions />
|
|
||||||
<wildcardResourcePatterns>
|
|
||||||
<entry name="!?*.java" />
|
|
||||||
<entry name="!?*.form" />
|
|
||||||
<entry name="!?*.class" />
|
|
||||||
<entry name="!?*.groovy" />
|
|
||||||
<entry name="!?*.scala" />
|
|
||||||
<entry name="!?*.flex" />
|
|
||||||
<entry name="!?*.kt" />
|
|
||||||
<entry name="!?*.clj" />
|
|
||||||
</wildcardResourcePatterns>
|
|
||||||
<annotationProcessing>
|
|
||||||
<profile default="true" name="Default" enabled="false">
|
|
||||||
<processorPath useClasspath="true" />
|
|
||||||
</profile>
|
|
||||||
</annotationProcessing>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
<component name="CopyrightManager">
|
|
||||||
<settings default="" />
|
|
||||||
</component>
|
|
|
@ -1,9 +0,0 @@
|
||||||
<component name="ProjectDictionaryState">
|
|
||||||
<dictionary name="vanitas">
|
|
||||||
<words>
|
|
||||||
<w>plugboard</w>
|
|
||||||
<w>ringsetting</w>
|
|
||||||
<w>ringsettings</w>
|
|
||||||
</words>
|
|
||||||
</dictionary>
|
|
||||||
</component>
|
|
|
@ -1,5 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
|
|
||||||
</project>
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="GradleSettings">
|
|
||||||
<option name="linkedExternalProjectsSettings">
|
|
||||||
<GradleProjectSettings>
|
|
||||||
<option name="distributionType" value="LOCAL" />
|
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
|
||||||
<option name="gradleHome" value="$APPLICATION_HOME_DIR$/gradle/gradle-2.2.1" />
|
|
||||||
<option name="modules">
|
|
||||||
<set>
|
|
||||||
<option value="$PROJECT_DIR$" />
|
|
||||||
<option value="$PROJECT_DIR$/app" />
|
|
||||||
</set>
|
|
||||||
</option>
|
|
||||||
</GradleProjectSettings>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
<component name="libraryTable">
|
|
||||||
<library name="support-annotations-21.0.3">
|
|
||||||
<CLASSES>
|
|
||||||
<root url="jar:///media/Daten/AndroidSDK/android-sdk-linux/extras/android/m2repository/com/android/support/support-annotations/21.0.3/support-annotations-21.0.3.jar!/" />
|
|
||||||
</CLASSES>
|
|
||||||
<JAVADOC />
|
|
||||||
<SOURCES>
|
|
||||||
<root url="jar:///media/Daten/AndroidSDK/android-sdk-linux/extras/android/m2repository/com/android/support/support-annotations/21.0.3/support-annotations-21.0.3-sources.jar!/" />
|
|
||||||
</SOURCES>
|
|
||||||
</library>
|
|
||||||
</component>
|
|
|
@ -1,13 +0,0 @@
|
||||||
<component name="libraryTable">
|
|
||||||
<library name="support-v4-21.0.3">
|
|
||||||
<CLASSES>
|
|
||||||
<root url="jar://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/support-v4/21.0.3/libs/internal_impl-21.0.3.jar!/" />
|
|
||||||
<root url="jar://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/support-v4/21.0.3/classes.jar!/" />
|
|
||||||
<root url="file://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/support-v4/21.0.3/res" />
|
|
||||||
</CLASSES>
|
|
||||||
<JAVADOC />
|
|
||||||
<SOURCES>
|
|
||||||
<root url="jar:///media/Daten/AndroidSDK/android-sdk-linux/extras/android/m2repository/com/android/support/support-v4/21.0.3/support-v4-21.0.3-sources.jar!/" />
|
|
||||||
</SOURCES>
|
|
||||||
</library>
|
|
||||||
</component>
|
|
|
@ -1,26 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="EntryPointsManager">
|
|
||||||
<entry_points version="2.0" />
|
|
||||||
</component>
|
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
|
||||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
|
||||||
</component>
|
|
||||||
<component name="masterDetails">
|
|
||||||
<states>
|
|
||||||
<state key="ProjectJDKs.UI">
|
|
||||||
<settings>
|
|
||||||
<last-edited>Android API 19 Platform</last-edited>
|
|
||||||
<splitter-proportions>
|
|
||||||
<option name="proportions">
|
|
||||||
<list>
|
|
||||||
<option value="0.2" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
</splitter-proportions>
|
|
||||||
</settings>
|
|
||||||
</state>
|
|
||||||
</states>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectModuleManager">
|
|
||||||
<modules>
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/EnigmAndroid.iml" filepath="$PROJECT_DIR$/EnigmAndroid.iml" />
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
|
|
||||||
</modules>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
<component name="DependencyValidationManager">
|
|
||||||
<state>
|
|
||||||
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
|
|
||||||
</state>
|
|
||||||
</component>
|
|
|
@ -1,8 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="VcsDirectoryMappings">
|
|
||||||
<mapping directory="" vcs="Git" />
|
|
||||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
|
|
|
@ -1,12 +1,18 @@
|
||||||
CHANGELOG ENIGMANDROID
|
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'
|
||||||
|
|
||||||
|
|
||||||
v0.1.4-15.08.2015<
|
v0.1.4-15.08.2015<
|
||||||
*Rewrite of the core implementation to follow some principals of Software Engineering
|
*Rewrite of the core implementation to follow some principals of Software Engineering
|
||||||
*Fixed some layout issues
|
*Fixed some layout issues
|
||||||
*Fixed anomaly for step by step inputs
|
*Fixed anomaly for step by step inputs
|
||||||
*Added send/receive text functionality
|
*Added send/receive text functionality
|
||||||
|
|
||||||
|
|
||||||
v0.1.3-14.03.2015<
|
v0.1.3-14.03.2015<
|
||||||
*Added About Dialog with ChangeLog-Button
|
*Added About Dialog with ChangeLog-Button
|
||||||
*Moved Version Info into About Dialog
|
*Moved Version Info into About Dialog
|
||||||
|
|
1
app/.gitignore
vendored
1
app/.gitignore
vendored
|
@ -1 +0,0 @@
|
||||||
/build
|
|
Binary file not shown.
12
app/build.gradle
Normal file → Executable file
12
app/build.gradle
Normal file → Executable file
|
@ -1,15 +1,15 @@
|
||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 21
|
compileSdkVersion 22
|
||||||
buildToolsVersion "20.0.0"
|
buildToolsVersion "22.0.1"
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "de.vanitasvitae.enigmandroid"
|
applicationId "de.vanitasvitae.enigmandroid"
|
||||||
minSdkVersion 15
|
minSdkVersion 15
|
||||||
targetSdkVersion 21
|
targetSdkVersion 22
|
||||||
versionCode 9
|
versionCode 10
|
||||||
versionName "0.1.3-14.03.2015-beta"
|
versionName "0.1.4-15.08.2015-beta"
|
||||||
}
|
}
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
|
@ -19,5 +19,5 @@ android {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
compile 'com.android.support:support-v4:21.+'
|
compile 'com.android.support:support-v4:22.2.1'
|
||||||
}
|
}
|
||||||
|
|
0
app/proguard-rules.pro
vendored
Normal file → Executable file
0
app/proguard-rules.pro
vendored
Normal file → Executable file
5
app/src/main/AndroidManifest.xml
Normal file → Executable file
5
app/src/main/AndroidManifest.xml
Normal file → Executable file
|
@ -15,6 +15,11 @@
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.SEND" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
<data android:mimeType="text/plain" />
|
||||||
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".SettingsActivity"
|
android:name=".SettingsActivity"
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
package de.vanitasvitae.enigmandroid;
|
package de.vanitasvitae.enigmandroid;
|
||||||
|
|
||||||
|
|
||||||
import de.vanitasvitae.enigmandroid.rotors.Reflector;
|
import de.vanitasvitae.enigmandroid.rotors.Reflector;
|
||||||
import de.vanitasvitae.enigmandroid.rotors.Rotor;
|
import de.vanitasvitae.enigmandroid.rotors.Rotor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enigma-machine
|
* Main component of the Enigma machine
|
||||||
*Copyright (C) 2015 Paul Schaub
|
* Copyright (C) 2015 Paul Schaub
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -35,13 +34,14 @@ public class Enigma
|
||||||
//Slot for the reflector
|
//Slot for the reflector
|
||||||
private Reflector reflector;
|
private Reflector reflector;
|
||||||
|
|
||||||
private boolean doAnomaly = false;
|
private boolean doAnomaly = false; //Has the time come to handle an anomaly?
|
||||||
|
|
||||||
private boolean prefAnomaly; //Do you want to simulate the anomaly?
|
private boolean prefAnomaly; //Do you WANT to simulate the anomaly?
|
||||||
|
private InputPreparator inputPreparator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create new Enigma with standard configuration.
|
* Create new Enigma with standard configuration.
|
||||||
* Empty Plugboard, rotors I,II,III, Positions 0,0,0
|
* Empty Plugboard, reflector B, rotors I,II,III, Positions 0,0,0
|
||||||
*/
|
*/
|
||||||
public Enigma()
|
public Enigma()
|
||||||
{
|
{
|
||||||
|
@ -55,11 +55,14 @@ public class Enigma
|
||||||
this.r3 = Rotor.createRotorIII(0, 0);
|
this.r3 = Rotor.createRotorIII(0, 0);
|
||||||
this.reflector = Reflector.createReflectorB();
|
this.reflector = Reflector.createReflectorB();
|
||||||
plugboard = new Plugboard();
|
plugboard = new Plugboard();
|
||||||
prefAnomaly = true;
|
prefAnomaly = true; //TODO: Is this necessary?
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encrypt / Decrypt a given String
|
* Encrypt / Decrypt a given String w.
|
||||||
|
* w must be prepared using prepare(w) beforehand.
|
||||||
|
* Doing so changes the state of the rotors but not the state of the plugboard and the
|
||||||
|
* ringSettings
|
||||||
*
|
*
|
||||||
* @param w Text to decrypt/encrypt
|
* @param w Text to decrypt/encrypt
|
||||||
* @return encrypted/decrypted string
|
* @return encrypted/decrypted string
|
||||||
|
@ -78,28 +81,30 @@ public class Enigma
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform crypto on char.
|
* Substitute char k by sending the signal through the enigma.
|
||||||
* Beforehand rotate rotors. Also implement the rotor anomaly.
|
* 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
|
* @param k input char
|
||||||
* @return output char
|
* @return substituted output char
|
||||||
*/
|
*/
|
||||||
public char encryptChar(char k)
|
public char encryptChar(char k)
|
||||||
{
|
{
|
||||||
//Rotate rotors
|
//Rotate rotors
|
||||||
r1.rotate();
|
r1.rotate();
|
||||||
|
//Eventually turn next rotor (usual turnOver or anomaly)
|
||||||
if (r1.isAtTurnoverPosition() || (this.doAnomaly && prefAnomaly))
|
if (r1.isAtTurnoverPosition() || (this.doAnomaly && prefAnomaly))
|
||||||
{
|
{
|
||||||
r2.rotate();
|
r2.rotate();
|
||||||
//Handle Anomaly
|
//Set doAnomaly for next call of encryptChar
|
||||||
this.doAnomaly = r2.doubleTurnAnomaly();
|
this.doAnomaly = r2.doubleTurnAnomaly();
|
||||||
|
//Eventually rotate next rotor
|
||||||
if (r2.isAtTurnoverPosition())
|
if (r2.isAtTurnoverPosition())
|
||||||
{
|
{
|
||||||
r3.rotate();
|
r3.rotate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int x = (int) k;
|
int x = ((int) k)-65; //Cast to int and remove Unicode Offset (A=65 in Unicode.)
|
||||||
x = x - 65; //Remove Unicode Offset (A=65 in Unicode.)
|
|
||||||
|
|
||||||
//Encryption
|
//Encryption
|
||||||
//forward direction
|
//forward direction
|
||||||
|
@ -122,43 +127,21 @@ public class Enigma
|
||||||
x = normalize(x - r1.getRotation());
|
x = normalize(x - r1.getRotation());
|
||||||
x = plugboard.encrypt(x);
|
x = plugboard.encrypt(x);
|
||||||
|
|
||||||
return (char) (x + 65); //Add Offset
|
return (char) (x + 65); //Add Offset again and cast back to char
|
||||||
}
|
|
||||||
|
|
||||||
public int normalize(int input)
|
|
||||||
{
|
|
||||||
return (26+input)%26;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare String for encryption via enigma
|
* Normalize the input.
|
||||||
* Replace . , ! ? : with X
|
* Normalizing means keeping the input via modulo in the range from 0 to n-1, where n is equal
|
||||||
* Remove all other chars that are not A..Z
|
* to the size of the rotors (in this case fixed to 26, TODO?).
|
||||||
*
|
* This is necessary since java allows negative modulo values,
|
||||||
* @param word string
|
* which can break this implementation
|
||||||
* @return prepared string
|
* @param input input signal
|
||||||
|
* @return "normalized" input signal
|
||||||
*/
|
*/
|
||||||
public static String prepare(String word)
|
public int normalize(int input)
|
||||||
{
|
{
|
||||||
String input = word.toUpperCase();
|
return (26+input)%26;
|
||||||
String output = "";
|
|
||||||
for (char x : input.toCharArray())
|
|
||||||
{
|
|
||||||
if (x >= 65 && x <= 90) //If x in [A..Z]
|
|
||||||
{
|
|
||||||
output = output + x; //Append to String
|
|
||||||
}
|
|
||||||
//if x is special symbol
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (x == '.' || x == ',' || x == '!' || x == '?' || x == ':')
|
|
||||||
{
|
|
||||||
//replace x with X and encrypt
|
|
||||||
output = output + 'X';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return output;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -198,6 +181,10 @@ public class Enigma
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the plugboard
|
||||||
|
* @param p Plugboard
|
||||||
|
*/
|
||||||
public void setPlugboard(Plugboard p)
|
public void setPlugboard(Plugboard p)
|
||||||
{
|
{
|
||||||
this.plugboard = p;
|
this.plugboard = p;
|
||||||
|
@ -226,6 +213,28 @@ public class Enigma
|
||||||
return configuration;
|
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)
|
public void setPrefAnomaly(boolean b)
|
||||||
{
|
{
|
||||||
this.prefAnomaly = b;
|
this.prefAnomaly = b;
|
||||||
|
|
|
@ -0,0 +1,123 @@
|
||||||
|
package de.vanitasvitae.enigmandroid;
|
||||||
|
|
||||||
|
import java.text.Normalizer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Preparator 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
|
||||||
|
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 InputPreparator
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Prepare the input String in a way that it only contains letters from [A..Z].
|
||||||
|
* Replace special characters and spell numbers.
|
||||||
|
* @param input String
|
||||||
|
* @return prepared String
|
||||||
|
*/
|
||||||
|
public String prepareString(String input)
|
||||||
|
{
|
||||||
|
input = input.toUpperCase();
|
||||||
|
input = input.replace("Ä","AE").replace("Ö","OE").replace("Ü","UE").replace("ß","SS");
|
||||||
|
String output = "";
|
||||||
|
|
||||||
|
for (char x : input.toCharArray())
|
||||||
|
{
|
||||||
|
if (x >= 65 && x <= 90) //x in [A..Z]
|
||||||
|
{
|
||||||
|
output = output + x;
|
||||||
|
}
|
||||||
|
else if (x >= 48 && x <= 57) //x in [0..9]
|
||||||
|
{
|
||||||
|
output = output + replaceNumber(x);
|
||||||
|
}
|
||||||
|
//x is special symbol
|
||||||
|
else
|
||||||
|
{
|
||||||
|
output = output + 'X';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract method that spells numbers in a certain language specified by the implementation
|
||||||
|
* @param input character
|
||||||
|
* @return spelled number
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
public static InputPreparator createInputPreparator(String language)
|
||||||
|
{
|
||||||
|
switch (language)
|
||||||
|
{
|
||||||
|
case "de": return new InputPreparatorGerman();
|
||||||
|
default: return new InputPreparatorEnglish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Concrete implementation of a german InputPreparator
|
||||||
|
*/
|
||||||
|
class InputPreparatorGerman extends InputPreparator
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public String replaceNumber(char input) {
|
||||||
|
switch (input)
|
||||||
|
{
|
||||||
|
case '0': return "NULL";
|
||||||
|
case '1': return "EINS";
|
||||||
|
case '2': return "ZWEI";
|
||||||
|
case '3': return "DREI";
|
||||||
|
case '4': return "VIER";
|
||||||
|
case '5': return "FUENF";
|
||||||
|
case '6': return "SECHS";
|
||||||
|
case '7': return "SIEBEN";
|
||||||
|
case '8': return "ACHT";
|
||||||
|
default: return "NEUN";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Concrete implementation of an english InputPreparator
|
||||||
|
*/
|
||||||
|
class InputPreparatorEnglish extends InputPreparator
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public String replaceNumber(char input)
|
||||||
|
{
|
||||||
|
switch (input) {
|
||||||
|
case '0': return "ZERO";
|
||||||
|
case '1': return "ONE";
|
||||||
|
case '2': return "TWO";
|
||||||
|
case '3': return "THREE";
|
||||||
|
case '4': return "FOUR";
|
||||||
|
case '5': return "FIVE";
|
||||||
|
case '6': return "SIX";
|
||||||
|
case '7': return "SEVEN";
|
||||||
|
case '8': return "EIGHT";
|
||||||
|
default: return "NINE";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,21 +1,3 @@
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.vanitasvitae.enigmandroid;
|
package de.vanitasvitae.enigmandroid;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
@ -33,21 +15,38 @@ import android.widget.EditText;
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
/**
|
||||||
|
* Main Android Activity of the app
|
||||||
|
* 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 MainActivity extends Activity
|
public class MainActivity extends Activity
|
||||||
{
|
{
|
||||||
private Menu menu;
|
private Spinner rotor1View;
|
||||||
private Spinner rotor1;
|
private Spinner rotor2View;
|
||||||
private Spinner rotor2;
|
private Spinner rotor3View;
|
||||||
private Spinner rotor3;
|
private Spinner reflectorView;
|
||||||
private Spinner reflector;
|
private Spinner rotor1PositionView;
|
||||||
private Spinner rotor1Position;
|
private Spinner rotor2PositionView;
|
||||||
private Spinner rotor2Position;
|
private Spinner rotor3PositionView;
|
||||||
private Spinner rotor3Position;
|
|
||||||
|
|
||||||
private EditText plugboard;
|
private EditText plugboardView;
|
||||||
private EditText input;
|
private EditText inputView;
|
||||||
private EditText output;
|
private EditText outputView;
|
||||||
|
|
||||||
private static final int RESULT_SETTINGS = 1;
|
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";
|
||||||
|
@ -56,6 +55,7 @@ public class MainActivity extends Activity
|
||||||
//memory for the ringSettings
|
//memory for the ringSettings
|
||||||
private int[] ringSettings = {0,0,0};
|
private int[] ringSettings = {0,0,0};
|
||||||
private boolean prefAnomaly;
|
private boolean prefAnomaly;
|
||||||
|
private String prefNumericLanguage;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState)
|
public void onCreate(Bundle savedInstanceState)
|
||||||
|
@ -63,7 +63,10 @@ public class MainActivity extends Activity
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
this.setContentView(R.layout.activity_main);
|
this.setContentView(R.layout.activity_main);
|
||||||
this.initLayout();
|
this.initLayout();
|
||||||
this.prefAnomaly = PreferenceManager.getDefaultSharedPreferences(this).getBoolean("prefAnomaly", true);
|
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.resetLayout();
|
||||||
ActivitySingleton singleton = ActivitySingleton.getInstance();
|
ActivitySingleton singleton = ActivitySingleton.getInstance();
|
||||||
singleton.setActivity(this);
|
singleton.setActivity(this);
|
||||||
|
@ -79,7 +82,7 @@ public class MainActivity extends Activity
|
||||||
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
|
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
|
||||||
if (sharedText != null)
|
if (sharedText != null)
|
||||||
{
|
{
|
||||||
input.setText(sharedText);
|
inputView.setText(sharedText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,7 +91,6 @@ public class MainActivity extends Activity
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu)
|
public boolean onCreateOptionsMenu(Menu menu)
|
||||||
{
|
{
|
||||||
this.menu = menu;
|
|
||||||
this.getMenuInflater().inflate(R.menu.main, menu);
|
this.getMenuInflater().inflate(R.menu.main, menu);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -109,7 +111,7 @@ public class MainActivity extends Activity
|
||||||
}
|
}
|
||||||
else if (id == R.id.action_choose_ringstellung)
|
else if (id == R.id.action_choose_ringstellung)
|
||||||
{
|
{
|
||||||
showRingsettingsDialog();
|
showRingSettingsDialog();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (id == R.id.action_settings)
|
else if (id == R.id.action_settings)
|
||||||
|
@ -124,15 +126,15 @@ public class MainActivity extends Activity
|
||||||
}
|
}
|
||||||
else if (id == R.id.action_send)
|
else if (id == R.id.action_send)
|
||||||
{
|
{
|
||||||
if(output.getText().length() == 0)
|
if(outputView.getText().length() == 0)
|
||||||
{
|
{
|
||||||
Toast.makeText(this, R.string.error_no_text_to_send, Toast.LENGTH_LONG).show();
|
Toast.makeText(this, R.string.error_no_text_to_send, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Intent sendIntent = new Intent();
|
Intent sendIntent = new Intent();
|
||||||
sendIntent.setAction(Intent.ACTION_SEND);
|
sendIntent.setAction(Intent.ACTION_SEND);
|
||||||
sendIntent.putExtra(Intent.EXTRA_TEXT, output.getText().toString());
|
sendIntent.putExtra(Intent.EXTRA_TEXT, outputView.getText().toString());
|
||||||
sendIntent.setType("text/plain");
|
sendIntent.setType("text/plain");
|
||||||
startActivity(Intent.createChooser(sendIntent, getResources().getText(R.string.send_to)));
|
startActivity(Intent.createChooser(sendIntent, getResources().getText(R.string.send_to)));
|
||||||
}
|
}
|
||||||
|
@ -148,25 +150,26 @@ public class MainActivity extends Activity
|
||||||
public void updateEnigma(View v)
|
public void updateEnigma(View v)
|
||||||
{
|
{
|
||||||
int[] conf = new int[10];
|
int[] conf = new int[10];
|
||||||
conf[0] = rotor1.getSelectedItemPosition() + 1;
|
conf[0] = rotor1View.getSelectedItemPosition() + 1;
|
||||||
conf[1] = rotor2.getSelectedItemPosition() + 1;
|
conf[1] = rotor2View.getSelectedItemPosition() + 1;
|
||||||
conf[2] = rotor3.getSelectedItemPosition() + 1;
|
conf[2] = rotor3View.getSelectedItemPosition() + 1;
|
||||||
conf[3] = reflector.getSelectedItemPosition() + 1;
|
conf[3] = reflectorView.getSelectedItemPosition() + 1;
|
||||||
conf[4] = rotor1Position.getSelectedItemPosition() + 1;
|
conf[4] = rotor1PositionView.getSelectedItemPosition() + 1;
|
||||||
conf[5] = rotor2Position.getSelectedItemPosition() + 1;
|
conf[5] = rotor2PositionView.getSelectedItemPosition() + 1;
|
||||||
conf[6] = rotor3Position.getSelectedItemPosition() + 1;
|
conf[6] = rotor3PositionView.getSelectedItemPosition() + 1;
|
||||||
conf[7] = ringSettings[0];
|
conf[7] = ringSettings[0];
|
||||||
conf[8] = ringSettings[1];
|
conf[8] = ringSettings[1];
|
||||||
conf[9] = ringSettings[2];
|
conf[9] = ringSettings[2];
|
||||||
|
|
||||||
enigma = new Enigma();
|
enigma = new Enigma();
|
||||||
|
|
||||||
int[][] plugboardConfiguration = null;
|
int[][] plugboardConfiguration;
|
||||||
plugboard.setText(plugboard.getText().toString().toUpperCase());
|
plugboardView.setText(plugboardView.getText().toString().toUpperCase());
|
||||||
plugboardConfiguration = Plugboard.parseConfigurationString(plugboard.getText().toString());
|
plugboardConfiguration = Plugboard.parseConfigurationString(plugboardView.getText().toString());
|
||||||
enigma.setConfiguration(conf);
|
enigma.setConfiguration(conf);
|
||||||
enigma.setPlugboard(new Plugboard(plugboardConfiguration));
|
enigma.setPlugboard(new Plugboard(plugboardConfiguration));
|
||||||
enigma.setPrefAnomaly(prefAnomaly);
|
enigma.setPrefAnomaly(prefAnomaly);
|
||||||
|
enigma.setInputPreparator(InputPreparator.createInputPreparator(prefNumericLanguage));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -177,12 +180,12 @@ public class MainActivity extends Activity
|
||||||
*/
|
*/
|
||||||
public void doCrypto(View v)
|
public void doCrypto(View v)
|
||||||
{
|
{
|
||||||
if(input.getText().length()!=0) {
|
if(inputView.getText().length()!=0) {
|
||||||
updateEnigma(null);
|
updateEnigma(null);
|
||||||
String m = input.getText().toString();
|
String m = inputView.getText().toString();
|
||||||
m = Enigma.prepare(m);
|
m = enigma.getInputPreparator().prepareString(m);
|
||||||
input.setText(m);
|
inputView.setText(m);
|
||||||
output.setText(enigma.encrypt(m));
|
outputView.setText(enigma.encrypt(m));
|
||||||
updateSpinner(enigma.getConfiguration());
|
updateSpinner(enigma.getConfiguration());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -193,17 +196,17 @@ public class MainActivity extends Activity
|
||||||
*/
|
*/
|
||||||
private void resetLayout()
|
private void resetLayout()
|
||||||
{
|
{
|
||||||
rotor1.setSelection(0);
|
rotor1View.setSelection(0);
|
||||||
rotor2.setSelection(1);
|
rotor2View.setSelection(1);
|
||||||
rotor3.setSelection(2);
|
rotor3View.setSelection(2);
|
||||||
reflector.setSelection(1);
|
reflectorView.setSelection(1);
|
||||||
rotor1Position.setSelection(0);
|
rotor1PositionView.setSelection(0);
|
||||||
rotor2Position.setSelection(0);
|
rotor2PositionView.setSelection(0);
|
||||||
rotor3Position.setSelection(0);
|
rotor3PositionView.setSelection(0);
|
||||||
ringSettings = new int[]{0,0,0};
|
ringSettings = new int[]{0,0,0};
|
||||||
plugboard.setText("");
|
plugboardView.setText("");
|
||||||
input.setText("");
|
inputView.setText("");
|
||||||
output.setText("");
|
outputView.setText("");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -214,63 +217,62 @@ public class MainActivity extends Activity
|
||||||
Character[] charArray = new Character[26];
|
Character[] charArray = new Character[26];
|
||||||
for(int i=0; i<26; i++) {charArray[i] = (char) (65+i);}
|
for(int i=0; i<26; i++) {charArray[i] = (char) (65+i);}
|
||||||
|
|
||||||
rotor1 = (Spinner) findViewById(R.id.rotor1);
|
rotor1View = (Spinner) findViewById(R.id.rotor1);
|
||||||
ArrayAdapter<CharSequence> rotor1Adapter = ArrayAdapter.createFromResource(this,
|
ArrayAdapter<CharSequence> rotor1Adapter = ArrayAdapter.createFromResource(this,
|
||||||
R.array.enigma_rotors, android.R.layout.simple_spinner_item);
|
R.array.enigma_rotors, android.R.layout.simple_spinner_item);
|
||||||
rotor1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
rotor1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
rotor1.setAdapter(rotor1Adapter);
|
rotor1View.setAdapter(rotor1Adapter);
|
||||||
|
|
||||||
|
|
||||||
rotor2 = (Spinner) findViewById(R.id.rotor2);
|
rotor2View = (Spinner) findViewById(R.id.rotor2);
|
||||||
ArrayAdapter<CharSequence> rotor2Adapter = ArrayAdapter.createFromResource(this,
|
ArrayAdapter<CharSequence> rotor2Adapter = ArrayAdapter.createFromResource(this,
|
||||||
R.array.enigma_rotors, android.R.layout.simple_spinner_item);
|
R.array.enigma_rotors, android.R.layout.simple_spinner_item);
|
||||||
rotor2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
rotor2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
rotor2.setAdapter(rotor2Adapter);
|
rotor2View.setAdapter(rotor2Adapter);
|
||||||
|
|
||||||
rotor3 = (Spinner) findViewById(R.id.rotor3);
|
rotor3View = (Spinner) findViewById(R.id.rotor3);
|
||||||
ArrayAdapter<CharSequence> rotor3Adapter = ArrayAdapter.createFromResource(this,
|
ArrayAdapter<CharSequence> rotor3Adapter = ArrayAdapter.createFromResource(this,
|
||||||
R.array.enigma_rotors, android.R.layout.simple_spinner_item);
|
R.array.enigma_rotors, android.R.layout.simple_spinner_item);
|
||||||
rotor3Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
rotor3Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
rotor3.setAdapter(rotor3Adapter);
|
rotor3View.setAdapter(rotor3Adapter);
|
||||||
|
|
||||||
reflector = (Spinner) findViewById(R.id.reflector);
|
reflectorView = (Spinner) findViewById(R.id.reflector);
|
||||||
ArrayAdapter<CharSequence> relfectorAdapter = ArrayAdapter.createFromResource(this,
|
ArrayAdapter<CharSequence> relfectorAdapter = ArrayAdapter.createFromResource(this,
|
||||||
R.array.enigma_reflectors, android.R.layout.simple_spinner_item);
|
R.array.enigma_reflectors, android.R.layout.simple_spinner_item);
|
||||||
relfectorAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
relfectorAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
reflector.setAdapter(relfectorAdapter);
|
reflectorView.setAdapter(relfectorAdapter);
|
||||||
|
|
||||||
rotor1Position = (Spinner) findViewById(R.id.rotor1position);
|
rotor1PositionView = (Spinner) findViewById(R.id.rotor1position);
|
||||||
ArrayAdapter<Character> rotor1PositionAdapter = new ArrayAdapter<>(this.getApplicationContext(),
|
ArrayAdapter<Character> rotor1PositionAdapter = new ArrayAdapter<>(this.getApplicationContext(),
|
||||||
android.R.layout.simple_spinner_item,charArray);
|
android.R.layout.simple_spinner_item,charArray);
|
||||||
rotor1PositionAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
rotor1PositionAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
rotor1Position.setAdapter(rotor1PositionAdapter);
|
rotor1PositionView.setAdapter(rotor1PositionAdapter);
|
||||||
|
|
||||||
rotor2Position = (Spinner) findViewById(R.id.rotor2position);
|
rotor2PositionView = (Spinner) findViewById(R.id.rotor2position);
|
||||||
ArrayAdapter<Character> rotor2PositionAdapter = new ArrayAdapter<>(this.getApplicationContext(),
|
ArrayAdapter<Character> rotor2PositionAdapter = new ArrayAdapter<>(this.getApplicationContext(),
|
||||||
android.R.layout.simple_spinner_item,charArray);
|
android.R.layout.simple_spinner_item,charArray);
|
||||||
rotor2PositionAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
rotor2PositionAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
rotor2Position.setAdapter(rotor2PositionAdapter);
|
rotor2PositionView.setAdapter(rotor2PositionAdapter);
|
||||||
|
|
||||||
rotor3Position = (Spinner) findViewById(R.id.rotor3position);
|
rotor3PositionView = (Spinner) findViewById(R.id.rotor3position);
|
||||||
ArrayAdapter<Character> rotor3PositionAdapter = new ArrayAdapter<>(this.getApplicationContext(),
|
ArrayAdapter<Character> rotor3PositionAdapter = new ArrayAdapter<>(this.getApplicationContext(),
|
||||||
android.R.layout.simple_spinner_item,charArray);
|
android.R.layout.simple_spinner_item,charArray);
|
||||||
rotor3PositionAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
rotor3PositionAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
rotor3Position.setAdapter(rotor3PositionAdapter);
|
rotor3PositionView.setAdapter(rotor3PositionAdapter);
|
||||||
|
|
||||||
plugboard = (EditText) findViewById(R.id.plugboard);
|
plugboardView = (EditText) findViewById(R.id.plugboard);
|
||||||
plugboard.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
plugboardView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onFocusChange(View v, boolean hasFocus) {
|
public void onFocusChange(View v, boolean hasFocus) {
|
||||||
if(!hasFocus)
|
if (!hasFocus) {
|
||||||
{
|
plugboardView.setText(plugboardView.getText().toString().toUpperCase());
|
||||||
plugboard.setText(plugboard.getText().toString().toUpperCase());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
input = (EditText) findViewById(R.id.input);
|
inputView = (EditText) findViewById(R.id.input);
|
||||||
output = (EditText) findViewById(R.id.output);
|
outputView = (EditText) findViewById(R.id.output);
|
||||||
|
|
||||||
input.requestFocus();
|
inputView.requestFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -279,40 +281,40 @@ public class MainActivity extends Activity
|
||||||
*/
|
*/
|
||||||
public void updateSpinner(int[] c)
|
public void updateSpinner(int[] c)
|
||||||
{
|
{
|
||||||
rotor1.setSelection(c[0] - 1);
|
rotor1View.setSelection(c[0] - 1);
|
||||||
rotor2.setSelection(c[1] - 1);
|
rotor2View.setSelection(c[1] - 1);
|
||||||
rotor3.setSelection(c[2] - 1);
|
rotor3View.setSelection(c[2] - 1);
|
||||||
rotor1Position.setSelection(c[4]);
|
rotor1PositionView.setSelection(c[4]);
|
||||||
rotor2Position.setSelection(c[5]);
|
rotor2PositionView.setSelection(c[5]);
|
||||||
rotor3Position.setSelection(c[6]);
|
rotor3PositionView.setSelection(c[6]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the dialog where the user can pick the ringsettings and set them if the user doesn't
|
* Show the dialog where the user can pick the ringsettings and set them if the user doesn't
|
||||||
* abort.
|
* abort.
|
||||||
*/
|
*/
|
||||||
public void showRingsettingsDialog()
|
public void showRingSettingsDialog()
|
||||||
{
|
{
|
||||||
View ringsettingsView = View.inflate(this, R.layout.dialog_ringsettings, null);
|
View ringSettingsView = View.inflate(this, R.layout.dialog_ringsettings, null);
|
||||||
|
|
||||||
Integer[] ringArray = new Integer[26];
|
Integer[] ringArray = new Integer[26];
|
||||||
for(int i=1; i<=26; i++) {ringArray[i-1] = i;}
|
for(int i=1; i<=26; i++) {ringArray[i-1] = i;}
|
||||||
|
|
||||||
final Spinner ring1 = (Spinner) ringsettingsView.findViewById(R.id.rotor1ring);
|
final Spinner ring1 = (Spinner) ringSettingsView.findViewById(R.id.rotor1ring);
|
||||||
ArrayAdapter<Integer> ring1Adapter = new ArrayAdapter<>(this.getApplicationContext(),
|
ArrayAdapter<Integer> ring1Adapter = new ArrayAdapter<>(this.getApplicationContext(),
|
||||||
android.R.layout.simple_spinner_item,ringArray);
|
android.R.layout.simple_spinner_item,ringArray);
|
||||||
ring1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
ring1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
ring1.setAdapter(ring1Adapter);
|
ring1.setAdapter(ring1Adapter);
|
||||||
ring1.setSelection(ringSettings[0]);
|
ring1.setSelection(ringSettings[0]);
|
||||||
|
|
||||||
final Spinner ring2 = (Spinner) ringsettingsView.findViewById(R.id.rotor2ring);
|
final Spinner ring2 = (Spinner) ringSettingsView.findViewById(R.id.rotor2ring);
|
||||||
ArrayAdapter<Integer> ring2Adapter = new ArrayAdapter<>(this.getApplicationContext(),
|
ArrayAdapter<Integer> ring2Adapter = new ArrayAdapter<>(this.getApplicationContext(),
|
||||||
android.R.layout.simple_spinner_item,ringArray);
|
android.R.layout.simple_spinner_item,ringArray);
|
||||||
ring2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
ring2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
ring2.setAdapter(ring2Adapter);
|
ring2.setAdapter(ring2Adapter);
|
||||||
ring2.setSelection(ringSettings[1]);
|
ring2.setSelection(ringSettings[1]);
|
||||||
|
|
||||||
final Spinner ring3 = (Spinner) ringsettingsView.findViewById(R.id.rotor3ring);
|
final Spinner ring3 = (Spinner) ringSettingsView.findViewById(R.id.rotor3ring);
|
||||||
ArrayAdapter<Integer> ring3Adapter = new ArrayAdapter<>(this.getApplicationContext(),
|
ArrayAdapter<Integer> ring3Adapter = new ArrayAdapter<>(this.getApplicationContext(),
|
||||||
android.R.layout.simple_spinner_item,ringArray);
|
android.R.layout.simple_spinner_item,ringArray);
|
||||||
ring3Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
ring3Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
|
@ -321,7 +323,7 @@ public class MainActivity extends Activity
|
||||||
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||||
builder.setTitle(R.string.title_ringsetting);
|
builder.setTitle(R.string.title_ringsetting);
|
||||||
builder.setView(ringsettingsView)
|
builder.setView(ringSettingsView)
|
||||||
.setCancelable(true)
|
.setCancelable(true)
|
||||||
.setPositiveButton(R.string.dialog_positiv, new DialogInterface.OnClickListener()
|
.setPositiveButton(R.string.dialog_positiv, new DialogInterface.OnClickListener()
|
||||||
{
|
{
|
||||||
|
@ -379,8 +381,12 @@ public class MainActivity extends Activity
|
||||||
{
|
{
|
||||||
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
|
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
this.prefAnomaly = sharedPrefs.getBoolean("prefAnomaly", true);
|
this.prefAnomaly = sharedPrefs.getBoolean("prefAnomaly", true);
|
||||||
|
this.prefNumericLanguage = sharedPrefs.getString("prefNumericLanguage",getResources().
|
||||||
|
getStringArray(R.array.pref_alias_numeric_spelling_language)[0]);
|
||||||
|
;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,23 @@ import android.widget.Toast;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by vanitas on 12.08.15.
|
* Plugboard of the enigma
|
||||||
|
* 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 Plugboard
|
public class Plugboard
|
||||||
{
|
{
|
||||||
|
@ -30,7 +46,7 @@ public class Plugboard
|
||||||
/**
|
/**
|
||||||
* Configure the plugboard according to the given array.
|
* Configure the plugboard according to the given array.
|
||||||
*
|
*
|
||||||
* @param configuration
|
* @param configuration two dimensional array of plugs
|
||||||
*/
|
*/
|
||||||
public void setConfiguration(int[][] configuration)
|
public void setConfiguration(int[][] configuration)
|
||||||
{
|
{
|
||||||
|
@ -68,7 +84,7 @@ public class Plugboard
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
input = input.toUpperCase();
|
input = input.toUpperCase();
|
||||||
ArrayList<int[]> plugList = new ArrayList<int[]>();
|
ArrayList<int[]> plugList = new ArrayList<>();
|
||||||
int[] plug = new int[2];
|
int[] plug = new int[2];
|
||||||
for (int i = 0; i < input.length(); i++) {
|
for (int i = 0; i < input.length(); i++) {
|
||||||
int c = input.charAt(i) - 65;
|
int c = input.charAt(i) - 65;
|
||||||
|
|
|
@ -1,7 +1,25 @@
|
||||||
package de.vanitasvitae.enigmandroid.rotors;
|
package de.vanitasvitae.enigmandroid.rotors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by vanitas on 11.08.15.
|
* Reflector of the enigma machine.
|
||||||
|
* The reflector was used to reflect the scrambled signal at the end of the wiring back to
|
||||||
|
* go through another (reversed but not inverting) process of scrambling.
|
||||||
|
* 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 Reflector
|
public class Reflector
|
||||||
{
|
{
|
||||||
|
@ -9,6 +27,14 @@ public class Reflector
|
||||||
protected int type;
|
protected int type;
|
||||||
protected Integer[] connections;
|
protected Integer[] connections;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This constructor is not accessible from outside this class file.
|
||||||
|
* Use the one of the createReflector* methods instead to create concrete Reflectors from
|
||||||
|
* outside this class file
|
||||||
|
* @param name phonetic name of the reflector (usually A,B,C)
|
||||||
|
* @param type type indicator of the reflector (A->1,...,C->3)
|
||||||
|
* @param connections wiring of the reflector as Integer array
|
||||||
|
*/
|
||||||
protected Reflector(String name, int type, Integer[] connections)
|
protected Reflector(String name, int type, Integer[] connections)
|
||||||
{
|
{
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
@ -16,21 +42,41 @@ public class Reflector
|
||||||
this.connections = connections;
|
this.connections = connections;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a reflector of type A
|
||||||
|
* @return ReflectorA
|
||||||
|
*/
|
||||||
public static Reflector createReflectorA()
|
public static Reflector createReflectorA()
|
||||||
{
|
{
|
||||||
return new ReflectorA();
|
return new ReflectorA();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a reflector of type B
|
||||||
|
* @return ReflectorB
|
||||||
|
*/
|
||||||
public static Reflector createReflectorB()
|
public static Reflector createReflectorB()
|
||||||
{
|
{
|
||||||
return new ReflectorB();
|
return new ReflectorB();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a reflector of type C
|
||||||
|
* @return ReflectorC
|
||||||
|
*/
|
||||||
public static Reflector createReflectorC()
|
public static Reflector createReflectorC()
|
||||||
{
|
{
|
||||||
return new ReflectorC();
|
return new ReflectorC();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory method to create reflectors.
|
||||||
|
* @param type type of the created reflector
|
||||||
|
* 1 -> ReflectorA
|
||||||
|
* 2 -> ReflectorB
|
||||||
|
* anything else -> ReflectorC
|
||||||
|
* @return ReflectorA | ReflectorB | ReflectorC
|
||||||
|
*/
|
||||||
public static Reflector createReflector(int type)
|
public static Reflector createReflector(int type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
|
@ -41,31 +87,61 @@ public class Reflector
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Substitute an input signal via the wiring of the reflector with a different (!) output.
|
||||||
|
* The output MUST not be equal to the input for any input, since this was not possible
|
||||||
|
* due to the electronic implementation of the historical enigma machine.
|
||||||
|
* @param input input signal
|
||||||
|
* @return encrypted (substituted) output
|
||||||
|
*/
|
||||||
public int encrypt(int input)
|
public int encrypt(int input)
|
||||||
{
|
{
|
||||||
return this.connections[normalize(input)];
|
return this.connections[normalize(input)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the type indicator of the reflector
|
||||||
|
* @return type
|
||||||
|
*/
|
||||||
public int getType()
|
public int getType()
|
||||||
{
|
{
|
||||||
return this.type;
|
return this.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return phonetic name of the reflector
|
||||||
|
* @return name
|
||||||
|
*/
|
||||||
public String getName()
|
public String getName()
|
||||||
{
|
{
|
||||||
return this.name;
|
return this.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the size (ie the number of wires/length of the connections array) of the reflector
|
||||||
|
* @return size
|
||||||
|
*/
|
||||||
private int getRotorSize()
|
private int getRotorSize()
|
||||||
{
|
{
|
||||||
return this.connections.length;
|
return this.connections.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 reflector. This is necessary since java allows negative modulo values,
|
||||||
|
* which can break this implementation
|
||||||
|
* @param input input signal
|
||||||
|
* @return "normalized" input signal
|
||||||
|
*/
|
||||||
private int normalize(int input)
|
private int normalize(int input)
|
||||||
{
|
{
|
||||||
return (input + this.getRotorSize()) % this.getRotorSize();
|
return (input + this.getRotorSize()) % this.getRotorSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Concrete implementation of ReflectorA
|
||||||
|
*/
|
||||||
private static class ReflectorA extends Reflector
|
private static class ReflectorA extends Reflector
|
||||||
{
|
{
|
||||||
public ReflectorA()
|
public ReflectorA()
|
||||||
|
@ -74,6 +150,9 @@ public class Reflector
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Concrete implementation of ReflectorB
|
||||||
|
*/
|
||||||
private static class ReflectorB extends Reflector
|
private static class ReflectorB extends Reflector
|
||||||
{
|
{
|
||||||
public ReflectorB()
|
public ReflectorB()
|
||||||
|
@ -82,6 +161,9 @@ public class Reflector
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Concrete implementation of ReflectorC
|
||||||
|
*/
|
||||||
private static class ReflectorC extends Reflector
|
private static class ReflectorC extends Reflector
|
||||||
{
|
{
|
||||||
public ReflectorC()
|
public ReflectorC()
|
||||||
|
|
|
@ -1,7 +1,28 @@
|
||||||
package de.vanitasvitae.enigmandroid.rotors;
|
package de.vanitasvitae.enigmandroid.rotors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by vanitas on 11.08.15.
|
* Rotor super class and inner concrete implementations
|
||||||
|
* The rotors were the key feature of the enigma used to scramble up input signals into
|
||||||
|
* encrypted signals difficult to predict. The rotors rotated to achieve a poly-alphabetic
|
||||||
|
* substitution which was hard to break. Each signal passes the rotor twice. Once in "forward"-
|
||||||
|
* direction and once in "backwards"-direction. There was a set of 3 out of 5 rotors inside the
|
||||||
|
* enigma machine M4.
|
||||||
|
* 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 Rotor
|
public class Rotor
|
||||||
{
|
{
|
||||||
|
@ -14,6 +35,22 @@ public class Rotor
|
||||||
protected int ringSetting;
|
protected int ringSetting;
|
||||||
protected int rotation;
|
protected int rotation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This constructor is not accessible from outside this class file.
|
||||||
|
* Use one of the createRotor* factory methods instead to create concrete Rotors.
|
||||||
|
* Note that connections and reversedConnections MUST be of the same size and that
|
||||||
|
* neither connections nor reversedConnections respectively MUST have any number between
|
||||||
|
* 0 and connections.length-1 only once (ie they represent permutations)
|
||||||
|
* @param name phonetic name of the rotor (usually I,II,...V)
|
||||||
|
* @param type type indicator (I -> 1,...,V -> 5)
|
||||||
|
* @param connections wiring of the rotor as Integer array
|
||||||
|
* @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 ringSetting setting of the ring that holds the letters
|
||||||
|
* @param rotation rotation of the rotor
|
||||||
|
*/
|
||||||
protected Rotor(String name, int type, Integer[] connections, Integer[] reversedConnections,
|
protected Rotor(String name, int type, Integer[] connections, Integer[] reversedConnections,
|
||||||
int turnOverNotch, int ringSetting, int rotation)
|
int turnOverNotch, int ringSetting, int rotation)
|
||||||
{
|
{
|
||||||
|
@ -26,6 +63,14 @@ public class Rotor
|
||||||
this.rotation = rotation;
|
this.rotation = rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 ringSetting setting of the outer ring (0..25)
|
||||||
|
* @param rotation rotation of the rotor
|
||||||
|
* @return Concrete rotor
|
||||||
|
*/
|
||||||
public static Rotor createRotor(int type, int ringSetting, int rotation)
|
public static Rotor createRotor(int type, int ringSetting, int rotation)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
|
@ -38,53 +83,103 @@ public class Rotor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
public static Rotor createRotorI(int ringSetting, int rotation)
|
||||||
{
|
{
|
||||||
return new RotorI(ringSetting, 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)
|
public static Rotor createRotorII(int ringSetting, int rotation)
|
||||||
{
|
{
|
||||||
return new RotorII(ringSetting, 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)
|
public static Rotor createRotorIII(int ringSetting, int rotation)
|
||||||
{
|
{
|
||||||
return new RotorIII(ringSetting, 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)
|
public static Rotor createRotorIV(int ringSetting, int rotation)
|
||||||
{
|
{
|
||||||
return new RotorIV(ringSetting, 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)
|
public static Rotor createRotorV(int ringSetting, int rotation)
|
||||||
{
|
{
|
||||||
return new RotorV(ringSetting, rotation);
|
return new RotorV(ringSetting, rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encrypt an input signal via the internal wiring in "forward" direction (using connections)
|
||||||
|
* @param input signal
|
||||||
|
* @return encrypted signal
|
||||||
|
*/
|
||||||
public int encryptForward(int input)
|
public int encryptForward(int input)
|
||||||
{
|
{
|
||||||
return this.connections[normalize(input)];
|
return this.connections[normalize(input)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encrypt an input signal via the internal wiring in "backwards" direction (using
|
||||||
|
* reversedConnections)
|
||||||
|
* @param input signal
|
||||||
|
* @return encrypted signal
|
||||||
|
*/
|
||||||
public int encryptBackward(int input)
|
public int encryptBackward(int input)
|
||||||
{
|
{
|
||||||
return this.reversedConnections[normalize(input)];
|
return this.reversedConnections[normalize(input)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the type indicator (usually 1..5)
|
||||||
|
* @return type indicator
|
||||||
|
*/
|
||||||
public int getType()
|
public int getType()
|
||||||
{
|
{
|
||||||
return this.type;
|
return this.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the current rotation of the rotor.
|
||||||
|
* The rotation consists of the actual rotation - the ringSetting
|
||||||
|
* @return rotation-ringSetting
|
||||||
|
*/
|
||||||
public int getRotation()
|
public int getRotation()
|
||||||
{
|
{
|
||||||
return this.rotation - this.getRingSetting();
|
return this.rotation - this.getRingSetting();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* increment rotation of the rotor by one.
|
* Increment rotation of the rotor by one.
|
||||||
*/
|
*/
|
||||||
public void rotate()
|
public void rotate()
|
||||||
{
|
{
|
||||||
|
@ -92,9 +187,8 @@ public class Rotor
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true, if rotor is at a position, where it turns over the next rotor
|
* Return true, if the rotor is at a position, where it turns over the next rotor by one
|
||||||
*
|
* @return rotation==turnOverNotch
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public boolean isAtTurnoverPosition()
|
public boolean isAtTurnoverPosition()
|
||||||
{
|
{
|
||||||
|
@ -102,31 +196,28 @@ public class Rotor
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Double Turn Anomaly (deutsch: Doppelsprung Anomalie) is an anomaly in the rotor movement
|
* Return true, if the rotor is in a position where the double turn anomaly happens.
|
||||||
|
* The double turn anomaly (german: Doppelsprung-Anomalie) is an anomaly in the rotor movement
|
||||||
* caused by the mechanical implementation of the enigma.
|
* caused by the mechanical implementation of the enigma.
|
||||||
* Whenever the rightmost rotor turns the middle rotor AND the middle rotor is only one move
|
* Whenever the rightmost rotor turns the middle rotor AND the middle rotor is only one move
|
||||||
* from turning the leftmost rotor, the middle rotor turns again with the next character.
|
* from turning the leftmost rotor, the middle rotor turns again with the next character.
|
||||||
* So technically there are only 26*25*26 possible rotor settings for any but firmly 3 rotors.
|
* So technically there are only 26*25*26 possible rotor settings for any but firmly 3 rotors.
|
||||||
*
|
* @return rotation == turnOverNotch-1
|
||||||
* @return boolean
|
|
||||||
*/
|
*/
|
||||||
public boolean doubleTurnAnomaly()
|
public boolean doubleTurnAnomaly()
|
||||||
{
|
{
|
||||||
return this.rotation == this.turnOverNotch - 1;
|
return this.rotation == this.getTurnOver() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
/**
|
/**
|
||||||
* Returns the position of the turnover notch
|
* Returns the position of the turnover notch
|
||||||
*
|
* @return turnOverNotch
|
||||||
* @return turnOver
|
|
||||||
*/
|
*/
|
||||||
public int getTurnOver()
|
public int getTurnOver()
|
||||||
{
|
{
|
||||||
return this.turnOverNotch;
|
return this.turnOverNotch;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
/**
|
/**
|
||||||
* Return ringSettings of the rotor
|
* Return ringSettings of the rotor
|
||||||
* @return ringSetting
|
* @return ringSetting
|
||||||
|
@ -136,21 +227,41 @@ public class Rotor
|
||||||
return this.ringSetting;
|
return this.ringSetting;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the phonetic name of the rotor
|
||||||
|
* @return name
|
||||||
|
*/
|
||||||
public String getName()
|
public String getName()
|
||||||
{
|
{
|
||||||
return this.name;
|
return this.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the size (ie the number of wires/size of the connections array)
|
||||||
|
* of the rotor
|
||||||
|
* @return size
|
||||||
|
*/
|
||||||
public int getRotorSize()
|
public int getRotorSize()
|
||||||
{
|
{
|
||||||
return this.connections.length;
|
return this.connections.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 rotor. 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)
|
public int normalize(int input)
|
||||||
{
|
{
|
||||||
return (input + this.getRotorSize()) % this.getRotorSize();
|
return (input + this.getRotorSize()) % this.getRotorSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Concrete implementation of Rotor of type 1 (I)
|
||||||
|
*/
|
||||||
private static class RotorI extends Rotor
|
private static class RotorI extends Rotor
|
||||||
{
|
{
|
||||||
public RotorI(int ringSetting, int rotation)
|
public RotorI(int ringSetting, int rotation)
|
||||||
|
@ -162,6 +273,9 @@ public class Rotor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Concrete implementation of Rotor of type 2 (II)
|
||||||
|
*/
|
||||||
private static class RotorII extends Rotor
|
private static class RotorII extends Rotor
|
||||||
{
|
{
|
||||||
public RotorII(int ringSetting, int rotation)
|
public RotorII(int ringSetting, int rotation)
|
||||||
|
@ -173,6 +287,9 @@ public class Rotor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Concrete implementation of Rotor of type 3 (III)
|
||||||
|
*/
|
||||||
private static class RotorIII extends Rotor
|
private static class RotorIII extends Rotor
|
||||||
{
|
{
|
||||||
public RotorIII(int ringSetting, int rotation)
|
public RotorIII(int ringSetting, int rotation)
|
||||||
|
@ -184,6 +301,9 @@ public class Rotor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Concrete implementation of Rotor of type 4 (IV)
|
||||||
|
*/
|
||||||
private static class RotorIV extends Rotor
|
private static class RotorIV extends Rotor
|
||||||
{
|
{
|
||||||
public RotorIV(int ringSetting, int rotation)
|
public RotorIV(int ringSetting, int rotation)
|
||||||
|
@ -195,6 +315,9 @@ public class Rotor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Concrete implementation of Rotor of type 5 (V)
|
||||||
|
*/
|
||||||
private static class RotorV extends Rotor
|
private static class RotorV extends Rotor
|
||||||
{
|
{
|
||||||
public RotorV(int ringSetting, int rotation)
|
public RotorV(int ringSetting, int rotation)
|
||||||
|
|
|
@ -144,6 +144,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="30pt"
|
android:layout_height="30pt"
|
||||||
android:id="@+id/plugboard"
|
android:id="@+id/plugboard"
|
||||||
|
android:inputType="textNoSuggestions"
|
||||||
android:hint="@string/hint_enigma_plugboard"
|
android:hint="@string/hint_enigma_plugboard"
|
||||||
android:layout_below="@+id/lin_lay_2"/>
|
android:layout_below="@+id/lin_lay_2"/>
|
||||||
|
|
||||||
|
@ -158,13 +159,14 @@
|
||||||
android:layout_weight=".50"
|
android:layout_weight=".50"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:id="@+id/input"
|
android:id="@+id/input"
|
||||||
|
android:inputType="textNoSuggestions"
|
||||||
android:hint="@string/hint_enigma_type_here" />
|
android:hint="@string/hint_enigma_type_here" />
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_weight=".50"
|
android:layout_weight=".50"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:editable="false"
|
android:inputType="none"
|
||||||
android:textIsSelectable="true"
|
android:textIsSelectable="true"
|
||||||
android:id="@+id/output"
|
android:id="@+id/output"
|
||||||
android:hint="@string/hint_enigma_code"/>
|
android:hint="@string/hint_enigma_code"/>
|
||||||
|
@ -178,7 +180,6 @@
|
||||||
<Button
|
<Button
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@+id/text_layer"
|
|
||||||
android:id="@+id/button_crypt"
|
android:id="@+id/button_crypt"
|
||||||
android:onClick="doCrypto"
|
android:onClick="doCrypto"
|
||||||
android:text="@string/button_crypt"
|
android:text="@string/button_crypt"
|
||||||
|
|
|
@ -7,5 +7,11 @@
|
||||||
<string name="pref_title_simulate_anomaly">Doppelschritt Anomalie</string>
|
<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>
|
||||||
|
<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>Englisch</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -25,10 +25,10 @@
|
||||||
<string name="error_unable_to_plug_a_b">Unable to plug </string>
|
<string name="error_unable_to_plug_a_b">Unable to plug </string>
|
||||||
<string name="error_plug_already_in_use">Error: One or more of these plugs are already in use:</string>
|
<string name="error_plug_already_in_use">Error: One or more of these plugs are already in use:</string>
|
||||||
<string name="error_no_text_to_send">Can\'t send empty text.</string>
|
<string name="error_no_text_to_send">Can\'t send empty text.</string>
|
||||||
<string name="title_ringsetting">Ringsettings</string>
|
<string name="title_ringsetting">Ring-Settings</string>
|
||||||
<string name="dialog_positiv">OK</string>
|
<string name="dialog_positiv">OK</string>
|
||||||
<string name="dialog_negativ">Cancel</string>
|
<string name="dialog_negativ">Cancel</string>
|
||||||
<string name="dialog_ringsettings_success">Set Ringsettings to</string>
|
<string name="dialog_ringsettings_success">Set Ring-Settings to</string>
|
||||||
<string name="dialog_ringsettings_abort">No changes</string>
|
<string name="dialog_ringsettings_abort">No changes</string>
|
||||||
<string name="message_reset">Enigma reset</string>
|
<string name="message_reset">Enigma reset</string>
|
||||||
|
|
||||||
|
|
|
@ -8,5 +8,15 @@
|
||||||
<string name="pref_description_simulate_anomaly">The double step anomaly causes the middle rotor
|
<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.
|
to rotate twice, if it is one step before its turnover point.
|
||||||
</string>
|
</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>English</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array translatable="false" name="pref_alias_numeric_spelling_language">
|
||||||
|
<item>de</item>
|
||||||
|
<item>en</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -7,6 +7,13 @@
|
||||||
android:title="@string/pref_title_simulate_anomaly"
|
android:title="@string/pref_title_simulate_anomaly"
|
||||||
android:summary="@string/pref_description_simulate_anomaly"
|
android:summary="@string/pref_description_simulate_anomaly"
|
||||||
android:defaultValue="true" />
|
android:defaultValue="true" />
|
||||||
|
<ListPreference
|
||||||
|
android:key="prefNumericLanguage"
|
||||||
|
android:title="@string/pref_title_numeric_spelling_language"
|
||||||
|
android:summary="@string/pref_description_numeric_spelling_language"
|
||||||
|
android:entries="@array/pref_list_numeric_spelling_language"
|
||||||
|
android:entryValues="@array/pref_alias_numeric_spelling_language"
|
||||||
|
android:defaultValue="de" />
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
Loading…
Reference in a new issue