Integrated ZXing Barcode scanner, added functionality to share/receive configurations via QR-Code, added option to generate configuration from passphrase

This commit is contained in:
VanitasVitae 2015-09-30 14:25:49 +02:00
parent f9b7be4ea0
commit 2bc5e62265
40 changed files with 1787 additions and 730 deletions

View File

@ -1,8 +1,10 @@
CHANGELOG ENIGMANDROID
v0.1.9-not-yet-released<
*Added option to share/receive configurations via QR-Code (ZXing Barcode Scanner)
*Prevent user from setting incomplete reflector wiring
*Add option to generate configuration from passphrase
*TODO: Add Enigma Z (Probably wont happen due to lack of information :/)
*TODO: Add multi-Enigma (select any rotor/reflector etc. Probably wont happen too soon)
*TODO: Enigma configuration from/to seed (text or qr code)
v0.1.8-27.09.2015<
*Added Enigma G31

View File

@ -0,0 +1,506 @@
/*
* Copyright 2009 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.integration.android;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Fragment;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
/**
* <p>A utility class which helps ease integration with Barcode Scanner via {@link Intent}s. This is a simple
* way to invoke barcode scanning and receive the result, without any need to integrate, modify, or learn the
* project's source code.</p>
*
* <h2>Initiating a barcode scan</h2>
*
* <p>To integrate, create an instance of {@code IntentIntegrator} and call {@link #initiateScan()} and wait
* for the result in your app.</p>
*
* <p>It does require that the Barcode Scanner (or work-alike) application is installed. The
* {@link #initiateScan()} method will prompt the user to download the application, if needed.</p>
*
* <p>There are a few steps to using this integration. First, your {@link Activity} must implement
* the method {@link Activity#onActivityResult(int, int, Intent)} and include a line of code like this:</p>
*
* <pre>{@code
* public void onActivityResult(int requestCode, int resultCode, Intent intent) {
* IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
* if (scanResult != null) {
* // handle scan result
* }
* // else continue with any other code you need in the method
* ...
* }
* }</pre>
*
* <p>This is where you will handle a scan result.</p>
*
* <p>Second, just call this in response to a user action somewhere to begin the scan process:</p>
*
* <pre>{@code
* IntentIntegrator integrator = new IntentIntegrator(yourActivity);
* integrator.initiateScan();
* }</pre>
*
* <p>Note that {@link #initiateScan()} returns an {@link AlertDialog} which is non-null if the
* user was prompted to download the application. This lets the calling app potentially manage the dialog.
* In particular, ideally, the app dismisses the dialog if it's still active in its {@link Activity#onPause()}
* method.</p>
*
* <p>You can use {@link #setTitle(String)} to customize the title of this download prompt dialog (or, use
* {@link #setTitleByID(int)} to set the title by string resource ID.) Likewise, the prompt message, and
* yes/no button labels can be changed.</p>
*
* <p>Finally, you can use {@link #addExtra(String, Object)} to add more parameters to the Intent used
* to invoke the scanner. This can be used to set additional options not directly exposed by this
* simplified API.</p>
*
* <p>By default, this will only allow applications that are known to respond to this intent correctly
* do so. The apps that are allowed to response can be set with {@link #setTargetApplications(List)}.
* For example, set to {@link #TARGET_BARCODE_SCANNER_ONLY} to only target the Barcode Scanner app itself.</p>
*
* <h2>Sharing text via barcode</h2>
*
* <p>To share text, encoded as a QR Code on-screen, similarly, see {@link #shareText(CharSequence)}.</p>
*
* <p>Some code, particularly download integration, was contributed from the Anobiit application.</p>
*
* <h2>Enabling experimental barcode formats</h2>
*
* <p>Some formats are not enabled by default even when scanning with {@link #ALL_CODE_TYPES}, such as
* PDF417. Use {@link #initiateScan(java.util.Collection)} with
* a collection containing the names of formats to scan for explicitly, like "PDF_417", to use such
* formats.</p>
*
* @author Sean Owen
* @author Fred Lin
* @author Isaac Potoczny-Jones
* @author Brad Drehmer
* @author gcstang
*/
public class IntentIntegrator {
public static final int REQUEST_CODE = 0x0000c0de; // Only use bottom 16 bits
private static final String TAG = IntentIntegrator.class.getSimpleName();
public static final String DEFAULT_TITLE = "Install Barcode Scanner?";
public static final String DEFAULT_MESSAGE =
"This application requires Barcode Scanner. Would you like to install it?";
public static final String DEFAULT_YES = "Yes";
public static final String DEFAULT_NO = "No";
private static final String BS_PACKAGE = "com.google.zxing.client.android";
private static final String BSPLUS_PACKAGE = "com.srowen.bs.android";
// supported barcode formats
public static final Collection<String> PRODUCT_CODE_TYPES = list("UPC_A", "UPC_E", "EAN_8", "EAN_13", "RSS_14");
public static final Collection<String> ONE_D_CODE_TYPES =
list("UPC_A", "UPC_E", "EAN_8", "EAN_13", "CODE_39", "CODE_93", "CODE_128",
"ITF", "RSS_14", "RSS_EXPANDED");
public static final Collection<String> QR_CODE_TYPES = Collections.singleton("QR_CODE");
public static final Collection<String> DATA_MATRIX_TYPES = Collections.singleton("DATA_MATRIX");
public static final Collection<String> ALL_CODE_TYPES = null;
public static final List<String> TARGET_BARCODE_SCANNER_ONLY = Collections.singletonList(BS_PACKAGE);
public static final List<String> TARGET_ALL_KNOWN = list(
BSPLUS_PACKAGE, // Barcode Scanner+
BSPLUS_PACKAGE + ".simple", // Barcode Scanner+ Simple
BS_PACKAGE // Barcode Scanner
// What else supports this intent?
);
private final Activity activity;
private final Fragment fragment;
private String title;
private String message;
private String buttonYes;
private String buttonNo;
private List<String> targetApplications;
private final Map<String,Object> moreExtras = new HashMap<String,Object>(3);
/**
* @param activity {@link Activity} invoking the integration
*/
public IntentIntegrator(Activity activity) {
this.activity = activity;
this.fragment = null;
initializeConfiguration();
}
/**
* @param fragment {@link Fragment} invoking the integration.
* {@link #startActivityForResult(Intent, int)} will be called on the {@link Fragment} instead
* of an {@link Activity}
*/
public IntentIntegrator(Fragment fragment) {
this.activity = fragment.getActivity();
this.fragment = fragment;
initializeConfiguration();
}
private void initializeConfiguration() {
title = DEFAULT_TITLE;
message = DEFAULT_MESSAGE;
buttonYes = DEFAULT_YES;
buttonNo = DEFAULT_NO;
targetApplications = TARGET_ALL_KNOWN;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public void setTitleByID(int titleID) {
title = activity.getString(titleID);
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public void setMessageByID(int messageID) {
message = activity.getString(messageID);
}
public String getButtonYes() {
return buttonYes;
}
public void setButtonYes(String buttonYes) {
this.buttonYes = buttonYes;
}
public void setButtonYesByID(int buttonYesID) {
buttonYes = activity.getString(buttonYesID);
}
public String getButtonNo() {
return buttonNo;
}
public void setButtonNo(String buttonNo) {
this.buttonNo = buttonNo;
}
public void setButtonNoByID(int buttonNoID) {
buttonNo = activity.getString(buttonNoID);
}
public Collection<String> getTargetApplications() {
return targetApplications;
}
public final void setTargetApplications(List<String> targetApplications) {
if (targetApplications.isEmpty()) {
throw new IllegalArgumentException("No target applications");
}
this.targetApplications = targetApplications;
}
public void setSingleTargetApplication(String targetApplication) {
this.targetApplications = Collections.singletonList(targetApplication);
}
public Map<String,?> getMoreExtras() {
return moreExtras;
}
public final void addExtra(String key, Object value) {
moreExtras.put(key, value);
}
/**
* Initiates a scan for all known barcode types with the default camera.
*
* @return the {@link AlertDialog} that was shown to the user prompting them to download the app
* if a prompt was needed, or null otherwise.
*/
public final AlertDialog initiateScan() {
return initiateScan(ALL_CODE_TYPES, -1);
}
/**
* Initiates a scan for all known barcode types with the specified camera.
*
* @param cameraId camera ID of the camera to use. A negative value means "no preference".
* @return the {@link AlertDialog} that was shown to the user prompting them to download the app
* if a prompt was needed, or null otherwise.
*/
public final AlertDialog initiateScan(int cameraId) {
return initiateScan(ALL_CODE_TYPES, cameraId);
}
/**
* Initiates a scan, using the default camera, only for a certain set of barcode types, given as strings corresponding
* to their names in ZXing's {@code BarcodeFormat} class like "UPC_A". You can supply constants
* like {@link #PRODUCT_CODE_TYPES} for example.
*
* @param desiredBarcodeFormats names of {@code BarcodeFormat}s to scan for
* @return the {@link AlertDialog} that was shown to the user prompting them to download the app
* if a prompt was needed, or null otherwise.
*/
public final AlertDialog initiateScan(Collection<String> desiredBarcodeFormats) {
return initiateScan(desiredBarcodeFormats, -1);
}
/**
* Initiates a scan, using the specified camera, only for a certain set of barcode types, given as strings corresponding
* to their names in ZXing's {@code BarcodeFormat} class like "UPC_A". You can supply constants
* like {@link #PRODUCT_CODE_TYPES} for example.
*
* @param desiredBarcodeFormats names of {@code BarcodeFormat}s to scan for
* @param cameraId camera ID of the camera to use. A negative value means "no preference".
* @return the {@link AlertDialog} that was shown to the user prompting them to download the app
* if a prompt was needed, or null otherwise
*/
public final AlertDialog initiateScan(Collection<String> desiredBarcodeFormats, int cameraId) {
Intent intentScan = new Intent(BS_PACKAGE + ".SCAN");
intentScan.addCategory(Intent.CATEGORY_DEFAULT);
// check which types of codes to scan for
if (desiredBarcodeFormats != null) {
// set the desired barcode types
StringBuilder joinedByComma = new StringBuilder();
for (String format : desiredBarcodeFormats) {
if (joinedByComma.length() > 0) {
joinedByComma.append(',');
}
joinedByComma.append(format);
}
intentScan.putExtra("SCAN_FORMATS", joinedByComma.toString());
}
// check requested camera ID
if (cameraId >= 0) {
intentScan.putExtra("SCAN_CAMERA_ID", cameraId);
}
String targetAppPackage = findTargetAppPackage(intentScan);
if (targetAppPackage == null) {
return showDownloadDialog();
}
intentScan.setPackage(targetAppPackage);
intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
attachMoreExtras(intentScan);
startActivityForResult(intentScan, REQUEST_CODE);
return null;
}
/**
* Start an activity. This method is defined to allow different methods of activity starting for
* newer versions of Android and for compatibility library.
*
* @param intent Intent to start.
* @param code Request code for the activity
* @see android.app.Activity#startActivityForResult(Intent, int)
* @see android.app.Fragment#startActivityForResult(Intent, int)
*/
protected void startActivityForResult(Intent intent, int code) {
if (fragment == null) {
activity.startActivityForResult(intent, code);
} else {
fragment.startActivityForResult(intent, code);
}
}
private String findTargetAppPackage(Intent intent) {
PackageManager pm = activity.getPackageManager();
List<ResolveInfo> availableApps = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
if (availableApps != null) {
for (String targetApp : targetApplications) {
if (contains(availableApps, targetApp)) {
return targetApp;
}
}
}
return null;
}
private static boolean contains(Iterable<ResolveInfo> availableApps, String targetApp) {
for (ResolveInfo availableApp : availableApps) {
String packageName = availableApp.activityInfo.packageName;
if (targetApp.equals(packageName)) {
return true;
}
}
return false;
}
private AlertDialog showDownloadDialog() {
AlertDialog.Builder downloadDialog = new AlertDialog.Builder(activity);
downloadDialog.setTitle(title);
downloadDialog.setMessage(message);
downloadDialog.setPositiveButton(buttonYes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
String packageName;
if (targetApplications.contains(BS_PACKAGE)) {
// Prefer to suggest download of BS if it's anywhere in the list
packageName = BS_PACKAGE;
} else {
// Otherwise, first option:
packageName = targetApplications.get(0);
}
Uri uri = Uri.parse("market://details?id=" + packageName);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
try {
if (fragment == null) {
activity.startActivity(intent);
} else {
fragment.startActivity(intent);
}
} catch (ActivityNotFoundException anfe) {
// Hmm, market is not installed
Log.w(TAG, "Google Play is not installed; cannot install " + packageName);
}
}
});
downloadDialog.setNegativeButton(buttonNo, null);
downloadDialog.setCancelable(true);
return downloadDialog.show();
}
/**
* <p>Call this from your {@link Activity}'s
* {@link Activity#onActivityResult(int, int, Intent)} method.</p>
*
* @param requestCode request code from {@code onActivityResult()}
* @param resultCode result code from {@code onActivityResult()}
* @param intent {@link Intent} from {@code onActivityResult()}
* @return null if the event handled here was not related to this class, or
* else an {@link IntentResult} containing the result of the scan. If the user cancelled scanning,
* the fields will be null.
*/
public static IntentResult parseActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
String contents = intent.getStringExtra("SCAN_RESULT");
String formatName = intent.getStringExtra("SCAN_RESULT_FORMAT");
byte[] rawBytes = intent.getByteArrayExtra("SCAN_RESULT_BYTES");
int intentOrientation = intent.getIntExtra("SCAN_RESULT_ORIENTATION", Integer.MIN_VALUE);
Integer orientation = intentOrientation == Integer.MIN_VALUE ? null : intentOrientation;
String errorCorrectionLevel = intent.getStringExtra("SCAN_RESULT_ERROR_CORRECTION_LEVEL");
return new IntentResult(contents,
formatName,
rawBytes,
orientation,
errorCorrectionLevel);
}
return new IntentResult();
}
return null;
}
/**
* Defaults to type "TEXT_TYPE".
*
* @param text the text string to encode as a barcode
* @return the {@link AlertDialog} that was shown to the user prompting them to download the app
* if a prompt was needed, or null otherwise
* @see #shareText(CharSequence, CharSequence)
*/
public final AlertDialog shareText(CharSequence text) {
return shareText(text, "TEXT_TYPE");
}
/**
* Shares the given text by encoding it as a barcode, such that another user can
* scan the text off the screen of the device.
*
* @param text the text string to encode as a barcode
* @param type type of data to encode. See {@code com.google.zxing.client.android.Contents.Type} constants.
* @return the {@link AlertDialog} that was shown to the user prompting them to download the app
* if a prompt was needed, or null otherwise
*/
public final AlertDialog shareText(CharSequence text, CharSequence type) {
Intent intent = new Intent();
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setAction(BS_PACKAGE + ".ENCODE");
intent.putExtra("ENCODE_TYPE", type);
intent.putExtra("ENCODE_DATA", text);
String targetAppPackage = findTargetAppPackage(intent);
if (targetAppPackage == null) {
return showDownloadDialog();
}
intent.setPackage(targetAppPackage);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
attachMoreExtras(intent);
if (fragment == null) {
activity.startActivity(intent);
} else {
fragment.startActivity(intent);
}
return null;
}
private static List<String> list(String... values) {
return Collections.unmodifiableList(Arrays.asList(values));
}
private void attachMoreExtras(Intent intent) {
for (Map.Entry<String,Object> entry : moreExtras.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
// Kind of hacky
if (value instanceof Integer) {
intent.putExtra(key, (Integer) value);
} else if (value instanceof Long) {
intent.putExtra(key, (Long) value);
} else if (value instanceof Boolean) {
intent.putExtra(key, (Boolean) value);
} else if (value instanceof Double) {
intent.putExtra(key, (Double) value);
} else if (value instanceof Float) {
intent.putExtra(key, (Float) value);
} else if (value instanceof Bundle) {
intent.putExtra(key, (Bundle) value);
} else {
intent.putExtra(key, value.toString());
}
}
}
}

View File

@ -0,0 +1,95 @@
/*
* Copyright 2009 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.zxing.integration.android;
/**
* <p>Encapsulates the result of a barcode scan invoked through {@link IntentIntegrator}.</p>
*
* @author Sean Owen
*/
public final class IntentResult {
private final String contents;
private final String formatName;
private final byte[] rawBytes;
private final Integer orientation;
private final String errorCorrectionLevel;
IntentResult() {
this(null, null, null, null, null);
}
IntentResult(String contents,
String formatName,
byte[] rawBytes,
Integer orientation,
String errorCorrectionLevel) {
this.contents = contents;
this.formatName = formatName;
this.rawBytes = rawBytes;
this.orientation = orientation;
this.errorCorrectionLevel = errorCorrectionLevel;
}
/**
* @return raw content of barcode
*/
public String getContents() {
return contents;
}
/**
* @return name of format, like "QR_CODE", "UPC_A". See {@code BarcodeFormat} for more format names.
*/
public String getFormatName() {
return formatName;
}
/**
* @return raw bytes of the barcode content, if applicable, or null otherwise
*/
public byte[] getRawBytes() {
return rawBytes;
}
/**
* @return rotation of the image, in degrees, which resulted in a successful scan. May be null.
*/
public Integer getOrientation() {
return orientation;
}
/**
* @return name of the error correction level used in the barcode, if applicable
*/
public String getErrorCorrectionLevel() {
return errorCorrectionLevel;
}
@Override
public String toString() {
StringBuilder dialogText = new StringBuilder(100);
dialogText.append("Format: ").append(formatName).append('\n');
dialogText.append("Contents: ").append(contents).append('\n');
int rawBytesLength = rawBytes == null ? 0 : rawBytes.length;
dialogText.append("Raw bytes: (").append(rawBytesLength).append(" bytes)\n");
dialogText.append("Orientation: ").append(orientation).append('\n');
dialogText.append("EC level: ").append(errorCorrectionLevel).append('\n');
return dialogText.toString();
}
}

View File

@ -15,10 +15,14 @@ import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import java.util.ArrayList;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
import de.vanitasvitae.enigmandroid.enigma.Enigma;
import de.vanitasvitae.enigmandroid.enigma.EnigmaStateBundle;
import de.vanitasvitae.enigmandroid.enigma.inputPreparer.InputPreparer;
import de.vanitasvitae.enigmandroid.layout.LayoutContainer;
import de.vanitasvitae.enigmandroid.layout.PassphraseDialogBuilder;
/**
* Main Android Activity of the app
@ -44,6 +48,7 @@ public class MainActivity extends Activity
private static final int RESULT_SETTINGS = 1;
private static final String URI_CHANGELOG =
"https://github.com/vanitasvitae/EnigmAndroid/blob/master/CHANGELOG.txt";
public static final String APP_ID = "EnigmAndroid";
LayoutContainer layoutContainer;
protected String prefMachineType;
@ -55,7 +60,6 @@ public class MainActivity extends Activity
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Log.d("Activity","OnCreate!");
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
this.prefMachineType = sharedPreferences.getString(SettingsActivity.PREF_MACHINE_TYPE, getResources().
getStringArray(R.array.pref_alias_machine_type)[0]);
@ -81,65 +85,6 @@ public class MainActivity extends Activity
}
}
/**
* Unfortunately we have to overwrite this, because on orientation changes the LayoutContainer
* will reset and we would lose information about plugboard, reflector-wiring and ring settings.
* These info are we saving here.
* TODO: Find more elegant solution
* @param outState state
*/
@Override
protected void onSaveInstanceState (Bundle outState)
{
ArrayList<Integer> plugboard = new ArrayList<>();
if(layoutContainer.getState().getConfigurationPlugboard() != null) {
for (int i : layoutContainer.getState().getConfigurationPlugboard()) plugboard.add(i);
}
outState.putIntegerArrayList("plugboard",plugboard);
ArrayList<Integer> reflector = new ArrayList<>();
if(layoutContainer.getState().getConfigurationReflector() != null) {
for (int i : layoutContainer.getState().getConfigurationReflector()) reflector.add(i);
}
outState.putIntegerArrayList("reflector", reflector);
outState.putInt("ring1", layoutContainer.getState().getRingSettingRotor1());
outState.putInt("ring2", layoutContainer.getState().getRingSettingRotor2());
outState.putInt("ring3", layoutContainer.getState().getRingSettingRotor3());
outState.putInt("ring4", layoutContainer.getState().getRingSettingRotor4());
outState.putInt("ringR", layoutContainer.getState().getRingSettingReflector());
super.onSaveInstanceState(outState);
}
/**
* Here we get back values previously saved int onSaveInstanceState
* @param savedInstanceState state
*/
@Override
protected void onRestoreInstanceState (Bundle savedInstanceState)
{
ArrayList<Integer> plugboard = savedInstanceState.getIntegerArrayList("plugboard");
if(plugboard != null && plugboard.size() != 0) {
int[] p = new int[plugboard.size()];
for (int i = 0; i < plugboard.size(); i++) p[i] = plugboard.get(i);
layoutContainer.getState().setConfigurationPlugboard(p);
}
ArrayList<Integer> reflector = savedInstanceState.getIntegerArrayList("reflector");
if(reflector != null && reflector.size() != 0) {
int[] r = new int[reflector.size()];
for (int i = 0; i < reflector.size(); i++) r[i] = reflector.get(i);
layoutContainer.getState().setConfigurationReflector(r);
}
layoutContainer.getState().setRingSettingRotor1(savedInstanceState.getInt("ring1"));
layoutContainer.getState().setRingSettingRotor2(savedInstanceState.getInt("ring2"));
layoutContainer.getState().setRingSettingRotor3(savedInstanceState.getInt("ring3"));
layoutContainer.getState().setRingSettingRotor4(savedInstanceState.getInt("ring4"));
layoutContainer.getState().setRingSettingReflector(savedInstanceState.getInt("ringR"));
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
@ -204,6 +149,8 @@ public class MainActivity extends Activity
layoutContainer = LayoutContainer.createLayoutContainer(prefMachineType);
layoutContainer.setInputPreparer(InputPreparer.createInputPreparer());
layoutContainer.getInput().setText(savedInput);
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
sharedPreferences.edit().putString(SettingsActivity.PREF_MACHINE_TYPE, type);
}
}
@ -266,6 +213,11 @@ public class MainActivity extends Activity
return prefMessageFormatting;
}
public void onDialogFinished(EnigmaStateBundle state)
{
layoutContainer.getEnigma().setState(state);
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
@ -290,12 +242,12 @@ public class MainActivity extends Activity
else if (id == R.id.action_random_configuration)
{
layoutContainer.getEnigma().randomState();
layoutContainer.setLayoutState(layoutContainer.getEnigma().getState());
layoutContainer.syncStateFromEnigmaToLayout();
Toast.makeText(getApplicationContext(), R.string.message_random,
Toast.LENGTH_SHORT).show();
return true;
}
else if (id == R.id.action_choose_ringstellung)
else if (id == R.id.action_choose_ringsetting)
{
layoutContainer.showRingSettingsDialog();
return true;
@ -325,6 +277,25 @@ public class MainActivity extends Activity
startActivity(Intent.createChooser(sendIntent, getResources().getText(R.string.send_to)));
}
}
else if (id == R.id.action_receive_scan)
{
IntentIntegrator integrator = new IntentIntegrator(this);
integrator.initiateScan();
return true;
}
else if(id == R.id.action_share_scan)
{
IntentIntegrator QRIntegrator = new IntentIntegrator(this);
layoutContainer.syncStateFromLayoutToEnigma();
Log.d(APP_ID, "Sharing configuration to QR: " + layoutContainer.getEnigma().stateToString());
QRIntegrator.shareText(layoutContainer.getEnigma().stateToString());
return true;
}
else if(id == R.id.action_enter_seed)
{
new PassphraseDialogBuilder().showDialog();
return true;
}
return super.onOptionsItemSelected(item);
}
@ -390,10 +361,37 @@ public class MainActivity extends Activity
getResources().getStringArray(R.array.pref_alias_message_formatting)[0]));
break;
}
case IntentIntegrator.REQUEST_CODE:
IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
if (scanResult != null) {
String content = scanResult.getContents();
if(content == null) Log.e(APP_ID, "Error! Received nothing from QR-Code!");
else Log.d(APP_ID, "Received "+content+" from QR-Code!");
restoreStateFromCode(content);
}
}
}
private void restoreStateFromCode(String mem)
{
setPrefMachineType(Enigma.chooseEnigmaFromSave(mem));
updateContentView();
layoutContainer = LayoutContainer.createLayoutContainer(getPrefMachineType());
layoutContainer.getEnigma().restoreState(mem);
layoutContainer.setInputPreparer(InputPreparer.createInputPreparer());
layoutContainer.syncStateFromEnigmaToLayout();
}
public void createStateFromSeed(String seed)
{
setPrefMachineType(Enigma.chooseEnigmaFromSeed(seed));
updateContentView();
layoutContainer = LayoutContainer.createLayoutContainer(getPrefMachineType());
layoutContainer.getEnigma().setStateFromSeed(seed);
layoutContainer.setInputPreparer(InputPreparer.createInputPreparer());
layoutContainer.syncStateFromEnigmaToLayout();
}
/**
* Open the web page with the URL url
* @param url URL of the website

View File

@ -1,5 +1,8 @@
package de.vanitasvitae.enigmandroid.enigma;
import java.security.SecureRandom;
import java.util.Random;
/**
* Main component of the Enigma machine
* This is the mostly abstract base of any enigma machine.
@ -23,14 +26,26 @@ package de.vanitasvitae.enigmandroid.enigma;
public abstract class Enigma
{
protected static String machineType;
protected int machineTypeOffset = 0;
protected boolean doAnomaly = false; //Has the time come to handle an anomaly?
protected boolean prefAnomaly; //Do you WANT to simulate the anomaly?
protected Random rand;
public Enigma(int off)
{
this.machineTypeOffset = off;
initialize();
}
public Enigma()
{
initialize();
}
public int getMachineTypeOffset()
{
return machineTypeOffset;
}
/**
* Set the enigma to an initial state
*/
@ -66,11 +81,20 @@ public abstract class Enigma
public abstract void nextState();
/**
* Set the enigma to a random state.
* Set the enigma into a completely random state using a unseeded SecureRandom object.
*/
public void randomState()
{
this.rand = new SecureRandom();
generateState();
}
/**
* Set the enigma to a random state based on the initialization of rand.
* Don not choose a rotor twice, set random rotations, ringSettings, ukw and possibly
* plugboard / rewirable ukw configurations.
*/
public abstract void randomState();
protected abstract void generateState();
/**
* Substitute char k by sending the signal through the enigma.
@ -94,6 +118,53 @@ public abstract class Enigma
*/
public abstract EnigmaStateBundle getState();
/**
* Set the rand into a certain state based on seed.
* Then set the enigmas state.
* @param seed
*/
public void setStateFromSeed(String seed)
{
rand = new Random(seed.hashCode());
generateState();
}
public abstract void restoreState(String mem);
public abstract String stateToString();
public static String numToMachineType(int n)
{
switch (n) {
case 0: return "I";
case 1: return "M3";
case 2: return "M4";
case 3: return "G31";
case 4: return "G312";
case 5: return "G260";
case 6: return "D";
case 7: return "K";
case 8: return "KS";
case 9: return "KSA";
case 10: return "R";
default: return "T";
}
}
public static String chooseEnigmaFromSeed(String seed)
{
return numToMachineType(seed.hashCode() % 12);
}
public static String chooseEnigmaFromSave(String save)
{
int index = save.indexOf(":");
if(index != -1) save = save.substring(0, index);
long s = Long.valueOf(save);
return numToMachineType(getValue(s,12));
}
/**
* set prefAnomaly variable
* @param b boolean
@ -112,4 +183,40 @@ public abstract class Enigma
return machineType;
}
/**
*
* @param s source
* @param d domain (max value) of the value
* @return value
*/
protected static int getValue(long s, int d)
{
return (int) ((s%d)+d)%d;
}
/**
* remove a digit of domain d from source s
* @param s source
* @param d domain (max value)
* @return trimmed source
*/
protected static long removeDigit(long s, int d)
{
return (s-(s%d))/d;
}
/**
*
* @param s source
* @param b base (max value)
* @param v actual value
* @return lengthened source
*/
protected static long addDigit(long s, int v, int b)
{
long x = s;
x*=b;
x+=(v%b);
return x;
}
}

View File

@ -1,8 +1,5 @@
package de.vanitasvitae.enigmandroid.enigma;
import java.security.SecureRandom;
import java.util.Random;
import de.vanitasvitae.enigmandroid.enigma.rotors.Reflector;
import de.vanitasvitae.enigmandroid.enigma.rotors.Rotor;
@ -34,6 +31,7 @@ public class Enigma_D extends Enigma {
protected Reflector.ReflectorEnigma_D_KD_G31 reflector;
protected static int machineTypeOffset = 70;
public Enigma_D()
{
super();
@ -44,10 +42,10 @@ public class Enigma_D extends Enigma {
public void initialize()
{
this.entryWheel = Rotor.createRotor(1, 0, 0);
this.rotor1 = Rotor.createRotor(70, 0, 0);
this.rotor2 = Rotor.createRotor(71, 0, 0);
this.rotor3 = Rotor.createRotor(72, 0, 0);
this.reflector = (Reflector.ReflectorEnigma_D_KD_G31) Reflector.createReflector(70);
this.rotor1 = Rotor.createRotor(machineTypeOffset, 0, 0);
this.rotor2 = Rotor.createRotor(machineTypeOffset, 0, 0);
this.rotor3 = Rotor.createRotor(machineTypeOffset, 0, 0);
this.reflector = (Reflector.ReflectorEnigma_D_KD_G31) Reflector.createReflector(machineTypeOffset);
}
@Override
@ -66,9 +64,7 @@ public class Enigma_D extends Enigma {
}
@Override
public void randomState()
{
Random rand = new SecureRandom();
protected void generateState() {
int rot1 = rand.nextInt(26);
int rot2 = rand.nextInt(26);
int rot3 = rand.nextInt(26);
@ -78,12 +74,14 @@ public class Enigma_D extends Enigma {
int ring3 = rand.nextInt(26);
int ringRef = rand.nextInt(26);
this.rotor1 = Rotor.createRotor(70, rot1, ring1);
this.rotor2 = Rotor.createRotor(71, rot2, ring2);
this.rotor3 = Rotor.createRotor(72, rot3, ring3);
this.reflector = (Reflector.ReflectorEnigma_D_KD_G31) Reflector.createReflector(70);
this.rotor1 = Rotor.createRotor(machineTypeOffset, rot1, ring1);
this.rotor2 = Rotor.createRotor(machineTypeOffset+1, rot2, ring2);
this.rotor3 = Rotor.createRotor(machineTypeOffset+2, rot3, ring3);
this.reflector = (Reflector.ReflectorEnigma_D_KD_G31) Reflector.createReflector(machineTypeOffset);
this.reflector.setRotation(rotRef);
this.reflector.setRingSetting(ringRef);
this.reflector.setConfiguration(Plugboard.seedToReflectorConfiguration(rand));
}
@Override
@ -153,4 +151,54 @@ public class Enigma_D extends Enigma {
return state;
}
@Override
public void restoreState(String mem)
{
String reflectorConf = mem.substring(mem.lastIndexOf(":r")+2);
long s = Long.valueOf(mem.substring(0, mem.indexOf(":r")));
s = removeDigit(s, 12); //Remove machine type
int rot1 = getValue(s, 26);
s = removeDigit(s, 26);
int ring1 = getValue(s, 26);
s = removeDigit(s, 26);
int rot2 = getValue(s, 26);
s = removeDigit(s, 26);
int ring2 = getValue(s, 26);
s = removeDigit(s, 26);
int rot3 = getValue(s, 26);
s = removeDigit(s, 26);
int ring3 = getValue(s, 26);
s = removeDigit(s, 26);
int rotRef = getValue(s, 26);
s = removeDigit(s, 26);
int ringRef = getValue(s, 26);
this.rotor1 = Rotor.createRotor(machineTypeOffset, rot1, ring1);
this.rotor2 = Rotor.createRotor(machineTypeOffset+1, rot2, ring2);
this.rotor3 = Rotor.createRotor(machineTypeOffset+2, rot3, ring3);
this.reflector = (Reflector.ReflectorEnigma_D_KD_G31) Reflector.createReflector(machineTypeOffset);
this.reflector.setConfiguration(Plugboard.stringToConfiguration(reflectorConf));
this.reflector.setRotation(rotRef);
this.reflector.setRingSetting(ringRef);
}
@Override
public String stateToString() {
String save = "";
long s = reflector.getRingSetting();
s = addDigit(s, reflector.getRotation(), 26);
s = addDigit(s, rotor3.getRingSetting(), 26);
s = addDigit(s, rotor3.getRotation(), 26);
s = addDigit(s, rotor2.getRingSetting(), 26);
s = addDigit(s, rotor2.getRotation(), 26);
s = addDigit(s, rotor1.getRingSetting(), 26);
s = addDigit(s, rotor1.getRotation(), 26);
s = addDigit(s, 6, 12); //Machine #6
save = save+s;
save = save + ":r" + Plugboard.configurationToString(getState().getConfigurationReflector());
return save;
}
}

View File

@ -1,11 +1,5 @@
package de.vanitasvitae.enigmandroid.enigma;
import java.security.SecureRandom;
import java.util.Random;
import de.vanitasvitae.enigmandroid.enigma.rotors.Reflector;
import de.vanitasvitae.enigmandroid.enigma.rotors.Rotor;
/**
* Implementation of the Enigma machine of type G31 (Abwehr)
* Copyright (C) 2015 Paul Schaub
@ -29,43 +23,31 @@ public class Enigma_G260 extends Enigma_G31
{
public Enigma_G260()
{
super();
super(60);
machineType = "G260";
}
@Override
public void initialize()
{
this.entryWheel = Rotor.createRotor(1, 0, 0);
this.rotor1 = Rotor.createRotor(60, 0, 0);
this.rotor2 = Rotor.createRotor(61, 0, 0);
this.rotor3 = Rotor.createRotor(62, 0, 0);
this.reflector = Reflector.createReflector(60);
}
@Override
public void randomState()
public String stateToString()
{
Random rand = new SecureRandom();
String save = "";
long s = reflector.getRingSetting();
s = addDigit(s, reflector.getRotation(), 26);
s = addDigit(s, rotor3.getRingSetting(), 26);
s = addDigit(s, rotor3.getRotation(), 26);
s = addDigit(s, rotor2.getRingSetting(), 26);
s = addDigit(s, rotor2.getRotation(), 26);
s = addDigit(s, rotor1.getRingSetting(), 26);
s = addDigit(s, rotor1.getRotation(), 26);
int rotor1, rotor2=-1, rotor3=-1;
rotor1 = rand.nextInt(3);
while(rotor2 == -1 || rotor2 == rotor1) rotor2 = rand.nextInt(3);
rotor3 = 3 - rotor1 - rotor2;
s = addDigit(s, rotor3.getNumber(), 10);
s = addDigit(s, rotor2.getNumber(), 10);
s = addDigit(s, rotor1.getNumber(), 10);
int rot1 = rand.nextInt(26);
int rot2 = rand.nextInt(26);
int rot3 = rand.nextInt(26);
int rotRef = rand.nextInt(26);
int ring1 = rand.nextInt(26);
int ring2 = rand.nextInt(26);
int ring3 = rand.nextInt(26);
int ringRef = rand.nextInt(26);
s = addDigit(s, 5, 12); //Machine #5
this.rotor1 = Rotor.createRotor(60 + rotor1, rot1, ring1);
this.rotor2 = Rotor.createRotor(60 + rotor2, rot2, ring2);
this.rotor3 = Rotor.createRotor(60 + rotor3, rot3, ring3);
this.reflector = Reflector.createReflector(60);
reflector.setRotation(rotRef);
reflector.setRingSetting(ringRef);
save = save+s;
return save;
}
}

View File

@ -2,9 +2,6 @@ package de.vanitasvitae.enigmandroid.enigma;
import android.util.Log;
import java.security.SecureRandom;
import java.util.Random;
import de.vanitasvitae.enigmandroid.enigma.rotors.Reflector;
import de.vanitasvitae.enigmandroid.enigma.rotors.Rotor;
@ -36,19 +33,24 @@ public class Enigma_G31 extends Enigma
protected Reflector reflector;
public Enigma_G31(int off)
{
super(off);
}
public Enigma_G31()
{
super();
super(40);
machineType = "G31";
}
@Override
public void initialize()
{
this.entryWheel = Rotor.createRotor(1, 0, 0);
this.rotor1 = Rotor.createRotor(40, 0, 0);
this.rotor2 = Rotor.createRotor(41, 0, 0);
this.rotor3 = Rotor.createRotor(42, 0, 0);
this.reflector = Reflector.createReflector(40);
this.rotor1 = Rotor.createRotor(machineTypeOffset, 0, 0);
this.rotor2 = Rotor.createRotor(machineTypeOffset + 1, 0, 0);
this.rotor3 = Rotor.createRotor(machineTypeOffset + 2, 0, 0);
this.reflector = Reflector.createReflector(machineTypeOffset);
}
@Override
@ -70,15 +72,12 @@ public class Enigma_G31 extends Enigma
}
}
@Override
public void randomState()
protected void generateState()
{
Random rand = new SecureRandom();
int rotor1, rotor2=-1, rotor3=-1;
rotor1 = rand.nextInt(3);
while(rotor2 == -1 || rotor2 == rotor1) rotor2 = rand.nextInt(3);
rotor3 = 3 - rotor1 - rotor2;
int r1, r2=-1, r3=-1;
r1 = rand.nextInt(3);
while(r2 == -1 || r2 == r1) r2 = rand.nextInt(3);
r3 = 3 - r1 - r2;
int rot1 = rand.nextInt(26);
int rot2 = rand.nextInt(26);
@ -89,10 +88,10 @@ public class Enigma_G31 extends Enigma
int ring3 = rand.nextInt(26);
int ringRef = rand.nextInt(26);
this.rotor1 = Rotor.createRotor(40 + rotor1, rot1, ring1);
this.rotor2 = Rotor.createRotor(40 + rotor2, rot2, ring2);
this.rotor3 = Rotor.createRotor(40 + rotor3, rot3, ring3);
this.reflector = Reflector.createReflector(40);
this.rotor1 = Rotor.createRotor(machineTypeOffset + r1, rot1, ring1);
this.rotor2 = Rotor.createRotor(machineTypeOffset + r2, rot2, ring2);
this.rotor3 = Rotor.createRotor(machineTypeOffset + r3, rot3, ring3);
this.reflector = Reflector.createReflector(machineTypeOffset);
reflector.setRotation(rotRef);
reflector.setRingSetting(ringRef);
}
@ -160,4 +159,65 @@ public class Enigma_G31 extends Enigma
return state;
}
@Override
public void restoreState(String mem)
{
long s = Long.valueOf(mem);
s = removeDigit(s, 12); //Remove machine type
int r1 = getValue(s, 10);
s = removeDigit(s, 10);
int r2 = getValue(s, 10);
s = removeDigit(s, 10);
int r3 = getValue(s, 10);
s = removeDigit(s, 10);
int rot1 = getValue(s, 26);
s = removeDigit(s, 26);
int ring1 = getValue(s, 26);
s = removeDigit(s, 26);
int rot2 = getValue(s, 26);
s = removeDigit(s, 26);
int ring2 = getValue(s, 26);
s = removeDigit(s, 26);
int rot3 = getValue(s, 26);
s = removeDigit(s, 26);
int ring3 = getValue(s, 26);
s = removeDigit(s, 26);
int rotRef = getValue(s, 26);
s = removeDigit(s, 26);
int ringRef = getValue(s, 26);
this.rotor1 = Rotor.createRotor(machineTypeOffset + r1, rot1, ring1);
this.rotor2 = Rotor.createRotor(machineTypeOffset + r2, rot2, ring2);
this.rotor3 = Rotor.createRotor(machineTypeOffset + r3, rot3, ring3);
this.reflector = Reflector.createReflector(machineTypeOffset);
this.reflector.setRotation(rotRef);
this.reflector.setRingSetting(ringRef);
}
@Override
public String stateToString()
{
String save = "";
long s = reflector.getRingSetting();
s = addDigit(s, reflector.getRotation(), 26);
s = addDigit(s, rotor3.getRingSetting(), 26);
s = addDigit(s, rotor3.getRotation(), 26);
s = addDigit(s, rotor2.getRingSetting(), 26);
s = addDigit(s, rotor2.getRotation(), 26);
s = addDigit(s, rotor1.getRingSetting(), 26);
s = addDigit(s, rotor1.getRotation(), 26);
s = addDigit(s, rotor3.getNumber(), 10);
s = addDigit(s, rotor2.getNumber(), 10);
s = addDigit(s, rotor1.getNumber(), 10);
s = addDigit(s, 3, 12); //Machine #3
save = save+s;
return save;
}
}

View File

@ -1,12 +1,5 @@
package de.vanitasvitae.enigmandroid.enigma;
import java.security.SecureRandom;
import java.sql.Ref;
import java.util.Random;
import de.vanitasvitae.enigmandroid.enigma.rotors.Reflector;
import de.vanitasvitae.enigmandroid.enigma.rotors.Rotor;
/**
* Implementation of the Enigma machine of type G31 (Abwehr)
* Copyright (C) 2015 Paul Schaub
@ -30,43 +23,30 @@ public class Enigma_G312 extends Enigma_G31
{
public Enigma_G312()
{
super();
super(50);
machineType = "G312";
}
@Override
public void initialize()
{
this.entryWheel = Rotor.createRotor(1, 0, 0);
this.rotor1 = Rotor.createRotor(50, 0, 0);
this.rotor2 = Rotor.createRotor(51, 0, 0);
this.rotor3 = Rotor.createRotor(52, 0, 0);
this.reflector = Reflector.createReflector(50);
}
@Override
public void randomState()
public String stateToString()
{
Random rand = new SecureRandom();
String save = "";
long s = reflector.getRingSetting();
s = addDigit(s, reflector.getRotation(), 26);
s = addDigit(s, rotor3.getRingSetting(), 26);
s = addDigit(s, rotor3.getRotation(), 26);
s = addDigit(s, rotor2.getRingSetting(), 26);
s = addDigit(s, rotor2.getRotation(), 26);
s = addDigit(s, rotor1.getRingSetting(), 26);
s = addDigit(s, rotor1.getRotation(), 26);
int rotor1, rotor2=-1, rotor3=-1;
rotor1 = rand.nextInt(3);
while(rotor2 == -1 || rotor2 == rotor1) rotor2 = rand.nextInt(3);
rotor3 = 3 - rotor1 - rotor2;
s = addDigit(s, rotor3.getNumber(), 10);
s = addDigit(s, rotor2.getNumber(), 10);
s = addDigit(s, rotor1.getNumber(), 10);
int rot1 = rand.nextInt(26);
int rot2 = rand.nextInt(26);
int rot3 = rand.nextInt(26);
int rotRef = rand.nextInt(26);
int ring1 = rand.nextInt(26);
int ring2 = rand.nextInt(26);
int ring3 = rand.nextInt(26);
int ringRef = rand.nextInt(26);
s = addDigit(s, 4, 12); //Machine #4
this.rotor1 = Rotor.createRotor(50 + rotor1, rot1, ring1);
this.rotor2 = Rotor.createRotor(50 + rotor2, rot2, ring2);
this.rotor3 = Rotor.createRotor(50 + rotor3, rot3, ring3);
this.reflector = Reflector.createReflector(50);
reflector.setRotation(rotRef);
reflector.setRingSetting(ringRef);
save = save+s;
return save;
}
}

View File

@ -1,8 +1,5 @@
package de.vanitasvitae.enigmandroid.enigma;
import java.security.SecureRandom;
import java.util.Random;
import de.vanitasvitae.enigmandroid.enigma.rotors.Reflector;
import de.vanitasvitae.enigmandroid.enigma.rotors.Rotor;
@ -34,6 +31,7 @@ public class Enigma_I extends Enigma
protected Reflector reflector;
protected Plugboard plugboard;
protected static int machineTypeOffset = 10;
public Enigma_I()
{
@ -45,10 +43,10 @@ public class Enigma_I extends Enigma
public void initialize()
{
this.plugboard= new Plugboard();
this.rotor1 = Rotor.createRotor(10, 0, 0);
this.rotor2 = Rotor.createRotor(11, 0, 0);
this.rotor3 = Rotor.createRotor(12, 0, 0);
this.reflector = Reflector.createReflector(10);
this.rotor1 = Rotor.createRotor(machineTypeOffset, 0, 0);
this.rotor2 = Rotor.createRotor(machineTypeOffset+1, 0, 0);
this.rotor3 = Rotor.createRotor(machineTypeOffset+2, 0, 0);
this.reflector = Reflector.createReflector(machineTypeOffset);
}
@Override
@ -67,10 +65,7 @@ public class Enigma_I extends Enigma
}
@Override
public void randomState()
{
Random rand = new SecureRandom();
protected void generateState() {
int rotor1, rotor2=-1, rotor3=-1;
rotor1 = rand.nextInt(5);
while(rotor2 == -1 || rotor2 == rotor1) rotor2 = rand.nextInt(5);
@ -84,10 +79,13 @@ public class Enigma_I extends Enigma
int ring2 = rand.nextInt(26);
int ring3 = rand.nextInt(26);
this.rotor1 = Rotor.createRotor(10 + rotor1, rot1, ring1);
this.rotor2 = Rotor.createRotor(10 + rotor2, rot2, ring2);
this.rotor3 = Rotor.createRotor(10 + rotor3, rot3, ring3);
this.reflector = Reflector.createReflector(10 + ref);
this.rotor1 = Rotor.createRotor(machineTypeOffset + rotor1, rot1, ring1);
this.rotor2 = Rotor.createRotor(machineTypeOffset + rotor2, rot2, ring2);
this.rotor3 = Rotor.createRotor(machineTypeOffset + rotor3, rot3, ring3);
this.reflector = Reflector.createReflector(machineTypeOffset + ref);
this.plugboard = new Plugboard();
plugboard.setConfiguration(Plugboard.seedToPlugboardConfiguration(rand));
}
@Override
@ -151,4 +149,59 @@ public class Enigma_I extends Enigma
return state;
}
@Override
public void restoreState(String mem)
{
String plugboardConf = mem.substring(mem.lastIndexOf(":p") + 2);
long s = Long.valueOf(mem.substring(0, mem.indexOf(":p")));
s = removeDigit(s, 12); //Remove machine type
int r1 = getValue(s, 10);
s = removeDigit(s, 10);
int r2 = getValue(s, 10);
s = removeDigit(s, 10);
int r3 = getValue(s, 10);
s = removeDigit(s, 10);
int ref = getValue(s, 10);
s = removeDigit(s, 10);
int rot1 = getValue(s, 26);
s = removeDigit(s, 26);
int ring1 = getValue(s, 26);
s = removeDigit(s, 26);
int rot2 = getValue(s, 26);
s = removeDigit(s, 26);
int ring2 = getValue(s, 26);
s = removeDigit(s, 26);
int rot3 = getValue(s, 26);
s = removeDigit(s, 26);
int ring3 = getValue(s, 26);
this.rotor1 = Rotor.createRotor(machineTypeOffset + r1, rot1, ring1);
this.rotor2 = Rotor.createRotor(machineTypeOffset + r2, rot2, ring2);
this.rotor3 = Rotor.createRotor(machineTypeOffset + r3, rot3, ring3);
this.reflector = Reflector.createReflector(machineTypeOffset + ref);
this.plugboard = new Plugboard();
plugboard.setConfiguration(Plugboard.stringToConfiguration(plugboardConf));
}
@Override
public String stateToString() {
String save = "";
long s = rotor3.getRingSetting();
s = addDigit(s, rotor3.getRotation(), 26);
s = addDigit(s, rotor2.getRingSetting(), 26);
s = addDigit(s, rotor2.getRotation(), 26);
s = addDigit(s, rotor1.getRingSetting(), 26);
s = addDigit(s, rotor1.getRotation(), 26);
s = addDigit(s, rotor3.getNumber(), 10);
s = addDigit(s, rotor2.getNumber(), 10);
s = addDigit(s, rotor1.getNumber(), 10);
s = addDigit(s, 0, 12); //Machine #0
save = save+s;
save = save + ":p" + Plugboard.configurationToString(getState().getConfigurationPlugboard());
return save;
}
}

View File

@ -1,8 +1,12 @@
package de.vanitasvitae.enigmandroid.enigma;
import android.app.Activity;
import android.util.Log;
import java.security.SecureRandom;
import java.util.Random;
import de.vanitasvitae.enigmandroid.MainActivity;
import de.vanitasvitae.enigmandroid.enigma.rotors.Reflector;
import de.vanitasvitae.enigmandroid.enigma.rotors.Rotor;
@ -34,19 +38,24 @@ public class Enigma_K extends Enigma
protected Reflector reflector;
public Enigma_K(int off)
{
super(off);
}
public Enigma_K()
{
super();
super(80);
machineType = "K";
}
@Override
public void initialize()
{
this.entryWheel = Rotor.createRotor(1, 0, 0);
this.rotor1 = Rotor.createRotor(80, 0, 0);
this.rotor2 = Rotor.createRotor(81, 0, 0);
this.rotor3 = Rotor.createRotor(82, 0, 0);
this.reflector = Reflector.createReflector(80);
this.rotor1 = Rotor.createRotor(machineTypeOffset, 0, 0);
this.rotor2 = Rotor.createRotor(machineTypeOffset+1, 0, 0);
this.rotor3 = Rotor.createRotor(machineTypeOffset+2, 0, 0);
this.reflector = Reflector.createReflector(machineTypeOffset);
}
@Override
@ -65,10 +74,7 @@ public class Enigma_K extends Enigma
}
@Override
public void randomState()
{
Random rand = new SecureRandom();
protected void generateState() {
int rotor1, rotor2=-1, rotor3=-1;
rotor1 = rand.nextInt(3);
while(rotor2 == -1 || rotor2 == rotor1) rotor2 = rand.nextInt(3);
@ -83,10 +89,10 @@ public class Enigma_K extends Enigma
int ring3 = rand.nextInt(26);
int ringRef = rand.nextInt(26);
this.rotor1 = Rotor.createRotor(80 + rotor1, rot1, ring1);
this.rotor2 = Rotor.createRotor(80 + rotor2, rot2, ring2);
this.rotor3 = Rotor.createRotor(80 + rotor3, rot3, ring3);
this.reflector = Reflector.createReflector(80);
this.rotor1 = Rotor.createRotor(machineTypeOffset + rotor1, rot1, ring1);
this.rotor2 = Rotor.createRotor(machineTypeOffset + rotor2, rot2, ring2);
this.rotor3 = Rotor.createRotor(machineTypeOffset + rotor3, rot3, ring3);
this.reflector = Reflector.createReflector(machineTypeOffset);
reflector.setRotation(rotRef);
reflector.setRingSetting(ringRef);
}
@ -155,4 +161,61 @@ public class Enigma_K extends Enigma
return state;
}
@Override
public void restoreState(String mem)
{
long s = Long.valueOf(mem);
s = removeDigit(s,12); //Remove machine type
int r1 = getValue(s,10);
s = removeDigit(s,10);
int r2 = getValue(s,10);
s = removeDigit(s,10);
int r3 = getValue(s,10);
s = removeDigit(s,10);
int rot1 = getValue(s,26);
s = removeDigit(s,26);
int ring1 = getValue(s,26);
s = removeDigit(s,26);
int rot2 = getValue(s,26);
s = removeDigit(s,26);
int ring2 = getValue(s,26);
s = removeDigit(s,26);
int rot3 = getValue(s,26);
s = removeDigit(s,26);
int ring3 = getValue(s,26);
s = removeDigit(s,26);
int rotRef = getValue(s,26);
s = removeDigit(s,26);
int ringRef = getValue(s,26);
this.rotor1 = Rotor.createRotor(machineTypeOffset + r1, rot1, ring1);
this.rotor2 = Rotor.createRotor(machineTypeOffset + r2, rot2, ring2);
this.rotor3 = Rotor.createRotor(machineTypeOffset + r3, rot3, ring3);
this.reflector = Reflector.createReflector(machineTypeOffset);
this.reflector.setRotation(rotRef);
this.reflector.setRingSetting(ringRef);
}
@Override
public String stateToString()
{
String save = "";
long t = reflector.getRingSetting();
t = addDigit(t, reflector.getRotation(), 26);
t = addDigit(t, rotor3.getRingSetting(),26);
t = addDigit(t, rotor3.getRotation(), 26);
t = addDigit(t, rotor2.getRingSetting(),26);
t = addDigit(t, rotor2.getRotation(), 26);
t = addDigit(t, rotor1.getRingSetting(), 26);
t = addDigit(t, rotor1.getRotation(), 26);
t = addDigit(t, rotor3.getNumber(), 10);
t = addDigit(t, rotor2.getNumber(), 10);
t = addDigit(t, rotor1.getNumber(), 10);
t = addDigit(t, 7, 12); //Machine #7
save = save+t;
return save;
}
}

View File

@ -27,131 +27,30 @@ import de.vanitasvitae.enigmandroid.enigma.rotors.Rotor;
*/
public class Enigma_K_Swiss_Airforce extends Enigma_K
{
protected Rotor entryWheel;
protected Rotor rotor1;
protected Rotor rotor2;
protected Rotor rotor3;
protected Reflector reflector;
public Enigma_K_Swiss_Airforce()
{
super();
super(100);
machineType = "KSA";
}
@Override
public void initialize()
public String stateToString()
{
this.entryWheel = Rotor.createRotor(1, 0, 0);
this.rotor1 = Rotor.createRotor(100, 0, 0);
this.rotor2 = Rotor.createRotor(101, 0, 0);
this.rotor3 = Rotor.createRotor(102, 0, 0);
this.reflector = Reflector.createReflector(100);
}
String save = "";
long t = reflector.getRingSetting();
t = addDigit(t, reflector.getRotation(), 26);
t = addDigit(t, rotor3.getRingSetting(),26);
t = addDigit(t, rotor3.getRotation(), 26);
t = addDigit(t, rotor2.getRingSetting(),26);
t = addDigit(t, rotor2.getRotation(), 26);
t = addDigit(t, rotor1.getRingSetting(), 26);
t = addDigit(t, rotor1.getRotation(), 26);
t = addDigit(t, rotor3.getNumber(), 10);
t = addDigit(t, rotor2.getNumber(), 10);
t = addDigit(t, rotor1.getNumber(), 10);
t = addDigit(t, 9, 12); //Machine #9
@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 void randomState()
{
Random rand = new SecureRandom();
int rotor1, rotor2=-1, rotor3=-1;
rotor1 = rand.nextInt(3);
while(rotor2 == -1 || rotor2 == rotor1) rotor2 = rand.nextInt(3);
rotor3 = 3 - rotor1 - rotor2;
int rot1 = rand.nextInt(26);
int rot2 = rand.nextInt(26);
int rot3 = rand.nextInt(26);
int rotRef = rand.nextInt(26);
int ring1 = rand.nextInt(26);
int ring2 = rand.nextInt(26);
int ring3 = rand.nextInt(26);
int ringRef = rand.nextInt(26);
this.rotor1 = Rotor.createRotor(100 + rotor1, rot1, ring1);
this.rotor2 = Rotor.createRotor(100 + rotor2, rot2, ring2);
this.rotor3 = Rotor.createRotor(100 + rotor3, rot3, ring3);
this.reflector = Reflector.createReflector(100);
reflector.setRotation(rotRef);
reflector.setRingSetting(ringRef);
}
@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 = entryWheel.encryptForward(x);
x = rotor1.normalize(x + rotor1.getRotation() - rotor1.getRingSetting());
x = rotor1.encryptForward(x);
x = rotor1.normalize(x - rotor1.getRotation() + rotor1.getRingSetting() + rotor2.getRotation() - rotor2.getRingSetting());
x = rotor2.encryptForward(x);
x = rotor1.normalize(x - rotor2.getRotation() + rotor2.getRingSetting() + rotor3.getRotation() - rotor3.getRingSetting());
x = rotor3.encryptForward(x);
x = rotor1.normalize(x - rotor3.getRotation() + rotor3.getRingSetting() + reflector.getRotation() - reflector.getRingSetting());
//backward direction
x = reflector.encrypt(x);
x = rotor1.normalize(x + rotor3.getRotation() - rotor3.getRingSetting() - reflector.getRotation() + reflector.getRingSetting());
x = rotor3.encryptBackward(x);
x = rotor1.normalize(x + rotor2.getRotation() - rotor2.getRingSetting() - rotor3.getRotation() + rotor3.getRingSetting());
x = rotor2.encryptBackward(x);
x = rotor1.normalize(x + rotor1.getRotation() - rotor1.getRingSetting() - rotor2.getRotation() + rotor2.getRingSetting());
x = rotor1.encryptBackward(x);
x = rotor1.normalize(x - rotor1.getRotation() + rotor1.getRingSetting());
x = entryWheel.encryptBackward(x);
return (char) (x + 65); //Add Offset again, cast back to char and return
}
@Override
public void setState(EnigmaStateBundle state)
{
this.entryWheel = Rotor.createRotor(state.getTypeEntryWheel(), 0, 0);
this.rotor1 = Rotor.createRotor(state.getTypeRotor1(), state.getRotationRotor1(), state.getRingSettingRotor1());
this.rotor2 = Rotor.createRotor(state.getTypeRotor2(), state.getRotationRotor2(), state.getRingSettingRotor2());
this.rotor3 = Rotor.createRotor(state.getTypeRotor3(), state.getRotationRotor3(), state.getRingSettingRotor3());
this.reflector = Reflector.createReflector(state.getTypeReflector());
this.reflector.setRotation(state.getRotationReflector());
this.reflector.setRingSetting(state.getRingSettingReflector());
}
@Override
public EnigmaStateBundle getState() {
EnigmaStateBundle state = new EnigmaStateBundle();
state.setTypeEntryWheel(entryWheel.getNumber());
state.setTypeRotor1(rotor1.getNumber());
state.setTypeRotor2(rotor2.getNumber());
state.setTypeRotor3(rotor3.getNumber());
state.setRotationRotor1(rotor1.getRotation());
state.setRotationRotor2(rotor2.getRotation());
state.setRotationRotor3(rotor3.getRotation());
state.setRingSettingRotor1(rotor1.getRingSetting());
state.setRingSettingRotor2(rotor2.getRingSetting());
state.setRingSettingRotor3(rotor3.getRingSetting());
state.setTypeReflector(reflector.getNumber());
state.setRotationReflector(reflector.getRotation());
state.setRingSettingReflector(reflector.getRingSetting());
return state;
save = save+t;
return save;
}
}

View File

@ -27,131 +27,31 @@ import de.vanitasvitae.enigmandroid.enigma.rotors.Rotor;
*/
public class Enigma_K_Swiss_Standard extends Enigma_K
{
protected Rotor entryWheel;
protected Rotor rotor1;
protected Rotor rotor2;
protected Rotor rotor3;
protected Reflector reflector;
public Enigma_K_Swiss_Standard()
{
super();
super(90);
machineType = "KS";
}
@Override
public void initialize()
public String stateToString()
{
this.entryWheel = Rotor.createRotor(1, 0, 0);
this.rotor1 = Rotor.createRotor(90, 0, 0);
this.rotor2 = Rotor.createRotor(91, 0, 0);
this.rotor3 = Rotor.createRotor(92, 0, 0);
this.reflector = Reflector.createReflector(90);
String save = "";
long t = reflector.getRingSetting();
t = addDigit(t, reflector.getRotation(), 26);
t = addDigit(t, rotor3.getRingSetting(),26);
t = addDigit(t, rotor3.getRotation(), 26);
t = addDigit(t, rotor2.getRingSetting(),26);
t = addDigit(t, rotor2.getRotation(), 26);
t = addDigit(t, rotor1.getRingSetting(), 26);
t = addDigit(t, rotor1.getRotation(), 26);
t = addDigit(t, rotor3.getNumber(), 10);
t = addDigit(t, rotor2.getNumber(), 10);
t = addDigit(t, rotor1.getNumber(), 10);
t = addDigit(t, 8, 12); //Machine #8
save = save+t;
return save;
}
@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 void randomState()
{
Random rand = new SecureRandom();
int rotor1, rotor2=-1, rotor3=-1;
rotor1 = rand.nextInt(3);
while(rotor2 == -1 || rotor2 == rotor1) rotor2 = rand.nextInt(3);
rotor3 = 3 - rotor1 - rotor2;
int rot1 = rand.nextInt(26);
int rot2 = rand.nextInt(26);
int rot3 = rand.nextInt(26);
int rotRef = rand.nextInt(26);
int ring1 = rand.nextInt(26);
int ring2 = rand.nextInt(26);
int ring3 = rand.nextInt(26);
int ringRef = rand.nextInt(26);
this.rotor1 = Rotor.createRotor(90 + rotor1, rot1, ring1);
this.rotor2 = Rotor.createRotor(90 + rotor2, rot2, ring2);
this.rotor3 = Rotor.createRotor(90 + rotor3, rot3, ring3);
this.reflector = Reflector.createReflector(90);
reflector.setRotation(rotRef);
reflector.setRingSetting(ringRef);
}
@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 = entryWheel.encryptForward(x);
x = rotor1.normalize(x + rotor1.getRotation() - rotor1.getRingSetting());
x = rotor1.encryptForward(x);
x = rotor1.normalize(x - rotor1.getRotation() + rotor1.getRingSetting() + rotor2.getRotation() - rotor2.getRingSetting());
x = rotor2.encryptForward(x);
x = rotor1.normalize(x - rotor2.getRotation() + rotor2.getRingSetting() + rotor3.getRotation() - rotor3.getRingSetting());
x = rotor3.encryptForward(x);
x = rotor1.normalize(x - rotor3.getRotation() + rotor3.getRingSetting() + reflector.getRotation() - reflector.getRingSetting());
//backward direction
x = reflector.encrypt(x);
x = rotor1.normalize(x + rotor3.getRotation() - rotor3.getRingSetting() - reflector.getRotation() + reflector.getRingSetting());
x = rotor3.encryptBackward(x);
x = rotor1.normalize(x + rotor2.getRotation() - rotor2.getRingSetting() - rotor3.getRotation() + rotor3.getRingSetting());
x = rotor2.encryptBackward(x);
x = rotor1.normalize(x + rotor1.getRotation() - rotor1.getRingSetting() - rotor2.getRotation() + rotor2.getRingSetting());
x = rotor1.encryptBackward(x);
x = rotor1.normalize(x - rotor1.getRotation() + rotor1.getRingSetting());
x = entryWheel.encryptBackward(x);
return (char) (x + 65); //Add Offset again, cast back to char and return
}
@Override
public void setState(EnigmaStateBundle state)
{
this.entryWheel = Rotor.createRotor(state.getTypeEntryWheel(), 0, 0);
this.rotor1 = Rotor.createRotor(state.getTypeRotor1(), state.getRotationRotor1(), state.getRingSettingRotor1());
this.rotor2 = Rotor.createRotor(state.getTypeRotor2(), state.getRotationRotor2(), state.getRingSettingRotor2());
this.rotor3 = Rotor.createRotor(state.getTypeRotor3(), state.getRotationRotor3(), state.getRingSettingRotor3());
this.reflector = Reflector.createReflector(state.getTypeReflector());
this.reflector.setRotation(state.getRotationReflector());
this.reflector.setRingSetting(state.getRingSettingReflector());
}
@Override
public EnigmaStateBundle getState() {
EnigmaStateBundle state = new EnigmaStateBundle();
state.setTypeEntryWheel(entryWheel.getNumber());
state.setTypeRotor1(rotor1.getNumber());
state.setTypeRotor2(rotor2.getNumber());
state.setTypeRotor3(rotor3.getNumber());
state.setRotationRotor1(rotor1.getRotation());
state.setRotationRotor2(rotor2.getRotation());
state.setRotationRotor3(rotor3.getRotation());
state.setRingSettingRotor1(rotor1.getRingSetting());
state.setRingSettingRotor2(rotor2.getRingSetting());
state.setRingSettingRotor3(rotor3.getRingSetting());
state.setTypeReflector(reflector.getNumber());
state.setRotationReflector(reflector.getRotation());
state.setRingSettingReflector(reflector.getRingSetting());
return state;
}
}

View File

@ -28,25 +28,16 @@ import de.vanitasvitae.enigmandroid.enigma.rotors.Rotor;
*/
public class Enigma_M3 extends Enigma_I
{
protected static int machineTypeOffset = 20;
public Enigma_M3()
{
super();
machineType = "M3";
}
@Override
public void initialize()
{
this.plugboard = new Plugboard();
this.rotor1 = Rotor.createRotor(20, 0, 0);
this.rotor2 = Rotor.createRotor(21, 0, 0);
this.rotor3 = Rotor.createRotor(22, 0, 0);
this.reflector = Reflector.createReflector(20);
}
@Override
public void randomState()
{
Random rand = new SecureRandom();
protected void generateState() {
int rotor1, rotor2=-1, rotor3=-1;
rotor1 = rand.nextInt(8);
while(rotor2 == -1 || rotor2 == rotor1) rotor2 = rand.nextInt(8);
@ -60,9 +51,31 @@ public class Enigma_M3 extends Enigma_I
int ring2 = rand.nextInt(26);
int ring3 = rand.nextInt(26);
this.rotor1 = Rotor.createRotor(20 + rotor1, rot1, ring1);
this.rotor2 = Rotor.createRotor(20 + rotor2, rot2, ring2);
this.rotor3 = Rotor.createRotor(20 + rotor3, rot3, ring3);
this.reflector = Reflector.createReflector(20 + ref);
this.rotor1 = Rotor.createRotor(machineTypeOffset + rotor1, rot1, ring1);
this.rotor2 = Rotor.createRotor(machineTypeOffset + rotor2, rot2, ring2);
this.rotor3 = Rotor.createRotor(machineTypeOffset + rotor3, rot3, ring3);
this.reflector = Reflector.createReflector(machineTypeOffset + ref);
this.plugboard = new Plugboard();
plugboard.setConfiguration(Plugboard.seedToPlugboardConfiguration(rand));
}
@Override
public String stateToString() {
String save = "";
long s = rotor3.getRingSetting();
s = addDigit(s, rotor3.getRotation(), 26);
s = addDigit(s, rotor2.getRingSetting(), 26);
s = addDigit(s, rotor2.getRotation(), 26);
s = addDigit(s, rotor1.getRingSetting(), 26);
s = addDigit(s, rotor1.getRotation(), 26);
s = addDigit(s, rotor3.getNumber(), 10);
s = addDigit(s, rotor2.getNumber(), 10);
s = addDigit(s, rotor1.getNumber(), 10);
s = addDigit(s, 1, 12); //Machine #1
save = save+s;
save = save + ":p" + Plugboard.configurationToString(getState().getConfigurationPlugboard());
return save;
}
}

View File

@ -3,6 +3,7 @@ package de.vanitasvitae.enigmandroid.enigma;
import java.security.SecureRandom;
import java.util.Random;
import de.vanitasvitae.enigmandroid.MainActivity;
import de.vanitasvitae.enigmandroid.enigma.rotors.Reflector;
import de.vanitasvitae.enigmandroid.enigma.rotors.Rotor;
@ -36,6 +37,8 @@ public class Enigma_M4 extends Enigma
private Plugboard plugboard;
protected static int machineTypeOffset = 30;
public Enigma_M4()
{
super();
@ -46,12 +49,13 @@ public class Enigma_M4 extends Enigma
public void initialize()
{
this.plugboard = new Plugboard();
this.rotor1 = Rotor.createRotor(30, 0, 0);
this.rotor2 = Rotor.createRotor(31, 0, 0);
this.rotor3 = Rotor.createRotor(32, 0, 0);
this.rotor4 = Rotor.createRotor(38, 0, 0);
this.reflector = Reflector.createReflector(30);
this.prefAnomaly = true;
this.rotor1 = Rotor.createRotor(machineTypeOffset, 0, 0);
this.rotor2 = Rotor.createRotor(machineTypeOffset+1, 0, 0);
this.rotor3 = Rotor.createRotor(machineTypeOffset+2, 0, 0);
this.rotor4 = Rotor.createRotor(machineTypeOffset + 8, 0, 0);
this.reflector = Reflector.createReflector(machineTypeOffset);
this.prefAnomaly = ((MainActivity) MainActivity.ActivitySingleton.getInstance()
.getActivity()).getPrefAnomaly();
}
@Override
@ -79,17 +83,14 @@ public class Enigma_M4 extends Enigma
}
@Override
public void randomState()
{
Random rand = new SecureRandom();
int rotor1, rotor2=-1, rotor3=-1;
int rotor4;
protected void generateState() {
int r1, r2=-1, r3=-1;
int r4;
int ref;
rotor1 = rand.nextInt(8);
while(rotor2 == -1 || rotor2 == rotor1) rotor2 = rand.nextInt(8);
while(rotor3 == -1 || rotor3 == rotor2 || rotor3 == rotor1) rotor3 = rand.nextInt(8);
rotor4 = rand.nextInt(2);
r1 = rand.nextInt(8);
while(r2 == -1 || r2 == r1) r2 = rand.nextInt(8);
while(r3 == -1 || r3 == r2 || r3 == r1) r3 = rand.nextInt(8);
r4 = rand.nextInt(2);
ref = rand.nextInt(2);
int rot1 = rand.nextInt(26);
@ -103,13 +104,17 @@ public class Enigma_M4 extends Enigma
int ring4 = rand.nextInt(26);
int ringRef = rand.nextInt(26);
this.rotor1 = Rotor.createRotor(30 + rotor1, rot1, ring1);
this.rotor2 = Rotor.createRotor(30 + rotor2, rot2, ring2);
this.rotor3 = Rotor.createRotor(30 + rotor3, rot3, ring3);
this.rotor4 = Rotor.createRotor(38 + rotor4, rot4, ring4);
this.reflector = Reflector.createReflector(30 + ref);
reflector.setRotation(rotRef);
reflector.setRingSetting(ringRef);
this.rotor1 = Rotor.createRotor(machineTypeOffset + r1, rot1, ring1);
this.rotor2 = Rotor.createRotor(machineTypeOffset + r2, rot2, ring2);
this.rotor3 = Rotor.createRotor(machineTypeOffset + r3, rot3, ring3);
this.rotor4 = Rotor.createRotor(machineTypeOffset + 8 + r4, rot4, ring4);
this.reflector = Reflector.createReflector(machineTypeOffset + ref);
this.reflector.setRotation(rotRef);
this.reflector.setRingSetting(ringRef);
this.plugboard = new Plugboard();
this.plugboard.setConfiguration(Plugboard.seedToPlugboardConfiguration(rand));
}
@Override
@ -189,4 +194,82 @@ public class Enigma_M4 extends Enigma
return state;
}
@Override
public void restoreState(String mem)
{
String plugboardConf = mem.substring(mem.lastIndexOf(":p") + 2);
long s = Long.valueOf(mem.substring(0, mem.indexOf(":p")));
s = (s-(s%12))/12; //Remove machine type
int r1 = getValue(s, 10);
s = removeDigit(s, 10);
int r2 = getValue(s, 10);
s = removeDigit(s,10);
int r3 = getValue(s, 10);
s = removeDigit(s,10);
int r4 = getValue(s, 10);
s = removeDigit(s,10);
int ref = getValue(s, 10);
s = removeDigit(s,10);
int rot1 = getValue(s, 26);
s = removeDigit(s,26);
int ring1 = getValue(s, 26);
s = removeDigit(s,26);
int rot2 = getValue(s, 26);
s = removeDigit(s,26);
int ring2 = getValue(s, 26);
s = removeDigit(s,26);
int rot3 = getValue(s, 26);
s = removeDigit(s,26);
int ring3 = getValue(s, 26);
s = removeDigit(s,26);
int rot4 = getValue(s, 26);
s = removeDigit(s,26);
int ring4 = getValue(s, 26);
s = removeDigit(s,26);
int rotRef = getValue(s, 26);
s = removeDigit(s,26);
int ringRef = getValue(s, 26);
this.rotor1 = Rotor.createRotor(machineTypeOffset + r1, rot1, ring1);
this.rotor2 = Rotor.createRotor(machineTypeOffset + r2, rot2, ring2);
this.rotor3 = Rotor.createRotor(machineTypeOffset + r3, rot3, ring3);
this.rotor4 = Rotor.createRotor(machineTypeOffset + r4, rot4, ring4);
this.reflector = Reflector.createReflector(machineTypeOffset + ref);
this.reflector.setRotation(rotRef);
this.reflector.setRingSetting(ringRef);
this.plugboard = new Plugboard();
plugboard.setConfiguration(Plugboard.stringToConfiguration(plugboardConf));
}
@Override
public String stateToString() {
String save = "";
long s = reflector.getRingSetting();
s = addDigit(s, reflector.getRotation(), 26);
s = addDigit(s, rotor4.getRingSetting(), 26);
s = addDigit(s, rotor4.getRotation(), 26);
s = addDigit(s, rotor3.getRingSetting(), 26);
s = addDigit(s, rotor3.getRotation(), 26);
s = addDigit(s, rotor2.getRingSetting(), 26);
s = addDigit(s, rotor2.getRotation(), 26);
s = addDigit(s, rotor1.getRingSetting(), 26);
s = addDigit(s, rotor1.getRotation(), 26);
s = addDigit(s, reflector.getNumber(), 10);
s = addDigit(s, rotor4.getNumber(), 10);
s = addDigit(s, rotor3.getNumber(), 10);
s = addDigit(s, rotor2.getNumber(), 10);
s = addDigit(s, rotor1.getNumber(), 10);
s = addDigit(s, 2, 12);
save = save+s;
save = save + ":p" + Plugboard.configurationToString(getState().getConfigurationPlugboard());
return save;
}
}

View File

@ -34,6 +34,8 @@ public class Enigma_R extends Enigma
protected Reflector reflector;
protected static int machineTypeOffset = 110;
public Enigma_R()
{
super();
@ -43,10 +45,10 @@ public class Enigma_R extends Enigma
public void initialize()
{
this.entryWheel = Rotor.createRotor(1, 0, 0);
this.rotor1 = Rotor.createRotor(110, 0, 0);
this.rotor2 = Rotor.createRotor(111, 0, 0);
this.rotor3 = Rotor.createRotor(112, 0, 0);
this.reflector = Reflector.createReflector(110);
this.rotor1 = Rotor.createRotor(machineTypeOffset, 0, 0);
this.rotor2 = Rotor.createRotor(machineTypeOffset+1, 0, 0);
this.rotor3 = Rotor.createRotor(machineTypeOffset+2, 0, 0);
this.reflector = Reflector.createReflector(machineTypeOffset);
}
@Override
@ -65,10 +67,8 @@ public class Enigma_R extends Enigma
}
@Override
public void randomState()
protected void generateState()
{
Random rand = new SecureRandom();
int rotor1, rotor2=-1, rotor3=-1;
rotor1 = rand.nextInt(3);
while(rotor2 == -1 || rotor2 == rotor1) rotor2 = rand.nextInt(3);
@ -83,10 +83,10 @@ public class Enigma_R extends Enigma
int ring3 = rand.nextInt(26);
int ringRef = rand.nextInt(26);
this.rotor1 = Rotor.createRotor(110 + rotor1, rot1, ring1);
this.rotor2 = Rotor.createRotor(110 + rotor2, rot2, ring2);
this.rotor3 = Rotor.createRotor(110 + rotor3, rot3, ring3);
this.reflector = Reflector.createReflector(110);
this.rotor1 = Rotor.createRotor(machineTypeOffset + rotor1, rot1, ring1);
this.rotor2 = Rotor.createRotor(machineTypeOffset + rotor2, rot2, ring2);
this.rotor3 = Rotor.createRotor(machineTypeOffset + rotor3, rot3, ring3);
this.reflector = Reflector.createReflector(machineTypeOffset);
reflector.setRotation(rotRef);
reflector.setRingSetting(ringRef);
}
@ -154,4 +154,61 @@ public class Enigma_R extends Enigma
return state;
}
@Override
public void restoreState(String mem)
{
long s = Long.valueOf(mem);
s = removeDigit(s,12); //Remove machine type
int r1 = getValue(s,10);
s = removeDigit(s,10);
int r2 = getValue(s,10);
s = removeDigit(s,10);
int r3 = getValue(s,10);
s = removeDigit(s,10);
int rot1 = getValue(s,26);
s = removeDigit(s,26);
int ring1 = getValue(s,26);
s = removeDigit(s,26);
int rot2 = getValue(s,26);
s = removeDigit(s,26);
int ring2 = getValue(s,26);
s = removeDigit(s,26);
int rot3 = getValue(s,26);
s = removeDigit(s,26);
int ring3 = getValue(s,26);
s = removeDigit(s,26);
int rotRef = getValue(s,26);
s = removeDigit(s,26);
int ringRef = getValue(s,26);
this.rotor1 = Rotor.createRotor(machineTypeOffset + r1, rot1, ring1);
this.rotor2 = Rotor.createRotor(machineTypeOffset + r2, rot2, ring2);
this.rotor3 = Rotor.createRotor(machineTypeOffset + r3, rot3, ring3);
this.reflector = Reflector.createReflector(machineTypeOffset);
this.reflector.setRotation(rotRef);
this.reflector.setRingSetting(ringRef);
}
@Override
public String stateToString()
{
String save = "";
long t = reflector.getRingSetting();
t = addDigit(t, reflector.getRotation(), 26);
t = addDigit(t, rotor3.getRingSetting(),26);
t = addDigit(t, rotor3.getRotation(), 26);
t = addDigit(t, rotor2.getRingSetting(),26);
t = addDigit(t, rotor2.getRotation(), 26);
t = addDigit(t, rotor1.getRingSetting(), 26);
t = addDigit(t, rotor1.getRotation(), 26);
t = addDigit(t, rotor3.getNumber(), 10);
t = addDigit(t, rotor2.getNumber(), 10);
t = addDigit(t, rotor1.getNumber(), 10);
t = addDigit(t, 10, 12); //Machine #10
save = save+t;
return save;
}
}

View File

@ -35,6 +35,8 @@ public class Enigma_T extends Enigma
protected Rotor rotor3;
protected Reflector reflector;
protected static int machineTypeOffset = 120;
public Enigma_T()
{
super();
@ -44,10 +46,10 @@ public class Enigma_T extends Enigma
@Override
public void initialize() {
this.entryWheel = Rotor.createRotor(2,0,0);
this.rotor1 = Rotor.createRotor(120, 0, 0);
this.rotor2 = Rotor.createRotor(121, 0, 0);
this.rotor3 = Rotor.createRotor(122, 0, 0);
this.reflector = Reflector.createReflector(120);
this.rotor1 = Rotor.createRotor(machineTypeOffset, 0, 0);
this.rotor2 = Rotor.createRotor(machineTypeOffset+1, 0, 0);
this.rotor3 = Rotor.createRotor(machineTypeOffset+2, 0, 0);
this.reflector = Reflector.createReflector(machineTypeOffset);
}
@Override
@ -66,10 +68,7 @@ public class Enigma_T extends Enigma
}
@Override
public void randomState()
{
Random rand = new SecureRandom();
protected void generateState() {
int rotor1, rotor2=-1, rotor3=-1;
rotor1 = rand.nextInt(8);
while(rotor2 == -1 || rotor2 == rotor1) rotor2 = rand.nextInt(8);
@ -84,10 +83,10 @@ public class Enigma_T extends Enigma
int ring3 = rand.nextInt(26);
int ringRef = rand.nextInt(26);
this.rotor1 = Rotor.createRotor(120 + rotor1, rot1, ring1);
this.rotor2 = Rotor.createRotor(120 + rotor2, rot2, ring2);
this.rotor3 = Rotor.createRotor(120 + rotor3, rot3, ring3);
this.reflector = Reflector.createReflector(120);
this.rotor1 = Rotor.createRotor(machineTypeOffset + rotor1, rot1, ring1);
this.rotor2 = Rotor.createRotor(machineTypeOffset + rotor2, rot2, ring2);
this.rotor3 = Rotor.createRotor(machineTypeOffset + rotor3, rot3, ring3);
this.reflector = Reflector.createReflector(machineTypeOffset);
reflector.setRotation(rotRef);
reflector.setRingSetting(ringRef);
}
@ -155,5 +154,60 @@ public class Enigma_T extends Enigma
return state;
}
@Override
public void restoreState(String mem)
{
long s = Long.valueOf(mem);
s = removeDigit(s,12); //Remove machine type
int r1 = getValue(s,10);
s = removeDigit(s,10);
int r2 = getValue(s,10);
s = removeDigit(s,10);
int r3 = getValue(s,10);
s = removeDigit(s,10);
int rot1 = getValue(s,26);
s = removeDigit(s,26);
int ring1 = getValue(s,26);
s = removeDigit(s,26);
int rot2 = getValue(s,26);
s = removeDigit(s,26);
int ring2 = getValue(s,26);
s = removeDigit(s,26);
int rot3 = getValue(s,26);
s = removeDigit(s,26);
int ring3 = getValue(s,26);
s = removeDigit(s,26);
int rotRef = getValue(s,26);
s = removeDigit(s,26);
int ringRef = getValue(s,26);
this.rotor1 = Rotor.createRotor(machineTypeOffset + r1, rot1, ring1);
this.rotor2 = Rotor.createRotor(machineTypeOffset + r2, rot2, ring2);
this.rotor3 = Rotor.createRotor(machineTypeOffset + r3, rot3, ring3);
this.reflector = Reflector.createReflector(machineTypeOffset);
this.reflector.setRotation(rotRef);
this.reflector.setRingSetting(ringRef);
}
@Override
public String stateToString()
{
String save = "";
long t = reflector.getRingSetting();
t = addDigit(t, reflector.getRotation(), 26);
t = addDigit(t, rotor3.getRingSetting(),26);
t = addDigit(t, rotor3.getRotation(), 26);
t = addDigit(t, rotor2.getRingSetting(),26);
t = addDigit(t, rotor2.getRotation(), 26);
t = addDigit(t, rotor1.getRingSetting(), 26);
t = addDigit(t, rotor1.getRotation(), 26);
t = addDigit(t, rotor3.getNumber(), 10);
t = addDigit(t, rotor2.getNumber(), 10);
t = addDigit(t, rotor1.getNumber(), 10);
t = addDigit(t, 11, 12); //Machine #11
save = save+t;
return save;
}
}

View File

@ -1,5 +1,9 @@
package de.vanitasvitae.enigmandroid.enigma;
import java.util.Random;
import de.vanitasvitae.enigmandroid.enigma.inputPreparer.InputPreparer;
/**
* Plugboard of the enigma
* Copyright (C) 2015 Paul Schaub
@ -53,4 +57,115 @@ public class Plugboard
{
return plugs[(input+plugs.length)%plugs.length];
}
/**
* Interpret a String of Pairs as a configuration for the plugboard
* Any char with an even index is connected to the successor.
* in must not contain duplicates!
* @param in String representation of pairs (eg. AXBHCS...)
* @return connections as int[]
*/
public static int[] stringToConfiguration(String in)
{
String pairs = trimString(new InputPreparer.RemoveIllegalCharacters().prepareString(in));
int[] out = empty;
//Check if in is too long or odd
if(pairs.length() > 26 || pairs.length()/2 == (pairs.length()-1)/2)
{
//Odd length. remove last char. Information loss!
pairs = pairs.substring(0,pairs.length()-1);
}
//Modify out
for(int i=0; i<pairs.length()/2; i++)
{
int a = (int) (pairs.toCharArray()[i*2])-65;
int b = (int) (pairs.toCharArray()[(i*2)+1])-65;
out[a] = b;
out[b] = a;
}
return out;
}
/**
* Remove all duplicate chars x from the String except the first appearance of x.
* String MUST be in upper case!
* @param in String
* @return String
*/
private static String trimString(String in)
{
in = in.toUpperCase();
for(int i=0; i<26; i++)
{
char x = (char)(i+65);
int index = in.indexOf(""+x);
if(index != in.lastIndexOf(""+x))
{
//Remove all duplicates of x
in = in.substring(0, index) + in.substring(index+1).replace(""+x,"");
}
}
return in;
}
/**
* Generate a configuration from a seeded PRNG.
* Not all connections have to be done.
* @param rand Seeded PRNG
* @return configuration
*/
public static int[] seedToPlugboardConfiguration(Random rand)
{
int connectionCount = rand.nextInt(14); //0..13
int[] out = empty;
for(int i=0; i<connectionCount; i++)
{
int rA = rand.nextInt(26);
while(out[rA] != rA) rA = (rA+1)%26;
int rB = rand.nextInt(26);
while(out[rB] != rB) rB = (rB+1)%26;
out[rA] = rB;
out[rB] = rA;
}
return out;
}
/**
* Generate a configuration with full set of connections from a seeded PRNG
* @param rand Seeded PRNG
* @return configuration
*/
public static int[] seedToReflectorConfiguration(Random rand)
{
int[] out = empty;
for(int i=0; i<empty.length; i++)
{
int rA = rand.nextInt(26);
while(out[rA] != rA) rA = (rA+1)%26;
int rB = rand.nextInt(26);
while(out[rB] != rB) rB = (rB+1)%26;
out[rA] = rB;
out[rB] = rA;
}
return out;
}
/**
* Converts a configurations array back to a String representation
* @param c array
* @return String representation
*/
public static String configurationToString(int[] c)
{
String out = "";
for(int i=0; i<c.length; i++) // c.length = 26 (mostly)
{
if(c[i] != i && out.indexOf((char)(c[i])+65)==-1)
{
out += (char) (i+65);
out += (char) (c[i]+65);
}
}
return out;
}
}

View File

@ -2,6 +2,11 @@ package de.vanitasvitae.enigmandroid.enigma.rotors;
import android.util.Log;
import java.util.Random;
import de.vanitasvitae.enigmandroid.MainActivity;
import de.vanitasvitae.enigmandroid.enigma.inputPreparer.InputPreparer;
/**
* Reflector of the enigma machine.
* The reflector was used to reflect the scrambled signal at the end of the wiring back to
@ -31,7 +36,7 @@ public class Reflector
protected int rotation;
protected int ringSetting;
public static final int[] defaultWiring_D_KD_G31 = {8,12,4,19,2,6,5,17,0,24,18,16,1,25,23,22,11,7,10,3,21,20,15,14,9,13};
public static final int[] defaultWiring_D_KD_G31 = {8,12,4,19,2,6,5,17,0,24,18,16,1,25,23,22,11,7,10,3,21,20,15,14,9,13};
/**
* This constructor is not accessible from outside this class file.
@ -95,6 +100,7 @@ public class Reflector
*/
public static Reflector createReflector(int type)
{
Log.d(MainActivity.APP_ID, "Reflectorcreation: "+type);
switch (type)
{
//Enigma I
@ -138,7 +144,7 @@ public class Reflector
case 120: return new ReflectorEnigma_T().setNumber(type);
default:
Log.e("Reflector:"," Tried to create Reflector of invalid type "+type);
Log.e(MainActivity.APP_ID," Tried to create Reflector of invalid type "+type);
return null;
}
}
@ -336,5 +342,4 @@ public class Reflector
super("Ref-R", new int[]{16,24,7,14,6,13,4,2,21,15,20,25,19,5,3,9,0,23,22,12,10,8,18,17,1,11});
}
}
}

View File

@ -2,6 +2,8 @@ package de.vanitasvitae.enigmandroid.enigma.rotors;
import android.util.Log;
import de.vanitasvitae.enigmandroid.MainActivity;
/**
* Rotor super class and inner concrete implementations
* The rotors were the key feature of the enigma used to scramble up input signals into
@ -82,6 +84,7 @@ public class Rotor
*/
public static Rotor createRotor(int type, int rotation, int ringSetting)
{
Log.d(MainActivity.APP_ID, "Rotorcreation: "+type);
switch (type)
{
case 1: return new EntryWheel_QWERTZ().setTypeNumber(type);
@ -166,7 +169,7 @@ public class Rotor
case 126: return new Rotor_T_VII(rotation, ringSetting).setTypeNumber(type);
case 127: return new Rotor_T_VIII(rotation, ringSetting).setTypeNumber(type);
default: Log.e("Rotor:"," Tried to create Rotor of invalid type "+type);
default: Log.e(MainActivity.APP_ID," Tried to create Rotor of invalid type "+type);
return null;
}
}

View File

@ -42,25 +42,17 @@ public abstract class LayoutContainer
protected InputPreparer inputPreparer;
protected MainActivity main;
protected EnigmaStateBundle state;
public abstract Enigma getEnigma();
protected abstract void initializeLayout();
public abstract void resetLayout();
public abstract void setLayoutState(EnigmaStateBundle state);
protected abstract void refreshState();
public abstract void syncStateFromLayoutToEnigma();
public void syncStateFromEnigmaToLayout()
{
this.setLayoutState(getEnigma().getState());
}
public abstract void showRingSettingsDialog();
public LayoutContainer(EnigmaStateBundle state)
{
main = (MainActivity) MainActivity.ActivitySingleton.getInstance().getActivity();
this.inputView = (EditText) main.findViewById(R.id.input);
this.outputView = (EditText) main.findViewById(R.id.output);
input = EditTextAdapter.createEditTextAdapter(inputView, main.getPrefMessageFormatting());
output = EditTextAdapter.createEditTextAdapter(outputView, main.getPrefMessageFormatting());
initializeLayout();
this.state = state;
}
public LayoutContainer()
{
main = (MainActivity) MainActivity.ActivitySingleton.getInstance().getActivity();
@ -75,7 +67,8 @@ public abstract class LayoutContainer
{
if(inputView.getText().length()!=0)
{
getEnigma().setState(getState());
syncStateFromLayoutToEnigma();
String message = inputView.getText().toString();
message = inputPreparer.prepareString(message);
input.setText(message);
@ -84,17 +77,6 @@ public abstract class LayoutContainer
}
}
public EnigmaStateBundle getState()
{
refreshState();
return state;
}
public void setState(EnigmaStateBundle state)
{
this.state = state;
}
public EditTextAdapter getInput()
{
return this.input;

View File

@ -56,7 +56,7 @@ public class LayoutContainer_D extends LayoutContainer
reflectorWiring.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new PluggableDialogBuilder(state).showDialogReflector();
new PluggableDialogBuilder(getEnigma().getState()).showDialogReflector();
}
});
@ -81,7 +81,6 @@ public class LayoutContainer_D extends LayoutContainer
@Override
public void setLayoutState(EnigmaStateBundle state)
{
this.state = state;
this.rotor1PositionView.setSelection(state.getRotationRotor1());
this.rotor2PositionView.setSelection(state.getRotationRotor2());
this.rotor3PositionView.setSelection(state.getRotationRotor3());
@ -89,12 +88,14 @@ public class LayoutContainer_D extends LayoutContainer
}
@Override
protected void refreshState()
public void syncStateFromLayoutToEnigma()
{
EnigmaStateBundle state = getEnigma().getState();
state.setRotationRotor1(rotor1PositionView.getSelectedItemPosition());
state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition());
state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition());
state.setRotationReflector(reflectorPositionView.getSelectedItemPosition());
getEnigma().setState(state);
}
public Enigma_D getEnigma()
@ -106,6 +107,6 @@ public class LayoutContainer_D extends LayoutContainer
public void showRingSettingsDialog()
{
new RingSettingsDialogBuilder.RingSettingsDialogBuilderRotRotRotRef().
createRingSettingsDialog(state);
createRingSettingsDialog(getEnigma().getState());
}
}

View File

@ -28,55 +28,17 @@ import de.vanitasvitae.enigmandroid.enigma.Enigma_G260;
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* @author vanitasvitae
*/
public class LayoutContainer_G260 extends LayoutContainer
public class LayoutContainer_G260 extends LayoutContainer_G31
{
private Enigma_G260 enigma;
protected int offsetRot = 60;
protected Spinner rotor1View;
protected Spinner rotor2View;
protected Spinner rotor3View;
protected Spinner rotor1PositionView;
protected Spinner rotor2PositionView;
protected Spinner rotor3PositionView;
protected Spinner reflectorPositionView;
protected static int offsetRot = 60;
public LayoutContainer_G260()
{
super();
super(60);
main.setTitle("G260 - EnigmAndroid");
this.resetLayout();
}
@Override
public Enigma getEnigma() {
return this.enigma;
}
@Override
protected void initializeLayout() {
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.rotor1PositionView = (Spinner) main.findViewById(R.id.rotor1position);
this.rotor2PositionView = (Spinner) main.findViewById(R.id.rotor2position);
this.rotor3PositionView = (Spinner) main.findViewById(R.id.rotor3position);
this.reflectorPositionView = (Spinner) main.findViewById(R.id.reflector_position);
Character[] rotorPositionArray = new Character[26];
for(int i=0; i<26; i++) {rotorPositionArray[i] = (char) (65+i); /*Fill with A..Z*/}
prepareSpinnerAdapter(rotor1View, R.array.rotors_1_3);
prepareSpinnerAdapter(rotor2View, R.array.rotors_1_3);
prepareSpinnerAdapter(rotor3View, R.array.rotors_1_3);
prepareSpinnerAdapter(rotor1PositionView, rotorPositionArray);
prepareSpinnerAdapter(rotor2PositionView, rotorPositionArray);
prepareSpinnerAdapter(rotor3PositionView, rotorPositionArray);
prepareSpinnerAdapter(reflectorPositionView, rotorPositionArray);
}
@Override
public void resetLayout() {
enigma = new Enigma_G260();
@ -84,36 +46,4 @@ public class LayoutContainer_G260 extends LayoutContainer
output.setText("");
input.setText("");
}
@Override
public void setLayoutState(EnigmaStateBundle state)
{
this.state = state;
this.rotor1View.setSelection(state.getTypeRotor1() - offsetRot);
this.rotor2View.setSelection(state.getTypeRotor2() - offsetRot);
this.rotor3View.setSelection(state.getTypeRotor3() - offsetRot);
this.rotor1PositionView.setSelection(state.getRotationRotor1());
this.rotor2PositionView.setSelection(state.getRotationRotor2());
this.rotor3PositionView.setSelection(state.getRotationRotor3());
this.reflectorPositionView.setSelection(state.getRotationReflector());
}
@Override
protected void refreshState()
{
state.setTypeRotor1(rotor1View.getSelectedItemPosition() + offsetRot);
state.setTypeRotor2(rotor2View.getSelectedItemPosition() + offsetRot);
state.setTypeRotor3(rotor3View.getSelectedItemPosition() + offsetRot);
state.setRotationRotor1(rotor1PositionView.getSelectedItemPosition());
state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition());
state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition());
state.setRotationReflector(reflectorPositionView.getSelectedItemPosition());
}
@Override
public void showRingSettingsDialog()
{
new RingSettingsDialogBuilder.RingSettingsDialogBuilderRotRotRotRef().
createRingSettingsDialog(state);
}
}

View File

@ -30,7 +30,7 @@ import de.vanitasvitae.enigmandroid.enigma.Enigma_G31;
*/
public class LayoutContainer_G31 extends LayoutContainer
{
private Enigma_G31 enigma;
protected Enigma enigma;
protected int offsetRot = 40;
@ -43,6 +43,12 @@ public class LayoutContainer_G31 extends LayoutContainer
protected Spinner rotor3PositionView;
protected Spinner reflectorPositionView;
public LayoutContainer_G31(int off)
{
super();
this.offsetRot = off;
}
public LayoutContainer_G31()
{
super();
@ -88,7 +94,6 @@ public class LayoutContainer_G31 extends LayoutContainer
@Override
public void setLayoutState(EnigmaStateBundle state)
{
this.state = state;
this.rotor1View.setSelection(state.getTypeRotor1() - offsetRot);
this.rotor2View.setSelection(state.getTypeRotor2() - offsetRot);
this.rotor3View.setSelection(state.getTypeRotor3() - offsetRot);
@ -99,8 +104,9 @@ public class LayoutContainer_G31 extends LayoutContainer
}
@Override
protected void refreshState()
public void syncStateFromLayoutToEnigma()
{
EnigmaStateBundle state = getEnigma().getState();
state.setTypeRotor1(rotor1View.getSelectedItemPosition() + offsetRot);
state.setTypeRotor2(rotor2View.getSelectedItemPosition() + offsetRot);
state.setTypeRotor3(rotor3View.getSelectedItemPosition() + offsetRot);
@ -108,12 +114,13 @@ public class LayoutContainer_G31 extends LayoutContainer
state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition());
state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition());
state.setRotationReflector(reflectorPositionView.getSelectedItemPosition());
getEnigma().setState(state);
}
@Override
public void showRingSettingsDialog()
{
new RingSettingsDialogBuilder.RingSettingsDialogBuilderRotRotRotRef().
createRingSettingsDialog(state);
createRingSettingsDialog(getEnigma().getState());
}
}

View File

@ -28,55 +28,15 @@ import de.vanitasvitae.enigmandroid.enigma.Enigma_G312;
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* @author vanitasvitae
*/
public class LayoutContainer_G312 extends LayoutContainer
public class LayoutContainer_G312 extends LayoutContainer_G31
{
private Enigma_G312 enigma;
protected int offsetRot = 50;
protected Spinner rotor1View;
protected Spinner rotor2View;
protected Spinner rotor3View;
protected Spinner rotor1PositionView;
protected Spinner rotor2PositionView;
protected Spinner rotor3PositionView;
protected Spinner reflectorPositionView;
public LayoutContainer_G312()
{
super();
super(50);
main.setTitle("G312 - EnigmAndroid");
this.resetLayout();
}
@Override
public Enigma getEnigma() {
return this.enigma;
}
@Override
protected void initializeLayout() {
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.rotor1PositionView = (Spinner) main.findViewById(R.id.rotor1position);
this.rotor2PositionView = (Spinner) main.findViewById(R.id.rotor2position);
this.rotor3PositionView = (Spinner) main.findViewById(R.id.rotor3position);
this.reflectorPositionView = (Spinner) main.findViewById(R.id.reflector_position);
Character[] rotorPositionArray = new Character[26];
for(int i=0; i<26; i++) {rotorPositionArray[i] = (char) (65+i); /*Fill with A..Z*/}
prepareSpinnerAdapter(rotor1View, R.array.rotors_1_3);
prepareSpinnerAdapter(rotor2View, R.array.rotors_1_3);
prepareSpinnerAdapter(rotor3View, R.array.rotors_1_3);
prepareSpinnerAdapter(rotor1PositionView, rotorPositionArray);
prepareSpinnerAdapter(rotor2PositionView, rotorPositionArray);
prepareSpinnerAdapter(rotor3PositionView, rotorPositionArray);
prepareSpinnerAdapter(reflectorPositionView, rotorPositionArray);
}
@Override
public void resetLayout() {
enigma = new Enigma_G312();
@ -84,36 +44,4 @@ public class LayoutContainer_G312 extends LayoutContainer
output.setText("");
input.setText("");
}
@Override
public void setLayoutState(EnigmaStateBundle state)
{
this.state = state;
this.rotor1View.setSelection(state.getTypeRotor1() - offsetRot);
this.rotor2View.setSelection(state.getTypeRotor2() - offsetRot);
this.rotor3View.setSelection(state.getTypeRotor3() - offsetRot);
this.rotor1PositionView.setSelection(state.getRotationRotor1());
this.rotor2PositionView.setSelection(state.getRotationRotor2());
this.rotor3PositionView.setSelection(state.getRotationRotor3());
this.reflectorPositionView.setSelection(state.getRotationReflector());
}
@Override
protected void refreshState()
{
state.setTypeRotor1(rotor1View.getSelectedItemPosition() + offsetRot);
state.setTypeRotor2(rotor2View.getSelectedItemPosition() + offsetRot);
state.setTypeRotor3(rotor3View.getSelectedItemPosition() + offsetRot);
state.setRotationRotor1(rotor1PositionView.getSelectedItemPosition());
state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition());
state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition());
state.setRotationReflector(reflectorPositionView.getSelectedItemPosition());
}
@Override
public void showRingSettingsDialog()
{
new RingSettingsDialogBuilder.RingSettingsDialogBuilderRotRotRotRef().
createRingSettingsDialog(state);
}
}

View File

@ -62,7 +62,7 @@ public class LayoutContainer_I extends LayoutContainer
setPlugboardButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new PluggableDialogBuilder(state).showDialogPlugboard();
new PluggableDialogBuilder(getEnigma().getState()).showDialogPlugboard();
}
});
@ -90,7 +90,6 @@ public class LayoutContainer_I extends LayoutContainer
@Override
public void setLayoutState(EnigmaStateBundle state)
{
this.state = state;
this.rotor1View.setSelection(state.getTypeRotor1() - 10);
this.rotor2View.setSelection(state.getTypeRotor2() - 10);
this.rotor3View.setSelection(state.getTypeRotor3() - 10);
@ -101,8 +100,9 @@ public class LayoutContainer_I extends LayoutContainer
}
@Override
protected void refreshState()
public void syncStateFromLayoutToEnigma()
{
EnigmaStateBundle state = getEnigma().getState();
state.setTypeRotor1(rotor1View.getSelectedItemPosition() + 10);
state.setTypeRotor2(rotor2View.getSelectedItemPosition() + 10);
state.setTypeRotor3(rotor3View.getSelectedItemPosition() + 10);
@ -110,6 +110,7 @@ public class LayoutContainer_I extends LayoutContainer
state.setRotationRotor1(rotor1PositionView.getSelectedItemPosition());
state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition());
state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition());
getEnigma().setState(state);
}
public Enigma_I getEnigma()
@ -121,6 +122,6 @@ public class LayoutContainer_I extends LayoutContainer
public void showRingSettingsDialog()
{
new RingSettingsDialogBuilder.RingSettingsDialogBuilderRotRotRot().
createRingSettingsDialog(state);
createRingSettingsDialog(getEnigma().getState());
}
}

View File

@ -88,7 +88,6 @@ public class LayoutContainer_K extends LayoutContainer
@Override
public void setLayoutState(EnigmaStateBundle state)
{
this.state = state;
this.rotor1View.setSelection(state.getTypeRotor1() - 80);
this.rotor2View.setSelection(state.getTypeRotor2() - 80);
this.rotor3View.setSelection(state.getTypeRotor3() - 80);
@ -99,8 +98,9 @@ public class LayoutContainer_K extends LayoutContainer
}
@Override
protected void refreshState()
public void syncStateFromLayoutToEnigma()
{
EnigmaStateBundle state = getEnigma().getState();
state.setTypeRotor1(rotor1View.getSelectedItemPosition() + 80);
state.setTypeRotor2(rotor2View.getSelectedItemPosition() + 80);
state.setTypeRotor3(rotor3View.getSelectedItemPosition() + 80);
@ -108,12 +108,13 @@ public class LayoutContainer_K extends LayoutContainer
state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition());
state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition());
state.setRotationReflector(reflectorPositionView.getSelectedItemPosition());
getEnigma().setState(state);
}
@Override
public void showRingSettingsDialog()
{
new RingSettingsDialogBuilder.RingSettingsDialogBuilderRotRotRotRef().
createRingSettingsDialog(state);
createRingSettingsDialog(getEnigma().getState());
}
}

View File

@ -88,7 +88,6 @@ public class LayoutContainer_K_Swiss extends LayoutContainer
@Override
public void setLayoutState(EnigmaStateBundle state)
{
this.state = state;
this.rotor1View.setSelection(state.getTypeRotor1() - 90);
this.rotor2View.setSelection(state.getTypeRotor2() - 90);
this.rotor3View.setSelection(state.getTypeRotor3() - 90);
@ -99,8 +98,9 @@ public class LayoutContainer_K_Swiss extends LayoutContainer
}
@Override
protected void refreshState()
public void syncStateFromLayoutToEnigma()
{
EnigmaStateBundle state = getEnigma().getState();
state.setTypeRotor1(rotor1View.getSelectedItemPosition() + 90);
state.setTypeRotor2(rotor2View.getSelectedItemPosition() + 90);
state.setTypeRotor3(rotor3View.getSelectedItemPosition() + 90);
@ -108,12 +108,13 @@ public class LayoutContainer_K_Swiss extends LayoutContainer
state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition());
state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition());
state.setRotationReflector(reflectorPositionView.getSelectedItemPosition());
getEnigma().setState(state);
}
@Override
public void showRingSettingsDialog()
{
new RingSettingsDialogBuilder.RingSettingsDialogBuilderRotRotRotRef().
createRingSettingsDialog(state);
createRingSettingsDialog(getEnigma().getState());
}
}

View File

@ -88,7 +88,6 @@ public class LayoutContainer_K_Swiss_Airforce extends LayoutContainer
@Override
public void setLayoutState(EnigmaStateBundle state)
{
this.state = state;
this.rotor1View.setSelection(state.getTypeRotor1() - 100);
this.rotor2View.setSelection(state.getTypeRotor2() - 100);
this.rotor3View.setSelection(state.getTypeRotor3() - 100);
@ -99,8 +98,9 @@ public class LayoutContainer_K_Swiss_Airforce extends LayoutContainer
}
@Override
protected void refreshState()
public void syncStateFromLayoutToEnigma()
{
EnigmaStateBundle state = getEnigma().getState();
state.setTypeRotor1(rotor1View.getSelectedItemPosition() + 100);
state.setTypeRotor2(rotor2View.getSelectedItemPosition() + 100);
state.setTypeRotor3(rotor3View.getSelectedItemPosition() + 100);
@ -108,12 +108,13 @@ public class LayoutContainer_K_Swiss_Airforce extends LayoutContainer
state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition());
state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition());
state.setRotationReflector(reflectorPositionView.getSelectedItemPosition());
getEnigma().setState(state);
}
@Override
public void showRingSettingsDialog()
{
new RingSettingsDialogBuilder.RingSettingsDialogBuilderRotRotRotRef().
createRingSettingsDialog(state);
createRingSettingsDialog(getEnigma().getState());
}
}

View File

@ -54,7 +54,7 @@ public class LayoutContainer_M3 extends LayoutContainer_I
setPlugboardButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new PluggableDialogBuilder(state).showDialogPlugboard();
new PluggableDialogBuilder(getEnigma().getState()).showDialogPlugboard();
}
});
@ -82,7 +82,6 @@ public class LayoutContainer_M3 extends LayoutContainer_I
@Override
public void setLayoutState(EnigmaStateBundle state)
{
this.state = state;
this.rotor1View.setSelection(state.getTypeRotor1() - 20);
this.rotor2View.setSelection(state.getTypeRotor2() - 20);
this.rotor3View.setSelection(state.getTypeRotor3() - 20);
@ -93,8 +92,9 @@ public class LayoutContainer_M3 extends LayoutContainer_I
}
@Override
protected void refreshState()
public void syncStateFromLayoutToEnigma()
{
EnigmaStateBundle state = getEnigma().getState();
state.setTypeRotor1(rotor1View.getSelectedItemPosition() + 20);
state.setTypeRotor2(rotor2View.getSelectedItemPosition() + 20);
state.setTypeRotor3(rotor3View.getSelectedItemPosition() + 20);
@ -102,6 +102,7 @@ public class LayoutContainer_M3 extends LayoutContainer_I
state.setRotationRotor1(rotor1PositionView.getSelectedItemPosition());
state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition());
state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition());
getEnigma().setState(state);
}
@Override

View File

@ -72,7 +72,7 @@ public class LayoutContainer_M4 extends LayoutContainer
setPlugboardButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new PluggableDialogBuilder(state).showDialogPlugboard();
new PluggableDialogBuilder(getEnigma().getState()).showDialogPlugboard();
}
});
@ -100,7 +100,6 @@ public class LayoutContainer_M4 extends LayoutContainer
@Override
public void setLayoutState(EnigmaStateBundle state) {
this.state = state;
this.rotor1View.setSelection(state.getTypeRotor1() - 30);
this.rotor2View.setSelection(state.getTypeRotor2() - 30);
this.rotor3View.setSelection(state.getTypeRotor3() - 30);
@ -113,7 +112,8 @@ public class LayoutContainer_M4 extends LayoutContainer
}
@Override
protected void refreshState() {
public void syncStateFromLayoutToEnigma() {
EnigmaStateBundle state = getEnigma().getState();
state.setTypeRotor1(rotor1View.getSelectedItemPosition() + 30);
state.setTypeRotor2(rotor2View.getSelectedItemPosition() + 30);
state.setTypeRotor3(rotor3View.getSelectedItemPosition() + 30);
@ -123,12 +123,13 @@ public class LayoutContainer_M4 extends LayoutContainer
state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition());
state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition());
state.setRotationRotor4(rotor4PositionView.getSelectedItemPosition());
getEnigma().setState(state);
}
@Override
public void showRingSettingsDialog()
{
new RingSettingsDialogBuilder.RingSettingsDialogBuilderRotRotRotRot().
createRingSettingsDialog(state);
createRingSettingsDialog(getEnigma().getState());
}
}

View File

@ -86,7 +86,6 @@ public class LayoutContainer_R extends LayoutContainer
@Override
public void setLayoutState(EnigmaStateBundle state)
{
this.state = state;
this.rotor1View.setSelection(state.getTypeRotor1() - 110);
this.rotor2View.setSelection(state.getTypeRotor2() - 110);
this.rotor3View.setSelection(state.getTypeRotor3() - 110);
@ -97,8 +96,9 @@ public class LayoutContainer_R extends LayoutContainer
}
@Override
protected void refreshState()
public void syncStateFromLayoutToEnigma()
{
EnigmaStateBundle state = getEnigma().getState();
state.setTypeRotor1(rotor1View.getSelectedItemPosition() + 110);
state.setTypeRotor2(rotor2View.getSelectedItemPosition() + 110);
state.setTypeRotor3(rotor3View.getSelectedItemPosition() + 110);
@ -106,12 +106,13 @@ public class LayoutContainer_R extends LayoutContainer
state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition());
state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition());
state.setRotationReflector(reflectorPositionView.getSelectedItemPosition());
getEnigma().setState(state);
}
@Override
public void showRingSettingsDialog()
{
new RingSettingsDialogBuilder.RingSettingsDialogBuilderRotRotRotRef().
createRingSettingsDialog(state);
createRingSettingsDialog(getEnigma().getState());
}
}

View File

@ -1,6 +1,5 @@
package de.vanitasvitae.enigmandroid.layout;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import de.vanitasvitae.enigmandroid.R;
@ -86,7 +85,6 @@ public class LayoutContainer_T extends LayoutContainer
@Override
public void setLayoutState(EnigmaStateBundle state)
{
this.state = state;
this.rotor1View.setSelection(state.getTypeRotor1() - 120);
this.rotor2View.setSelection(state.getTypeRotor2() - 120);
this.rotor3View.setSelection(state.getTypeRotor3() - 120);
@ -98,8 +96,9 @@ public class LayoutContainer_T extends LayoutContainer
}
@Override
protected void refreshState()
public void syncStateFromLayoutToEnigma()
{
EnigmaStateBundle state = getEnigma().getState();
state.setTypeRotor1(rotor1View.getSelectedItemPosition() + 120);
state.setTypeRotor2(rotor2View.getSelectedItemPosition() + 120);
state.setTypeRotor3(rotor3View.getSelectedItemPosition() + 120);
@ -107,12 +106,13 @@ public class LayoutContainer_T extends LayoutContainer
state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition());
state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition());
state.setRotationReflector(reflectorPositionView.getSelectedItemPosition());
getEnigma().setState(state);
}
@Override
public void showRingSettingsDialog()
{
new RingSettingsDialogBuilder.RingSettingsDialogBuilderRotRotRotRef().
createRingSettingsDialog(state);
createRingSettingsDialog(getEnigma().getState());
}
}

View File

@ -0,0 +1,99 @@
package de.vanitasvitae.enigmandroid.layout;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import de.vanitasvitae.enigmandroid.MainActivity;
import de.vanitasvitae.enigmandroid.R;
import de.vanitasvitae.enigmandroid.enigma.EnigmaStateBundle;
/**
* Builder for the dialog that is used to get settings for the rings
* 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 PassphraseDialogBuilder
{
MainActivity main;
View passphraseDialogView;
EditText passphrase;
Button positive;
public PassphraseDialogBuilder()
{
main = (MainActivity) MainActivity.ActivitySingleton.getInstance().getActivity();
passphraseDialogView = View.inflate(main, R.layout.dialog_passphrase, null);
passphrase = (EditText) passphraseDialogView.findViewById(R.id.passphrase);
passphrase.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if(s.length() > 0) positive.setEnabled(true);
else positive.setEnabled(false);
}
});
}
public void showDialog()
{
AlertDialog.Builder builder = new AlertDialog.Builder(main);
builder.setTitle(R.string.hint_passphrase);
Dialog d = builder.setView(passphraseDialogView)
.setCancelable(true)
.setPositiveButton(R.string.dialog_positiv, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
String pass = passphrase.getText().toString();
main.createStateFromSeed(pass);
String message = main.getResources().getString(R.string.dialog_passphrase_set)
+" \'" + pass + "\'";
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_abort,
Toast.LENGTH_SHORT).show();
}
}).create();
d.show();
positive = ((AlertDialog)d).getButton(AlertDialog.BUTTON_POSITIVE);
positive.setEnabled(false);
}
}

View File

@ -3,7 +3,6 @@ package de.vanitasvitae.enigmandroid.layout;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
@ -13,7 +12,6 @@ import android.widget.Toast;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Objects;
import de.vanitasvitae.enigmandroid.MainActivity;
import de.vanitasvitae.enigmandroid.R;
@ -45,6 +43,9 @@ public class PluggableDialogBuilder
protected MainActivity main;
protected EnigmaStateBundle state;
protected boolean allowIncompleteConnections;
protected Button positive;
protected HashSet<Integer> colors;
protected int previouslyPressedButton = -1;
@ -59,6 +60,7 @@ public class PluggableDialogBuilder
public void showDialogPlugboard()
{
allowIncompleteConnections = true;
restoreConfigurationPlugboard();
AlertDialog.Builder adb = new AlertDialog.Builder(main);
adb.setTitle(R.string.title_plugboard_dialog);
@ -71,6 +73,7 @@ public class PluggableDialogBuilder
plugs[i] = buttons.get(i).getConnectedButton();
}
state.setConfigurationPlugboard(plugs);
main.onDialogFinished(state);
Toast.makeText(main.getApplication(), R.string.dialog_plugboard_set, Toast.LENGTH_SHORT).show();
}
})
@ -92,6 +95,7 @@ public class PluggableDialogBuilder
public void showDialogReflector()
{
allowIncompleteConnections = false;
restoreConfigurationReflector();
AlertDialog.Builder adb = new AlertDialog.Builder(main);
adb.setTitle(R.string.title_reflector_dialog);
@ -104,6 +108,7 @@ public class PluggableDialogBuilder
plugs[i] = buttons.get(i).getConnectedButton();
}
state.setConfigurationReflector(plugs);
main.onDialogFinished(state);
Toast.makeText(main.getApplication(), R.string.dialog_reflector_set, Toast.LENGTH_SHORT).show();
}
})
@ -120,6 +125,11 @@ public class PluggableDialogBuilder
lp.width = WindowManager.LayoutParams.MATCH_PARENT;
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
d.show();
positive = ((AlertDialog)d).getButton(AlertDialog.BUTTON_POSITIVE);
if(!allConnectionsDone())
{
positive.setEnabled(false);
}
d.getWindow().setAttributes(lp);
}
public void initializeLayout()
@ -186,6 +196,16 @@ public class PluggableDialogBuilder
}
}
protected boolean allConnectionsDone()
{
for(int i=0; i<buttons.size(); i++)
{
ButtonWrapper b = buttons.get(i);
if(b.getConnectedButton() == i || b.getConnectedButton() == -1) return false;
}
return true;
}
protected void restoreConfigurationPlugboard()
{
restoreConfiguration(state.getConfigurationPlugboard());
@ -235,6 +255,16 @@ public class PluggableDialogBuilder
b1.setResourceID(res);
b2.setResourceID(res);
}
updatePositiveButton();
}
protected void updatePositiveButton()
{
if(!allowIncompleteConnections && positive != null)
{
if(allConnectionsDone()) positive.setEnabled(true);
else positive.setEnabled(false);
}
}
private void setButtonFree(int b)

View File

@ -102,7 +102,7 @@ public abstract class RingSettingsDialogBuilder
}
@Override
protected void showDialog(EnigmaStateBundle stateBundle, ArrayAdapter[] adapters, int[] rIDs, Actions actions)
protected void showDialog(final EnigmaStateBundle stateBundle, ArrayAdapter[] adapters, int[] rIDs, Actions actions)
{
if(adapters.length != 3 || rIDs.length != 3)
{
@ -147,6 +147,7 @@ public abstract class RingSettingsDialogBuilder
(ring1.getSelectedItemPosition()+1) + ", " +
(ring2.getSelectedItemPosition()+1) + ", " +
(ring3.getSelectedItemPosition()+1) + ".";
main.onDialogFinished(stateBundle);
Toast.makeText(main, message, Toast.LENGTH_LONG).show();
}
})
@ -219,7 +220,7 @@ public abstract class RingSettingsDialogBuilder
});
}
@Override
protected void showDialog(EnigmaStateBundle stateBundle, ArrayAdapter[] adapters, int[] rIDs, Actions actions) {
protected void showDialog(final EnigmaStateBundle stateBundle, ArrayAdapter[] adapters, int[] rIDs, Actions actions) {
if(adapters.length != 4 || rIDs.length != 4)
{
Log.d("Enigm|RingSettings", "Length of adapters array or length of rIDs array not equal to 4!");
@ -271,6 +272,7 @@ public abstract class RingSettingsDialogBuilder
(ring2.getSelectedItemPosition()+1) + ", " +
(ring3.getSelectedItemPosition()+1) + ", " +
(ring4.getSelectedItemPosition()+1) + ".";
main.onDialogFinished(stateBundle);
Toast.makeText(main, message, Toast.LENGTH_LONG).show();
}
})

View File

@ -0,0 +1,17 @@
<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">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/hint_passphrase"
android:id="@+id/passphrase"/>
</LinearLayout>
</RelativeLayout>

View File

@ -2,29 +2,50 @@
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity" >
<!-- RESET -->
<item android:id="@+id/action_reset"
android:orderInCategory="95"
android:showAsAction="ifRoom"
android:title="@string/action_reset" />
<!-- SEND -->
<item android:id="@+id/action_send"
android:orderInCategory="96"
android:showAsAction="always"
android:title="@string/action_send"
android:icon="@drawable/ic_send_white_48dp"/>
<item android:id="@+id/action_random_configuration"
<!-- RINGSETTING -->
<item android:id="@+id/action_choose_ringsetting"
android:title="@string/action_choose_ringsettings"
android:orderInCategory="97"
android:showAsAction="ifRoom" />
<!-- ENTER SEED -->
<item android:id="@+id/action_enter_seed"
android:title="@string/action_read_passphrase"
android:showAsAction="ifRoom"
android:orderInCategory="98" />
<!-- RECEIVE QR -->
<item android:id="@+id/action_receive_scan"
android:title="@string/action_read_qr"
android:showAsAction="ifRoom"
android:orderInCategory="99" />
<!-- SHARE QR -->
<item android:id="@+id/action_share_scan"
android:title="@string/action_send_qr"
android:showAsAction="ifRoom"
android:orderInCategory="100" />
<!-- RANDOM -->
<item android:id="@+id/action_random_configuration"
android:orderInCategory="101"
android:showAsAction="ifRoom"
android:title="@string/action_random" />
<item android:id="@+id/action_choose_ringstellung"
android:title="@string/action_choose_ringsettings"
android:orderInCategory="98"
android:showAsAction="never" />
<!-- SETTINGS -->
<item android:id="@+id/action_settings"
android:title="@string/action_settings"
android:orderInCategory="99"
android:showAsAction="never" />
android:title="@string/action_settings"
android:orderInCategory="102"
android:showAsAction="ifRoom" />
<!-- ABOUT -->
<item android:id="@+id/action_about"
android:title="@string/title_action_about"
android:orderInCategory="100"
android:showAsAction="never" />
android:title="@string/title_action_about"
android:orderInCategory="103"
android:showAsAction="ifRoom" />
</menu>

View File

@ -5,6 +5,9 @@
<string name="action_version">Version</string>
<string name="action_reset">Zurücksetzen</string>
<string name="action_random">Zufällige Konfiguration</string>
<string name="action_read_qr">Lese Konfiguration aus QR-Code</string>
<string name="action_send_qr">Teile Konfiguration per QR-Code</string>
<string name="action_read_passphrase">Konfiguration aus Schlüsselwort</string>
<string name="action_settings">Einstellungen</string>
<string name="action_choose_ringsettings">Ringstellung</string>
<string name="action_send">Senden</string>
@ -24,13 +27,14 @@
<string name="hint_reflector_position">Position\nUmkehr-\nWalze</string>
<string name="hint_thin_rotor_position">Position\nWalze 4</string>
<string name="hint_enigma_reflector_wiring">Verkabelung Umkehrwalze</string>
<string name="hint_passphrase">Passphrase eingeben</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>
<string name="error_plug_already_in_use">Fehler: Einer oder mehrere dieser Stecker sind bereits in Benutzung: </string>
<string name="error_no_text_to_send">Nachricht ist leer.</string>
<string name="title_ringsetting">Ringstellungen</string>
<string name="title_plugboard_dialog">Steckbrett-\nverbindungen</string>
<string name="title_plugboard_dialog">Steckbrett-\nVerbindungen</string>
<string name="title_reflector_dialog">Verkabelung Umkehrwalze</string>
<string name="dialog_positiv">OK</string>
<string name="dialog_negativ">Abbrechen</string>
@ -38,6 +42,7 @@
<string name="dialog_ringsettings_success">Setze Ringe auf</string>
<string name="dialog_reflector_set">Umkehrwalze verkabelt.</string>
<string name="dialog_plugboard_set">Steckbrett gesteckert.</string>
<string name="dialog_passphrase_set">Generiere Konfiguration aus Schlüsselwort</string>
<string name="dialog_abort">Keine Änderungen</string>
<string name="message_reset">Enigma zurückgesetzt</string>
<string name="message_random">Enigma auf zufällige Konfiguration gesetzt</string>

View File

@ -6,6 +6,9 @@
<string name="action_version">Version</string>
<string name="action_reset">Reset</string>
<string name="action_random">Random configuration</string>
<string name="action_read_qr">Read configuration from QR-Code</string>
<string name="action_send_qr">Share configuration via QR-Code</string>
<string name="action_read_passphrase">Create configuration from passphrase</string>
<string name="action_choose_ringsettings">Ring-Settings</string>
<string name="action_settings">Settings</string>
<string name="action_send">Send</string>
@ -25,6 +28,7 @@
<string name="hint_reflector_position">Position\nReflector</string>
<string name="hint_thin_rotor_position">Position\nRotor 4</string>
<string name="hint_enigma_reflector_wiring">Wiring Reflector</string>
<string name="hint_passphrase">Enter passphrase</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>
@ -39,6 +43,7 @@
<string name="dialog_ringsettings_success">Set Ring-Settings to</string>
<string name="dialog_reflector_set">Rewired Reflector.</string>
<string name="dialog_plugboard_set">Plugged Plugboard.</string>
<string name="dialog_passphrase_set">Generate configuration from passphrase</string>
<string name="dialog_abort">No changes</string>
<string name="message_reset">Enigma reset</string>
<string name="message_random">Enigma set to random configuration</string>