Compare commits
44 Commits
v0.1.5-27.
...
master
Author | SHA1 | Date |
---|---|---|
|
f45a4129ab | |
|
e100617f43 | |
|
1dbeb7f530 | |
|
a31a653b2e | |
|
bad1850170 | |
|
f4cfdaaf26 | |
|
2961cd4c1f | |
|
6259280078 | |
|
eaf39dbd56 | |
|
3e45620d0d | |
|
309deb5429 | |
|
c4cf30baa3 | |
|
d43fb4c9dd | |
|
7c83ae82d3 | |
|
04137eefab | |
|
7001ea0565 | |
|
8cf9eda715 | |
|
85cdb31e5e | |
|
6ac769df94 | |
|
9417045100 | |
|
dae5e47b6c | |
|
dc5c8fdb82 | |
|
1fac879035 | |
|
e72bd31ccd | |
|
0d9dfb6b0d | |
|
d1d3211cca | |
|
8cd2b6467b | |
|
992c9a924d | |
|
8bab418e2b | |
|
2bc5e62265 | |
|
f9b7be4ea0 | |
|
074b2b30c5 | |
|
e4a0e3ccb8 | |
|
95f449d743 | |
|
82e21e48ec | |
|
8e49652f91 | |
|
63682d6462 | |
|
802b51f91d | |
|
0fa6344f27 | |
|
9d021aaa29 | |
|
5e584acede | |
|
c5a0b549b7 | |
|
3b71d21c71 | |
|
129af285c3 |
|
@ -0,0 +1,30 @@
|
|||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.log
|
||||
*~*
|
||||
*.iml
|
||||
out/
|
||||
.idea/
|
||||
*.ipr
|
||||
*.iws
|
||||
.gradle
|
||||
app/build/
|
||||
build/
|
||||
gradle-app.setting
|
||||
!gradle-wrapper.jar
|
||||
*.class
|
||||
.mtj.tmp/
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
hs_err_pid*
|
||||
*.apk
|
||||
*.ap_
|
||||
*.dex
|
||||
bin/
|
||||
gen/
|
||||
local.properties
|
||||
proguard/
|
||||
.navigation/
|
||||
gen-external-apklibs
|
|
@ -0,0 +1,99 @@
|
|||
# Changelog EnigmAndroid
|
||||
|
||||
## v1.0.2-01.01.2019
|
||||
### Changes
|
||||
* Added support for fastlane metadata
|
||||
* Remove What's new dialog
|
||||
|
||||
## v1.0.1-12.01.2018
|
||||
### Changes
|
||||
* Added language: Brazilian-Portuguese
|
||||
|
||||
## v1.0.0-05.05.2017
|
||||
### Changes
|
||||
* Added Enigma KD
|
||||
* Added "protocol version" to QR-Code-shared configuration strings.
|
||||
This breaks backwards compatibility to older versions, but I added it to enable backwards compatibility in upcoming releases.
|
||||
* Configurations can now be shared to EnigmAndroid as text
|
||||
* Moved preference management to SettingsActivity
|
||||
* Added dialog to choose whether to share configuration via text or via QR-code
|
||||
* Same for receiving
|
||||
* Added TextBox to configuration-share-dialog that lets the user see and copy the
|
||||
configuration string.
|
||||
* Added Whats-new-Dialog
|
||||
* New Icon!
|
||||
* Added Script to automatically generate icons
|
||||
* Reformatted code
|
||||
### TODO
|
||||
* Add tips on long clicks at parts
|
||||
* Move KD right below K
|
||||
* Add intent filters to recognize and automatically handle shared/copied configuration Strings .These are Strings starting with "EnigmAndroid/"
|
||||
* Write tests to ensure correct functionality (Pull Requests welcome)
|
||||
* Add multi-Enigma (select any rotor/reflector etc. Probably wont happen too soon)
|
||||
|
||||
## v0.1.9-09.10.2015
|
||||
### Changes
|
||||
* 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
|
||||
* Reworked Enigma definition (available Rotors/Reflectors/ Entrywheels
|
||||
* Completely verified correct functionality of Enigma T
|
||||
* Added number spelling in spanish, italian
|
||||
* Added backwards compatibility to API level 10 (Gingerbread 2.3.3)
|
||||
|
||||
## v0.1.8-27.09.2015
|
||||
### Changes
|
||||
* Added Enigma G31
|
||||
* Added Enigma G312
|
||||
* Added Enigma G260
|
||||
* Replaced Enigma K with Enigma K, K (Swiss) and K (Swiss, Airforce)
|
||||
* Added Enigma R
|
||||
* Changed identifiers of enigma models
|
||||
* Changed landscape layout of enigma model d
|
||||
* Updated the about-dialog text.
|
||||
* Shortened EnigmaStateBundle
|
||||
* Added different colors to the plugboard-/pluggable reflector dialog. This helps to differentiate connections.
|
||||
* Reworked InputPreparer using decorator pattern and added options to customize input preparation
|
||||
* Reworked Reflector-/Rotor creation/management
|
||||
* Added Button to set the Enigma into a random configuration
|
||||
|
||||
## v0.1.7-15.09.2015
|
||||
### Changes
|
||||
* Added Enigma K
|
||||
* Added Enigma T
|
||||
* Created Plugboard-/pluggable Reflector-Setting-Dialog
|
||||
|
||||
## v0.1.6-10.09.2015
|
||||
### Changes
|
||||
* Fixed about dialog (outdated manual)
|
||||
* Updated CHANGELOG (oops)
|
||||
* Added Enigma D
|
||||
* Added rotor names to ringSettingsDialog
|
||||
* Reworked major parts of the app once again :)
|
||||
* Added option to break messages up into blocks
|
||||
|
||||
## v0.1.5-27.08.2015
|
||||
### Changes
|
||||
* Added french number spelling
|
||||
* Added Enigma Models M3, M4
|
||||
* Added option to select different enigma models into options menu
|
||||
* Added developer class for simple rotor creation (not a feature in the app)
|
||||
* Fixed broken ring settings
|
||||
* Fixed false reset of ring settings when switching from/to landscape mode
|
||||
|
||||
## v0.1.4-15.08.2015
|
||||
### Changes
|
||||
* Reworked the core implementation to follow some principals of Software Engineering
|
||||
* Fixed some layout issues
|
||||
* Fixed anomaly for step by step inputs
|
||||
* Added send/receive text functionality
|
||||
* added missing licenses to class files
|
||||
* Added proper documentation
|
||||
* Extended input interpretation (number spelling in different languages, any unknown special character now becomes 'X'
|
||||
|
||||
## v0.1.3-14.03.2015
|
||||
### Changes
|
||||
* Added About Dialog with ChangeLog-Button
|
||||
* Moved Version Info into About Dialog
|
||||
* Updated License Files
|
||||
* Fixed Landscape Layout
|
|
@ -1,26 +0,0 @@
|
|||
CHANGELOG ENIGMANDROID
|
||||
|
||||
v0.1.5-not.yet.released<
|
||||
*Added french number spelling
|
||||
*Added Enigma Models M3, M4
|
||||
*Added option to select different enigma models into options menu
|
||||
*Added developer class for simple rotor creation (not a feature in the app)
|
||||
*Fixed broken ring settings
|
||||
*Fixed false reset of ring settings when switching from/to landscape mode
|
||||
|
||||
|
||||
v0.1.4-15.08.2015<
|
||||
*Rewrite of the core implementation to follow some principals of Software Engineering
|
||||
*Fixed some layout issues
|
||||
*Fixed anomaly for step by step inputs
|
||||
*Added send/receive text functionality
|
||||
*added missing licenses to class files
|
||||
*Added proper documentation
|
||||
*Extended input interpretation (number spelling in different languages, any unknown special
|
||||
character now becomes 'X'
|
||||
|
||||
v0.1.3-14.03.2015<
|
||||
*Added About Dialog with ChangeLog-Button
|
||||
*Moved Version Info into About Dialog
|
||||
*Updated License Files
|
||||
*Fixed Landscape Layout
|
|
@ -1,19 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.linked.project.id="EnigmAndroid" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="java-gradle" name="Java-Gradle">
|
||||
<configuration>
|
||||
<option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
|
||||
<option name="BUILDABLE" value="false" />
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
|
@ -1,280 +1,676 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
0. Definitions.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
1. Source Code.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
2. Basic Permissions.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
14. Revised Versions of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
NO WARRANTY
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
{one line to give the program's name and a brief idea of what it does.}
|
||||
Copyright (C) {year} {name of author}
|
||||
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
{project} Copyright (C) {year} {fullname}
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
|
@ -1,2 +1,24 @@
|
|||
# EnigmAndroid
|
||||
Android implementation of the famous Enigma machine
|
||||
|
||||
|
||||
[<img src="https://f-droid.org/badge/get-it-on.png" alt="Get it on F-Droid" height="80">](https://f-droid.org/app/de.vanitasvitae.enigmandroid)
|
||||
|
||||
Android implementation of the famous Enigma machine.
|
||||
|
||||
Check out the website at [Jabberhead.tk](https://blog.jabberhead.tk/EnigmAndroid/).
|
||||
|
||||
## Screenshots
|
||||
|
||||
<div style="display:flex;" >
|
||||
<img src="https://raw.githubusercontent.com/vanitasvitae/EnigmAndroid/master/fastlane/metadata/android/en-US/images/phoneScreenshots/shot_01.png" width="40%" >
|
||||
<img src="https://raw.githubusercontent.com/vanitasvitae/EnigmAndroid/master/fastlane/metadata/android/en-US/images/phoneScreenshots/shot_02.png" width="40%" style="margin-left:15px;" >
|
||||
</div>
|
||||
|
||||
<div style="display:flex;" >
|
||||
<img src="https://raw.githubusercontent.com/vanitasvitae/EnigmAndroid/master/fastlane/metadata/android/en-US/images/phoneScreenshots/shot_03.png" width="40%" >
|
||||
<img src="https://raw.githubusercontent.com/vanitasvitae/EnigmAndroid/master/fastlane/metadata/android/en-US/images/phoneScreenshots/shot_04.png" width="40%" style="margin-left:15px;" >
|
||||
</div>
|
||||
|
||||
If you want to support me with a donation, feel free to do so :)
|
||||
|
||||
btc: 1MW2DobbNFfcjxTSYzJhtkmiNS7efwaWFX
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
/build
|
||||
/src/main/java/de/vanitasvitae/enigmandroid/enigma/util/
|
||||
/src/androidTest/
|
||||
/src/main/res/render-icon.sh
|
95
app/app.iml
|
@ -1,95 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="EnigmAndroid" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="android-gradle" name="Android-Gradle">
|
||||
<configuration>
|
||||
<option name="GRADLE_PROJECT_PATH" value=":app" />
|
||||
</configuration>
|
||||
</facet>
|
||||
<facet type="android" name="Android">
|
||||
<configuration>
|
||||
<option name="SELECTED_BUILD_VARIANT" value="debug" />
|
||||
<option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
|
||||
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
|
||||
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
|
||||
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugAndroidTest" />
|
||||
<option name="COMPILE_JAVA_TEST_TASK_NAME" value="compileDebugAndroidTestSources" />
|
||||
<afterSyncTasks>
|
||||
<task>generateDebugAndroidTestSources</task>
|
||||
<task>generateDebugSources</task>
|
||||
</afterSyncTasks>
|
||||
<option name="ALLOW_USER_CONFIGURATION" value="false" />
|
||||
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
|
||||
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
|
||||
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
|
||||
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="false">
|
||||
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
|
||||
<output-test url="file://$MODULE_DIR$/build/intermediates/classes/androidTest/debug" />
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/23.0.0/jars" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Android API 23 Platform" jdkType="Android SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" exported="" name="support-v4-23.0.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-annotations-23.0.0" level="project" />
|
||||
</component>
|
||||
</module>
|
|
@ -1,23 +1,28 @@
|
|||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 23
|
||||
buildToolsVersion "22.0.1"
|
||||
compileSdkVersion 25
|
||||
buildToolsVersion "25.0.3"
|
||||
|
||||
defaultConfig {
|
||||
applicationId "de.vanitasvitae.enigmandroid"
|
||||
minSdkVersion 15
|
||||
targetSdkVersion 23
|
||||
versionCode 11
|
||||
versionName "0.1.5-27.08.2015-beta"
|
||||
minSdkVersion 11
|
||||
targetSdkVersion 25
|
||||
versionCode 18
|
||||
versionName "1.0.2-01.01.2019"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
}
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
disable 'MissingTranslation'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
compile 'com.android.support:support-v4:23.0.0'
|
||||
compile 'com.android.support:support-v4:25.3.1'
|
||||
}
|
||||
|
|
|
@ -4,18 +4,19 @@
|
|||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:fullBackupContent="false"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme" >
|
||||
android:theme="@style/AppTheme">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:label="@string/app_name" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
|
|
@ -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<>(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 name "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 name 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* 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() {
|
||||
int rawBytesLength = rawBytes == null ? 0 : rawBytes.length;
|
||||
return "Format: "+formatName+'\n'+"Contents: "+contents+'\n'+"Raw bytes: ("+rawBytesLength+" bytes)\n"+"Orientation: "+orientation+'\n'+"EC level: "+errorCorrectionLevel+'\n';
|
||||
}
|
||||
|
||||
}
|
|
@ -1,344 +1,509 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.ClipData;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.InputType;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.enigma.Plugboard;
|
||||
import com.google.zxing.integration.android.IntentIntegrator;
|
||||
import com.google.zxing.integration.android.IntentResult;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
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
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* @author vanitasvitae
|
||||
*/
|
||||
public class MainActivity extends Activity
|
||||
{
|
||||
private static final int RESULT_SETTINGS = 1;
|
||||
private static final String URI_CHANGELOG =
|
||||
"https://github.com/vanitasvitae/EnigmAndroid/blob/master/CHANGELOG.txt";
|
||||
private static final 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";
|
||||
public static final int latest_protocol_version = 1;
|
||||
public static final int max_protocol_version = 256;
|
||||
|
||||
LayoutContainer layoutContainer;
|
||||
protected String prefMachineType;
|
||||
protected boolean prefAnomaly;
|
||||
protected String prefNumericLanguage;
|
||||
private LayoutContainer layoutContainer;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
this.prefMachineType = sharedPreferences.getString("prefMachineType", getResources().
|
||||
getStringArray(R.array.pref_list_machine_type)[0]);
|
||||
ActivitySingleton singleton = ActivitySingleton.getInstance();
|
||||
singleton.setActivity(this);
|
||||
updateContentView();
|
||||
layoutContainer = LayoutContainer.createLayoutContainer(prefMachineType);
|
||||
updatePreferenceValues();
|
||||
//Handle shared text
|
||||
Intent intent = getIntent();
|
||||
String action = intent.getAction();
|
||||
String type = intent.getType();
|
||||
private SecureRandom secureRandom;
|
||||
|
||||
if (Intent.ACTION_SEND.equals(action) && type != null) {
|
||||
if ("text/plain".equals(type))
|
||||
{
|
||||
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
|
||||
if (sharedText != null)
|
||||
{
|
||||
layoutContainer.getInputView().setText(sharedText);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
secureRandom = new SecureRandom();
|
||||
ActivitySingleton.getInstance().setActivity(this);
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
SettingsActivity.SettingsSingleton.getInstance(prefs, getResources());
|
||||
layoutContainer = LayoutContainer.createLayoutContainer();
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
}
|
||||
//Handle shared text
|
||||
Intent intent = getIntent();
|
||||
String action = intent.getAction();
|
||||
String type = intent.getType();
|
||||
if (Intent.ACTION_SEND.equals(action) && type != null) {
|
||||
if ("text/plain".equals(type))
|
||||
{
|
||||
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
|
||||
if (sharedText != null)
|
||||
{
|
||||
//If shared text consists of an encoded configuration, try to restore it
|
||||
if(sharedText.startsWith(APP_ID+"/"))
|
||||
restoreStateFromCode(sharedText);
|
||||
//Else put it in the input text box
|
||||
else
|
||||
layoutContainer.getInput().setRawText(sharedText);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateContentView()
|
||||
{
|
||||
switch (prefMachineType)
|
||||
{
|
||||
case "M4":
|
||||
this.setContentView(R.layout.activity_main_m4);
|
||||
break;
|
||||
case "M3":
|
||||
this.setContentView(R.layout.activity_main_i_m3);
|
||||
break;
|
||||
default:
|
||||
this.setContentView(R.layout.activity_main_i_m3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
public SecureRandom getSecureRandom()
|
||||
{
|
||||
return this.secureRandom;
|
||||
}
|
||||
|
||||
private void updatePreferenceValues()
|
||||
{
|
||||
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
this.setPrefMachineType(sharedPreferences.getString("prefMachineType", getResources().
|
||||
getStringArray(R.array.pref_list_machine_type)[0]));
|
||||
this.setPrefAnomaly(sharedPreferences.getBoolean("prefAnomaly", true));
|
||||
this.setPrefNumericLanguage(sharedPreferences.getString("prefNumericLanguage", getResources().
|
||||
getStringArray(R.array.pref_alias_numeric_spelling_language)[0]));
|
||||
}
|
||||
public void onDialogFinished(EnigmaStateBundle state)
|
||||
{
|
||||
layoutContainer.getEnigma().setState(state);
|
||||
}
|
||||
|
||||
public void setPrefMachineType(String type)
|
||||
{
|
||||
if(prefMachineType == null || !prefMachineType.equals(type))
|
||||
{
|
||||
prefMachineType = type;
|
||||
String savedInput = "";
|
||||
if(layoutContainer != null)
|
||||
{
|
||||
savedInput = layoutContainer.getInputView().getText().toString();
|
||||
}
|
||||
updateContentView();
|
||||
layoutContainer = LayoutContainer.createLayoutContainer(prefMachineType);
|
||||
layoutContainer.getInputView().setText(savedInput);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu)
|
||||
{
|
||||
this.getMenuInflater().inflate(R.menu.main, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getPrefMachineType()
|
||||
{
|
||||
if(prefMachineType != null) return prefMachineType;
|
||||
else
|
||||
{
|
||||
updatePreferenceValues();
|
||||
return prefMachineType;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
/**
|
||||
* Handle Options menu clicks
|
||||
*/
|
||||
public boolean onOptionsItemSelected(MenuItem item)
|
||||
{
|
||||
int id = item.getItemId();
|
||||
if (id == R.id.action_reset)
|
||||
{
|
||||
layoutContainer.resetLayout();
|
||||
Toast.makeText(getApplicationContext(), R.string.message_reset,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
}
|
||||
else if (id == R.id.action_send_message)
|
||||
{
|
||||
if(layoutContainer.getOutput().getText().length() == 0)
|
||||
{
|
||||
Toast.makeText(this, R.string.error_no_text_to_send, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
else
|
||||
{
|
||||
Intent sendIntent = new Intent();
|
||||
sendIntent.setAction(Intent.ACTION_SEND);
|
||||
sendIntent.putExtra(Intent.EXTRA_TEXT, layoutContainer.getOutput().getModifiedText());
|
||||
sendIntent.setType("text/plain");
|
||||
startActivity(Intent.createChooser(sendIntent, getResources().getText(R.string.send_to)));
|
||||
}
|
||||
}
|
||||
else if (id == R.id.action_choose_ringsetting)
|
||||
{
|
||||
layoutContainer.showRingSettingsDialog();
|
||||
return true;
|
||||
}
|
||||
else if(id == R.id.action_share_configuration)
|
||||
{
|
||||
showShareConfigurationDialog();
|
||||
}
|
||||
else if (id == R.id.action_restore_configuration)
|
||||
{
|
||||
showReceiveConfigurationDialog();
|
||||
return true;
|
||||
}
|
||||
else if (id == R.id.action_random_configuration)
|
||||
{
|
||||
layoutContainer.getEnigma().randomState();
|
||||
layoutContainer.syncStateFromEnigmaToLayout();
|
||||
Toast.makeText(getApplicationContext(), R.string.message_random,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
layoutContainer.getOutput().setText("");
|
||||
return true;
|
||||
}
|
||||
else if (id == R.id.action_settings)
|
||||
{
|
||||
Intent i = new Intent(this, SettingsActivity.class);
|
||||
startActivityForResult(i, RESULT_SETTINGS);
|
||||
}
|
||||
else if (id == R.id.action_about)
|
||||
{
|
||||
showAboutDialog();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
public void setPrefAnomaly(boolean anomaly)
|
||||
{
|
||||
if(prefAnomaly !=anomaly)
|
||||
{
|
||||
prefAnomaly = anomaly;
|
||||
layoutContainer.getEnigma().setPrefAnomaly(anomaly);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Set the chosen Configuration to the enigma, get the input string from the input text box and
|
||||
* prepare it, set the input to the prepared text, encrypt the prepared input and set the
|
||||
* encrypted string to the output text box and update the spinners to their new positions.
|
||||
* @param v View
|
||||
*/
|
||||
public void doCrypto(View v)
|
||||
{
|
||||
layoutContainer.doCrypto();
|
||||
}
|
||||
|
||||
public boolean getPrefAnomaly()
|
||||
{
|
||||
return prefAnomaly;
|
||||
}
|
||||
/**
|
||||
* Start an intent to share the configuration as QR-Code via Barcode Scanner
|
||||
*/
|
||||
private void shareConfigurationAsQR()
|
||||
{
|
||||
IntentIntegrator QRIntegrator = new IntentIntegrator(this);
|
||||
layoutContainer.syncStateFromLayoutToEnigma();
|
||||
String encoded_state = APP_ID+"/"+layoutContainer.getEnigma().getEncodedState().toString(16);
|
||||
Log.d(APP_ID, "Sharing configuration to QR: "+encoded_state);
|
||||
QRIntegrator.shareText(encoded_state);
|
||||
}
|
||||
|
||||
public void setPrefNumericLanguage(String lang)
|
||||
{
|
||||
if(prefNumericLanguage == null || !prefNumericLanguage.equals(lang))
|
||||
{
|
||||
prefNumericLanguage = lang;
|
||||
layoutContainer.getEnigma().setInputPreparer(InputPreparer.createInputPreparer(lang));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Start an intent to share the configuration as text
|
||||
*/
|
||||
private void shareConfigurationAsText()
|
||||
{
|
||||
Intent sendIntent = new Intent();
|
||||
sendIntent.setAction(Intent.ACTION_SEND);
|
||||
sendIntent.putExtra(Intent.EXTRA_TEXT,
|
||||
APP_ID+"/"+layoutContainer.getEnigma().getEncodedState().toString(16));
|
||||
sendIntent.setType("text/plain");
|
||||
startActivity(Intent.createChooser(sendIntent, getResources().getText(R.string.send_to)));
|
||||
}
|
||||
|
||||
public String getPrefNumericLanguage()
|
||||
{
|
||||
if(prefNumericLanguage != null) return prefNumericLanguage;
|
||||
else
|
||||
{
|
||||
updatePreferenceValues();
|
||||
return prefNumericLanguage;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Start the barcode app to scan a barcode for configuration
|
||||
*/
|
||||
private void receiveConfigurationQR()
|
||||
{
|
||||
IntentIntegrator integrator = new IntentIntegrator(this);
|
||||
integrator.initiateScan();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu)
|
||||
{
|
||||
this.getMenuInflater().inflate(R.menu.main, menu);
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Show a dialog to restore a configuration
|
||||
*/
|
||||
private void receiveConfigurationText()
|
||||
{
|
||||
new PassphraseDialogBuilder().showDialog();
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Handle Options menu clicks
|
||||
*/
|
||||
public boolean onOptionsItemSelected(MenuItem item)
|
||||
{
|
||||
int id = item.getItemId();
|
||||
if (id == R.id.action_reset)
|
||||
{
|
||||
layoutContainer.reset();
|
||||
Toast.makeText(getApplicationContext(), R.string.message_reset,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
}
|
||||
else if (id == R.id.action_choose_ringstellung)
|
||||
{
|
||||
layoutContainer.showRingSettingsDialog();
|
||||
return true;
|
||||
}
|
||||
else if (id == R.id.action_settings)
|
||||
{
|
||||
Intent i = new Intent(this, SettingsActivity.class);
|
||||
startActivityForResult(i, RESULT_SETTINGS);
|
||||
}
|
||||
else if (id == R.id.action_about)
|
||||
{
|
||||
showAboutDialog();
|
||||
return true;
|
||||
}
|
||||
else if (id == R.id.action_send)
|
||||
{
|
||||
if(layoutContainer.getOutputView().getText().length() == 0)
|
||||
{
|
||||
Toast.makeText(this, R.string.error_no_text_to_send, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
else
|
||||
{
|
||||
Intent sendIntent = new Intent();
|
||||
sendIntent.setAction(Intent.ACTION_SEND);
|
||||
sendIntent.putExtra(Intent.EXTRA_TEXT, layoutContainer.getOutputView().getText().toString());
|
||||
sendIntent.setType("text/plain");
|
||||
startActivity(Intent.createChooser(sendIntent, getResources().getText(R.string.send_to)));
|
||||
}
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
/**
|
||||
* Show a Dialog containing information about the app, license, usage, author and a link
|
||||
* to the changelog
|
||||
*/
|
||||
private void showAboutDialog()
|
||||
{
|
||||
final View aboutView = View.inflate(this, R.layout.dialog_about, null);
|
||||
//Get and set Version code
|
||||
PackageInfo pInfo = null;
|
||||
try{ pInfo = getPackageManager().getPackageInfo(this.getPackageName(), 0);}
|
||||
catch (PackageManager.NameNotFoundException e){ e.printStackTrace();}
|
||||
assert pInfo != null;
|
||||
String version = pInfo.versionName+ " ("+pInfo.versionCode+")";
|
||||
TextView versionText = (TextView) aboutView.findViewById(R.id.about_version_section);
|
||||
versionText.setText(version);
|
||||
|
||||
/**
|
||||
* Set the chosen Configuration to the enigma, get the input string from the input textbox and
|
||||
* prepare it, set the input to the prepared text, encrypt the prepared input and set the
|
||||
* encrypted string to the output textbox and update the spinners to their new positions.
|
||||
* @param v View
|
||||
*/
|
||||
public void doCrypto(View v)
|
||||
{
|
||||
if(layoutContainer.getInputView().getText().length()!=0) {
|
||||
layoutContainer.getEnigma().setConfiguration(layoutContainer.createConfiguration());
|
||||
layoutContainer.getEnigma().setPlugboard(new Plugboard(layoutContainer.createPlugboardConfiguration()));
|
||||
String m = layoutContainer.getInputView().getText().toString();
|
||||
m = layoutContainer.getEnigma().getInputPreparer().prepareString(m);
|
||||
layoutContainer.getInputView().setText(m);
|
||||
layoutContainer.getOutputView().setText(layoutContainer.getEnigma().encrypt(m));
|
||||
layoutContainer.updateLayout();
|
||||
}
|
||||
}
|
||||
//Build and show dialog
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle(R.string.title_about_dialog);
|
||||
builder.setView(aboutView)
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(R.string.dialog_positive, new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int id)
|
||||
{
|
||||
dialog.dismiss();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.button_show_changelog, new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int id)
|
||||
{
|
||||
dialog.cancel();
|
||||
openWebPage(URI_CHANGELOG);
|
||||
}
|
||||
}).show();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a Dialog containing information about the app, license, usage, author and a link
|
||||
* to the changelog
|
||||
*/
|
||||
public void showAboutDialog()
|
||||
{
|
||||
final View aboutView = View.inflate(this, R.layout.dialog_about, null);
|
||||
/**
|
||||
* Show a dialog where the user can choose between sharing the configuration via QR-code or
|
||||
* via string (intent or copy-to-clipboard)
|
||||
*/
|
||||
private void showShareConfigurationDialog()
|
||||
{
|
||||
final String configuration = APP_ID+"/"+layoutContainer.getEnigma().getEncodedState().toString(16);
|
||||
final View shareView = View.inflate(this, R.layout.dialog_two_options, null);
|
||||
LinearLayout l = (LinearLayout) shareView.findViewById(R.id.dialog_two_options_lay);
|
||||
EditText e = new EditText(this);
|
||||
e.setText(configuration);
|
||||
e.setInputType(InputType.TYPE_NULL);
|
||||
e.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB){
|
||||
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
|
||||
ClipData clip;
|
||||
clip = ClipData.newPlainText("label", configuration);
|
||||
clipboard.setPrimaryClip(clip);
|
||||
} else{
|
||||
@SuppressWarnings("deprecation")
|
||||
android.text.ClipboardManager clipboard = (android.text.ClipboardManager)getSystemService(CLIPBOARD_SERVICE);
|
||||
clipboard.setText(configuration);
|
||||
}
|
||||
Toast.makeText(getApplicationContext(), R.string.message_clipboard, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
l.addView(e);
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle(R.string.dialog_title_share_configuration)
|
||||
.setView(shareView).setCancelable(true);
|
||||
final Dialog d = builder.create();
|
||||
Button one = (Button) shareView.findViewById(R.id.dialog_two_options_1);
|
||||
one.setText(R.string.dialog_share_qr);
|
||||
one.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
shareConfigurationAsQR();
|
||||
d.dismiss();
|
||||
}
|
||||
});
|
||||
Button two = (Button) shareView.findViewById(R.id.dialog_two_options_2);
|
||||
two.setText(R.string.dialog_share_code);
|
||||
two.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
shareConfigurationAsText();
|
||||
d.dismiss();
|
||||
}
|
||||
});
|
||||
d.show();
|
||||
}
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle(R.string.title_about_dialog);
|
||||
builder.setView(aboutView)
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(R.string.dialog_positiv, new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int id)
|
||||
{
|
||||
dialog.dismiss();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.button_show_changelog, new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int id)
|
||||
{
|
||||
dialog.cancel();
|
||||
openWebPage(URI_CHANGELOG);
|
||||
}
|
||||
}).show();
|
||||
}
|
||||
/**
|
||||
* Show a dialog, where the user can choose between scanning QR-code and entering a string to
|
||||
* restore the encoded configuration
|
||||
*/
|
||||
private void showReceiveConfigurationDialog()
|
||||
{
|
||||
final View shareView = View.inflate(this, R.layout.dialog_two_options, null);
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle(R.string.dialog_title_restore_configuration)
|
||||
.setView(shareView).setCancelable(true);
|
||||
final Dialog d = builder.create();
|
||||
Button one = (Button) shareView.findViewById(R.id.dialog_two_options_1);
|
||||
one.setText(R.string.dialog_restore_qr);
|
||||
one.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
receiveConfigurationQR();
|
||||
d.dismiss();
|
||||
}
|
||||
});
|
||||
Button two = (Button) shareView.findViewById(R.id.dialog_two_options_2);
|
||||
two.setText(R.string.dialog_restore_code);
|
||||
two.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
receiveConfigurationText();
|
||||
d.dismiss();
|
||||
}
|
||||
});
|
||||
d.show();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle preference changes
|
||||
* @param requestCode requestCode
|
||||
* @param resultCode resultCode (RESULT_SETTINGS is defined at the top)
|
||||
* @param data data (not important here)
|
||||
*/
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
/**
|
||||
* Handle Activity Results
|
||||
* @param requestCode requestCode
|
||||
* @param resultCode resultCode (RESULT_SETTINGS is defined at the top)
|
||||
* @param data data
|
||||
*/
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
switch (requestCode) {
|
||||
//Come back from Settings
|
||||
case RESULT_SETTINGS:
|
||||
{
|
||||
applyPreferenceChanges();
|
||||
break;
|
||||
}
|
||||
// Receive from QR
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (requestCode) {
|
||||
case RESULT_SETTINGS:
|
||||
{
|
||||
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
this.setPrefMachineType(sharedPrefs.getString("prefMachineType", getResources()
|
||||
.getStringArray(R.array.pref_list_machine_type)[0]));
|
||||
this.setPrefAnomaly(sharedPrefs.getBoolean("prefAnomaly", true));
|
||||
this.setPrefNumericLanguage(this.prefNumericLanguage = sharedPrefs.getString("prefNumericLanguage", getResources().
|
||||
getStringArray(R.array.pref_alias_numeric_spelling_language)[0]));
|
||||
break;
|
||||
}
|
||||
/**
|
||||
* Handle changes in preferences and apply those changes to the app
|
||||
*/
|
||||
private void applyPreferenceChanges()
|
||||
{
|
||||
SettingsActivity s = SettingsActivity.SettingsSingleton.getInstance();
|
||||
if(s.prefMachineTypeChanged())
|
||||
{
|
||||
layoutContainer = LayoutContainer.createLayoutContainer();
|
||||
}
|
||||
if(s.prefMessageFormattingChanged())
|
||||
{
|
||||
layoutContainer.setEditTextAdapter(s.getPrefMessageFormatting());
|
||||
}
|
||||
if(s.prefNumericLanguageChanged())
|
||||
{
|
||||
layoutContainer.setInputPreparer(InputPreparer.createInputPreparer());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Set EnigmAndroid into a certain state as described in the QR-Code
|
||||
* @param mem content of the QR-Code
|
||||
*/
|
||||
public void restoreStateFromCode(String mem)
|
||||
{
|
||||
if(!mem.startsWith(APP_ID+"/"))
|
||||
{
|
||||
Toast.makeText(this, R.string.error_no_valid_qr, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
else
|
||||
{
|
||||
String inputString = layoutContainer.getInput().getText();
|
||||
mem = mem.substring((APP_ID+"/").length());
|
||||
BigInteger s = new BigInteger(mem, 16);
|
||||
int protocol_version = Enigma.getValue(s, max_protocol_version);
|
||||
s = Enigma.removeDigit(s, max_protocol_version);
|
||||
Log.d(APP_ID,
|
||||
"Try to restore configuration from BigInteger value "+s.toString()+" in protocol version "+protocol_version+".");
|
||||
SettingsActivity.SettingsSingleton.getInstance()
|
||||
.setPrefMachineType(Enigma.chooseEnigmaFromSave(s));
|
||||
layoutContainer = LayoutContainer.createLayoutContainer();
|
||||
layoutContainer.getEnigma().restoreState(Enigma.removeDigit(s,20), protocol_version);
|
||||
layoutContainer.setInputPreparer(InputPreparer.createInputPreparer());
|
||||
layoutContainer.syncStateFromEnigmaToLayout();
|
||||
layoutContainer.getInput().setText(inputString);
|
||||
layoutContainer.getOutput().setText("");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the web page with the URL url
|
||||
* @param url URL of the website
|
||||
*/
|
||||
public void openWebPage(String url) {
|
||||
Uri webPage = Uri.parse(url);
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, webPage);
|
||||
if (intent.resolveActivity(getPackageManager()) != null) {
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Set EnigmAndroid into a state calculated from the seed.
|
||||
* @param seed seed
|
||||
*/
|
||||
public void applyStateFromSeed(String seed)
|
||||
{
|
||||
String inputString = layoutContainer.getInput().getText();
|
||||
SettingsActivity.SettingsSingleton.getInstance()
|
||||
.setPrefMachineType(Enigma.chooseEnigmaFromSeed(seed));
|
||||
layoutContainer = LayoutContainer.createLayoutContainer();
|
||||
layoutContainer.getEnigma().setStateFromSeed(seed);
|
||||
layoutContainer.setInputPreparer(InputPreparer.createInputPreparer());
|
||||
layoutContainer.syncStateFromEnigmaToLayout();
|
||||
layoutContainer.getInput().setText(inputString);
|
||||
layoutContainer.getOutput().setText("");
|
||||
}
|
||||
|
||||
/**
|
||||
* Singleton that grants access to an Activity from anywhere within the app
|
||||
*/
|
||||
public static class ActivitySingleton
|
||||
{
|
||||
private static ActivitySingleton instance = null;
|
||||
private Activity activity;
|
||||
/**
|
||||
* Open the web page with the URL url
|
||||
* @param url URL of the website
|
||||
*/
|
||||
private void openWebPage(String url) {
|
||||
Uri webPage = Uri.parse(url);
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, webPage);
|
||||
if (intent.resolveActivity(getPackageManager()) != null) {
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
||||
//private constructor
|
||||
private ActivitySingleton(){}
|
||||
//Singleton method
|
||||
public static ActivitySingleton getInstance()
|
||||
{
|
||||
if(instance == null) instance = new ActivitySingleton();
|
||||
return instance;
|
||||
}
|
||||
/**
|
||||
* Singleton that grants access to an Activity from anywhere within the app
|
||||
*/
|
||||
public static class ActivitySingleton
|
||||
{
|
||||
private static ActivitySingleton instance = null;
|
||||
private Activity activity;
|
||||
|
||||
/**
|
||||
* Set an Activity that the Singleton returns
|
||||
* @param activity activity that's stored
|
||||
*/
|
||||
public void setActivity(Activity activity)
|
||||
{
|
||||
this.activity = activity;
|
||||
}
|
||||
//private constructor
|
||||
private ActivitySingleton(){}
|
||||
//Singleton method
|
||||
public static ActivitySingleton getInstance()
|
||||
{
|
||||
if(instance == null) instance = new ActivitySingleton();
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the stored Activity
|
||||
* @return stored Activity
|
||||
*/
|
||||
public Activity getActivity()
|
||||
{
|
||||
return activity;
|
||||
}
|
||||
/**
|
||||
* Set an Activity that the Singleton returns
|
||||
* @param activity activity that's stored
|
||||
*/
|
||||
public void setActivity(Activity activity)
|
||||
{
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Returns the stored Activity
|
||||
* @return stored Activity
|
||||
*/
|
||||
public Activity getActivity()
|
||||
{
|
||||
return activity;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
268
app/src/main/java/de/vanitasvitae/enigmandroid/SettingsActivity.java
Executable file → Normal file
|
@ -1,34 +1,254 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Class that represents the settings activity.
|
||||
* 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
|
||||
* Use the singleton to get an instance of this class to get preferences
|
||||
*/
|
||||
public class SettingsActivity extends PreferenceActivity
|
||||
{
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
//noinspection deprecation
|
||||
addPreferencesFromResource(R.xml.pref_page);
|
||||
}
|
||||
}
|
||||
public static final String PREF_NUMERIC_LANGUAGE = "prefNumericLanguage";
|
||||
public static final String PREF_MACHINE_TYPE = "prefMachineType";
|
||||
public static final String PREF_MESSAGE_FORMATTING = "prefMessageFormatting";
|
||||
public static final String PREF_REPLACE_SPECIAL_CHARACTERS = "prefReplaceSpecialCharacters";
|
||||
public static final String PREF_SAVED_ENIGMA_STATE = "prefSavedEnigmaState";
|
||||
public static final String PREF_VERSION_NUMBER = "prefVersionNumber";
|
||||
|
||||
private String previousPrefNumericLanguage;
|
||||
private String previousPrefMachineType;
|
||||
private String previousPrefMessageFormatting;
|
||||
private boolean previousPrefReplaceSpecialCharacters;
|
||||
private String previousPrefSavedEnigmaState;
|
||||
|
||||
private SharedPreferences prefs;
|
||||
private Resources res;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
//noinspection deprecation
|
||||
addPreferencesFromResource(R.xml.pref_page);
|
||||
}
|
||||
|
||||
public void setSharedPreferences(SharedPreferences prefs)
|
||||
{
|
||||
this.prefs = prefs;
|
||||
}
|
||||
|
||||
public void setResources(Resources res)
|
||||
{
|
||||
this.res = res;
|
||||
}
|
||||
|
||||
private boolean isFullyInitialized()
|
||||
{
|
||||
if (prefs == null)
|
||||
{
|
||||
Log.e(MainActivity.APP_ID,
|
||||
"SharedPreferences not initialized via setSharedPreferences!");
|
||||
return false;
|
||||
}
|
||||
if (res == null)
|
||||
{
|
||||
Log.e(MainActivity.APP_ID, "Resources not initialized via setResources!");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getPrefNumericLanguage()
|
||||
{
|
||||
if (isFullyInitialized())
|
||||
return prefs.getString(
|
||||
PREF_NUMERIC_LANGUAGE,
|
||||
res.getStringArray(R.array.pref_alias_message_formatting)[0]);
|
||||
else return null;
|
||||
}
|
||||
|
||||
public void setPrefNumericLanguage(String lang)
|
||||
{
|
||||
if (isFullyInitialized())
|
||||
prefs.edit().putString(PREF_NUMERIC_LANGUAGE, lang).apply();
|
||||
}
|
||||
|
||||
public boolean prefNumericLanguageChanged()
|
||||
{
|
||||
if (this.previousPrefNumericLanguage == null || !this.previousPrefNumericLanguage.equals(
|
||||
getPrefNumericLanguage()))
|
||||
{
|
||||
this.previousPrefNumericLanguage = this.getPrefNumericLanguage();
|
||||
Log.d(MainActivity.APP_ID, PREF_NUMERIC_LANGUAGE+" changed!");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether special characters will be replaced.
|
||||
* If the SettingsActivity is not fully initialized return false and ignore preference.
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean getPrefReplaceSpecialCharacters()
|
||||
{
|
||||
return isFullyInitialized() && prefs.getBoolean(PREF_REPLACE_SPECIAL_CHARACTERS, true);
|
||||
}
|
||||
|
||||
public void setPrefReplaceSpecialCharacters(boolean replace)
|
||||
{
|
||||
if (isFullyInitialized())
|
||||
prefs.edit().putBoolean(PREF_REPLACE_SPECIAL_CHARACTERS, replace).apply();
|
||||
}
|
||||
|
||||
public boolean prefReplaceSpecialCharactersChanged()
|
||||
{
|
||||
boolean changed = previousPrefReplaceSpecialCharacters != getPrefReplaceSpecialCharacters();
|
||||
if (changed)
|
||||
{
|
||||
previousPrefReplaceSpecialCharacters = getPrefReplaceSpecialCharacters();
|
||||
Log.d(MainActivity.APP_ID, PREF_REPLACE_SPECIAL_CHARACTERS+" changed!");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getPrefMachineType()
|
||||
{
|
||||
if (isFullyInitialized())
|
||||
return prefs.getString(PREF_MACHINE_TYPE,
|
||||
res.getStringArray(R.array.pref_alias_machine_type)[0]);
|
||||
else return null;
|
||||
}
|
||||
|
||||
public void setPrefMachineType(String pref)
|
||||
{
|
||||
if (isFullyInitialized())
|
||||
prefs.edit().putString(PREF_MACHINE_TYPE, pref).apply();
|
||||
}
|
||||
|
||||
public boolean prefMachineTypeChanged()
|
||||
{
|
||||
if (this.previousPrefMachineType == null || !this.previousPrefMachineType.equals(
|
||||
getPrefMachineType()))
|
||||
{
|
||||
this.previousPrefMachineType = this.getPrefMachineType();
|
||||
Log.d(MainActivity.APP_ID, PREF_MACHINE_TYPE+" changed!");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getPrefSavedEnigmaState()
|
||||
{
|
||||
if (isFullyInitialized())
|
||||
return prefs.getString(PREF_SAVED_ENIGMA_STATE, "-1");
|
||||
else return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param state HEX
|
||||
*/
|
||||
public void setPrefSavedEnigmaState(String state)
|
||||
{
|
||||
if (isFullyInitialized())
|
||||
prefs.edit().putString(PREF_SAVED_ENIGMA_STATE, state).apply();
|
||||
}
|
||||
|
||||
public boolean prefSavedEnigmaStateChanged()
|
||||
{
|
||||
if (this.previousPrefSavedEnigmaState == null || !this.previousPrefSavedEnigmaState
|
||||
.equals(getPrefSavedEnigmaState()))
|
||||
{
|
||||
this.previousPrefSavedEnigmaState = this.getPrefSavedEnigmaState();
|
||||
Log.d(MainActivity.APP_ID, PREF_SAVED_ENIGMA_STATE+" changed!");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getPrefMessageFormatting()
|
||||
{
|
||||
if (isFullyInitialized())
|
||||
return prefs.getString(SettingsActivity.PREF_MESSAGE_FORMATTING,
|
||||
res.getStringArray(R.array.pref_alias_message_formatting)[0]);
|
||||
else return null;
|
||||
}
|
||||
|
||||
public void setPrefMessageFormatting(String format)
|
||||
{
|
||||
if (isFullyInitialized())
|
||||
prefs.edit().putString(PREF_MESSAGE_FORMATTING, format).apply();
|
||||
}
|
||||
|
||||
public boolean prefMessageFormattingChanged()
|
||||
{
|
||||
if (this.previousPrefMessageFormatting == null || !this.previousPrefMessageFormatting
|
||||
.equals(getPrefMessageFormatting()))
|
||||
{
|
||||
this.previousPrefMessageFormatting = this.getPrefMessageFormatting();
|
||||
Log.d(MainActivity.APP_ID, PREF_MESSAGE_FORMATTING+" changed!");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getVersionNumber()
|
||||
{
|
||||
if (isFullyInitialized())
|
||||
return prefs.getInt(PREF_VERSION_NUMBER, -1);
|
||||
else return -1;
|
||||
}
|
||||
|
||||
public void setVersionNumber(int v)
|
||||
{
|
||||
if (isFullyInitialized())
|
||||
prefs.edit().putInt(PREF_VERSION_NUMBER, v).apply();
|
||||
}
|
||||
|
||||
public static class SettingsSingleton extends SettingsActivity
|
||||
{
|
||||
private static SettingsActivity instance;
|
||||
|
||||
private SettingsSingleton()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public static SettingsActivity getInstance(SharedPreferences prefs, Resources res)
|
||||
{
|
||||
instance = new SettingsActivity();
|
||||
instance.setSharedPreferences(prefs);
|
||||
instance.setResources(res);
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static SettingsActivity getInstance()
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
instance = new SettingsActivity();
|
||||
Log.d(MainActivity.APP_ID, "Created new SettingsActivity!");
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,168 +1,291 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.enigma;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.enigma.inputPreparer.InputPreparer;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.EntryWheel;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Reflector;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Rotor;
|
||||
|
||||
/**
|
||||
* Main component of the Enigma machine
|
||||
* This is the mostly abstract base of any enigma machine.
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* @author vanitasvitae
|
||||
*/
|
||||
public abstract class Enigma
|
||||
{
|
||||
protected static String machineType;
|
||||
protected boolean doAnomaly = false; //Has the time come to handle an anomaly?
|
||||
protected boolean prefAnomaly; //Do you WANT to simulate the anomaly?
|
||||
protected InputPreparer inputPreparer;
|
||||
static String machineType;
|
||||
|
||||
/**
|
||||
* Set the enigma to an initial state
|
||||
*/
|
||||
public abstract void initialize();
|
||||
boolean doAnomaly = false; //Has the time come to handle an anomaly?
|
||||
|
||||
/**
|
||||
* Set the reflector of the enigma machine to one of type type.
|
||||
* @param type type indicator of the reflector
|
||||
* @return success (not every reflector fits in every machine)
|
||||
*/
|
||||
public abstract boolean setReflector(int type);
|
||||
ArrayList<EntryWheel> availableEntryWheels;
|
||||
ArrayList<Rotor> availableRotors;
|
||||
ArrayList<Reflector> availableReflectors;
|
||||
|
||||
/**
|
||||
* Set the rotor on position pos to a rotor of type type with ring-setting ringSetting and
|
||||
* rotation rotation.
|
||||
* @param pos position of the rotor
|
||||
* @param type type indicator
|
||||
* @param ringSetting ringSetting
|
||||
* @param rotation rotation
|
||||
* @return success
|
||||
*/
|
||||
public abstract boolean setRotor(int pos, int type, int ringSetting, int rotation);
|
||||
Random rand;
|
||||
|
||||
/**
|
||||
* Encrypt / Decrypt a given String w.
|
||||
* w must be prepared using prepare(w) beforehand.
|
||||
* Doing so changes the state of the rotors but not the state of the plugboard and the
|
||||
* ringSettings
|
||||
*
|
||||
* @param w Text to decrypt/encrypt
|
||||
* @return encrypted/decrypted string
|
||||
*/
|
||||
public String encrypt(String w)
|
||||
{
|
||||
//output string
|
||||
String output = "";
|
||||
//for each char x in k
|
||||
for (char x : w.toCharArray())
|
||||
{
|
||||
output = output + this.encryptChar(x);
|
||||
}
|
||||
//return en-/decrypted string
|
||||
return output;
|
||||
}
|
||||
Enigma()
|
||||
{
|
||||
establishAvailableParts();
|
||||
initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the enigma into the next mechanical state.
|
||||
* This rotates the first rotor and eventually also the second/third.
|
||||
* Also this method handles the anomaly in case it should happen.
|
||||
*/
|
||||
public abstract void nextState();
|
||||
/**
|
||||
* In this method, available EntryWheels, Rotors and Reflectors can be defined.
|
||||
*/
|
||||
protected abstract void establishAvailableParts();
|
||||
|
||||
/**
|
||||
* Substitute char k by sending the signal through the enigma.
|
||||
* The signal passes the plugboard, the rotors and returns back after going through the
|
||||
* reflector wheel.
|
||||
*
|
||||
* @param k input char
|
||||
* @return substituted output char
|
||||
*/
|
||||
public abstract char encryptChar(char k);
|
||||
/**
|
||||
* Add a Rotor to the ArrayList of available rotors for this machine.
|
||||
* Also set the index of the Rotor.
|
||||
* @param r Rotor
|
||||
*/
|
||||
void addAvailableRotor(Rotor r)
|
||||
{
|
||||
if(availableRotors == null) availableRotors = new ArrayList<>();
|
||||
availableRotors.add(availableRotors.size(), r.setIndex(availableRotors.size()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize the input.
|
||||
* Normalizing means keeping the input via modulo in the range from 0 to n-1, where n is equal
|
||||
* to the size of the rotors.
|
||||
* This is necessary since java allows negative modulo values,
|
||||
* which can break this implementation
|
||||
* @param input input signal
|
||||
* @return "normalized" input signal
|
||||
*/
|
||||
public abstract int normalize(int input);
|
||||
void addAvailableEntryWheel(EntryWheel e)
|
||||
{
|
||||
if(availableEntryWheels == null) availableEntryWheels = new ArrayList<>();
|
||||
availableEntryWheels.add(availableEntryWheels.size(), e.setIndex(availableEntryWheels.size()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set config of the enigma
|
||||
*
|
||||
* @param conf configuration
|
||||
*/
|
||||
public abstract void setConfiguration(int[] conf);
|
||||
void addAvailableReflector(Reflector r)
|
||||
{
|
||||
if(availableReflectors == null) availableReflectors = new ArrayList<>();
|
||||
availableReflectors.add(availableReflectors.size(), r.setIndex(availableReflectors.size()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the plugboard
|
||||
* @param p Plugboard
|
||||
*/
|
||||
public abstract void setPlugboard(Plugboard p);
|
||||
public ArrayList<EntryWheel> getAvailableEntryWheels()
|
||||
{
|
||||
return availableEntryWheels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the configuration, the enigma machine is in right NOW
|
||||
*
|
||||
* @return array containing configuration
|
||||
*/
|
||||
public abstract int[] getConfiguration();
|
||||
public ArrayList<Rotor> getAvailableRotors()
|
||||
{
|
||||
return availableRotors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the inputPreparer
|
||||
* @param preparer concrete InputPreparer
|
||||
*/
|
||||
public void setInputPreparer(InputPreparer preparer)
|
||||
{
|
||||
this.inputPreparer = preparer;
|
||||
}
|
||||
public ArrayList<Reflector> getAvailableReflectors()
|
||||
{
|
||||
return availableReflectors;
|
||||
}
|
||||
|
||||
EntryWheel getEntryWheel(int index)
|
||||
{
|
||||
if(availableEntryWheels == null || availableEntryWheels.size() == 0) return null;
|
||||
return availableEntryWheels.get(index % availableEntryWheels.size()).getInstance();
|
||||
}
|
||||
|
||||
Rotor getRotor(int index)
|
||||
{
|
||||
if(availableRotors == null || availableRotors.size() == 0) return null;
|
||||
return availableRotors.get(index % availableRotors.size()).getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the inputPreparer
|
||||
* @return inputPreparer
|
||||
*/
|
||||
public InputPreparer getInputPreparer()
|
||||
{
|
||||
if(inputPreparer == null)
|
||||
{
|
||||
MainActivity main = (MainActivity) MainActivity.ActivitySingleton.getInstance().getActivity();
|
||||
inputPreparer = InputPreparer.createInputPreparer(main.getPrefNumericLanguage());
|
||||
}
|
||||
return this.inputPreparer;
|
||||
}
|
||||
Rotor getRotor(int index, int rotation, int ringSetting)
|
||||
{
|
||||
return getRotor(index).setRotation(rotation).setRingSetting(ringSetting);
|
||||
}
|
||||
|
||||
/**
|
||||
* set prefAnomaly variable
|
||||
* @param b boolean
|
||||
*/
|
||||
public void setPrefAnomaly(boolean b)
|
||||
{
|
||||
this.prefAnomaly = b;
|
||||
}
|
||||
Reflector getReflector(int index)
|
||||
{
|
||||
if(availableReflectors == null || availableReflectors.size() == 0) return null;
|
||||
return availableReflectors.get(index%availableReflectors.size()).getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type indicator of the enigma machine
|
||||
* @return type
|
||||
*/
|
||||
public String getMachineType()
|
||||
{
|
||||
return machineType;
|
||||
}
|
||||
Reflector getReflector(int index, int rotation, int ringSetting)
|
||||
{
|
||||
return getReflector(index).setRotation(rotation).setRingSetting(ringSetting);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the enigma to an initial state
|
||||
*/
|
||||
protected abstract void initialize();
|
||||
|
||||
/**
|
||||
* Encrypt / Decrypt a given String w.
|
||||
* w must be prepared using prepare(w) beforehand.
|
||||
* Doing so changes the state of the rotors but not the state of the plugboard and the
|
||||
* ringSettings
|
||||
*
|
||||
* @param w Text to decrypt/encryptString
|
||||
* @return encrypted/decrypted string
|
||||
*/
|
||||
public String encryptString(String w)
|
||||
{
|
||||
//output string
|
||||
String output = "";
|
||||
//for each char x in k
|
||||
for (char x : w.toCharArray())
|
||||
{
|
||||
output = output + this.encryptChar(x);
|
||||
}
|
||||
//return en-/decrypted string
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the enigma into the next mechanical state.
|
||||
* This rotates the first rotor and eventually also the second/third.
|
||||
* Also this method handles the anomaly in case it should happen.
|
||||
*/
|
||||
public abstract void nextState();
|
||||
|
||||
/**
|
||||
* Set the enigma into a completely random state using a unseeded SecureRandom object.
|
||||
*/
|
||||
public void randomState()
|
||||
{
|
||||
this.rand = ((MainActivity) (MainActivity.ActivitySingleton.getInstance().getActivity()))
|
||||
.getSecureRandom();
|
||||
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.
|
||||
*/
|
||||
protected abstract void generateState();
|
||||
|
||||
/**
|
||||
* Substitute char k by sending the signal through the enigma.
|
||||
* The signal passes the plugboard, the rotors and returns back after going through the
|
||||
* reflector wheel.
|
||||
*
|
||||
* @param k input char
|
||||
* @return substituted output char
|
||||
*/
|
||||
protected abstract char encryptChar(char k);
|
||||
|
||||
/**
|
||||
* Set the state of the enigma
|
||||
* @param state new state
|
||||
*/
|
||||
public abstract void setState(EnigmaStateBundle state);
|
||||
|
||||
/**
|
||||
* Return an object representing the current state of the enigma
|
||||
* @return state
|
||||
*/
|
||||
public abstract EnigmaStateBundle getState();
|
||||
|
||||
/**
|
||||
* Set the rand into a certain state based on seed.
|
||||
* Then set the enigmas state.
|
||||
* @param seed passphrase
|
||||
*/
|
||||
public void setStateFromSeed(String seed)
|
||||
{
|
||||
rand = new Random(seed.hashCode());
|
||||
generateState();
|
||||
}
|
||||
|
||||
public abstract void restoreState(BigInteger mem, int protocol_version);
|
||||
|
||||
public BigInteger getEncodedState()
|
||||
{
|
||||
return getEncodedState(MainActivity.latest_protocol_version);
|
||||
}
|
||||
protected abstract BigInteger getEncodedState(int protocol_version);
|
||||
|
||||
private static String numToMachineType(int n)
|
||||
{
|
||||
int m = 13;
|
||||
n = (m+(n+m)%m)%m; //Problem? Trolololo
|
||||
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";
|
||||
case 11: return "T";
|
||||
case 12: return "KD";
|
||||
default: return "KD";
|
||||
}
|
||||
}
|
||||
|
||||
public static String chooseEnigmaFromSeed(String seed)
|
||||
{
|
||||
return numToMachineType(seed.hashCode() % 13);
|
||||
}
|
||||
|
||||
public static String chooseEnigmaFromSave(BigInteger save)
|
||||
{
|
||||
return numToMachineType(getValue(save, 20));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name indicator of the enigma machine
|
||||
* @return name
|
||||
*/
|
||||
public String getMachineType()
|
||||
{
|
||||
return machineType;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param s source
|
||||
* @param d domain (max value) of the value
|
||||
* @return value
|
||||
*/
|
||||
public static int getValue(BigInteger s, int d)
|
||||
{
|
||||
BigInteger o = s.mod(BigInteger.valueOf(d)).add(BigInteger.valueOf(d)).mod(BigInteger.valueOf(d));
|
||||
return Integer.valueOf(o.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* remove a digit of domain d from source s
|
||||
* @param s source
|
||||
* @param d domain (max value)
|
||||
* @return trimmed source
|
||||
*/
|
||||
public static BigInteger removeDigit(BigInteger s, int d)
|
||||
{
|
||||
s = s.subtract(s.mod(BigInteger.valueOf(d)));
|
||||
s = s.divide(BigInteger.valueOf(d));
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param s source
|
||||
* @param b base (max value)
|
||||
* @param v actual value
|
||||
* @return lengthened source
|
||||
*/
|
||||
public static BigInteger addDigit(BigInteger s, int v, int b)
|
||||
{
|
||||
s = s.multiply(BigInteger.valueOf(b));
|
||||
s = s.add(BigInteger.valueOf(v % b));
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,208 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.enigma;
|
||||
|
||||
/**
|
||||
* Class that contains a possible state of an enigma machine.
|
||||
* Used to store and transport configuration and settings.
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
*/
|
||||
public class EnigmaStateBundle{
|
||||
private String machineType;
|
||||
|
||||
private int typeEntryWheel;
|
||||
|
||||
private int typeRotor1;
|
||||
private int typeRotor2;
|
||||
private int typeRotor3;
|
||||
private int typeRotor4;
|
||||
|
||||
private int rotationRotor1;
|
||||
private int rotationRotor2;
|
||||
private int rotationRotor3;
|
||||
private int rotationRotor4;
|
||||
|
||||
private int ringSettingRotor1;
|
||||
private int ringSettingRotor2;
|
||||
private int ringSettingRotor3;
|
||||
private int ringSettingRotor4;
|
||||
|
||||
private int typeReflector;
|
||||
|
||||
private int rotationReflector;
|
||||
private int ringSettingReflector;
|
||||
|
||||
private int[] configurationPlugboard;
|
||||
|
||||
private int[] configurationReflector;
|
||||
|
||||
// --Commented out by Inspection START (07.11.15 19:46):
|
||||
// public String getMachineType()
|
||||
// {
|
||||
// return this.machineType;
|
||||
// }
|
||||
// --Commented out by Inspection STOP (07.11.15 19:46)
|
||||
|
||||
// --Commented out by Inspection START (07.11.15 19:46):
|
||||
// public void setMachineType(String type)
|
||||
// {
|
||||
// this.machineType = type;
|
||||
// }
|
||||
// --Commented out by Inspection STOP (07.11.15 19:46)
|
||||
|
||||
public int getTypeRotor1() {
|
||||
return typeRotor1;
|
||||
}
|
||||
|
||||
public void setTypeRotor1(int typeRotor1) {
|
||||
this.typeRotor1 = typeRotor1;
|
||||
}
|
||||
|
||||
public int getTypeRotor2() {
|
||||
return typeRotor2;
|
||||
}
|
||||
|
||||
public void setTypeRotor2(int typeRotor2) {
|
||||
this.typeRotor2 = typeRotor2;
|
||||
}
|
||||
|
||||
public int getTypeRotor3() {
|
||||
return typeRotor3;
|
||||
}
|
||||
|
||||
public void setTypeRotor3(int typeRotor3) {
|
||||
this.typeRotor3 = typeRotor3;
|
||||
}
|
||||
|
||||
public int getTypeRotor4() {
|
||||
return typeRotor4;
|
||||
}
|
||||
|
||||
public void setTypeRotor4(int typeRotor4) {
|
||||
this.typeRotor4 = typeRotor4;
|
||||
}
|
||||
|
||||
public int getRotationRotor1() {
|
||||
return rotationRotor1;
|
||||
}
|
||||
|
||||
public void setRotationRotor1(int rotationRotor1) {
|
||||
this.rotationRotor1 = rotationRotor1;
|
||||
}
|
||||
|
||||
public int getRotationRotor2() {
|
||||
return rotationRotor2;
|
||||
}
|
||||
|
||||
public void setRotationRotor2(int rotationRotor2) {
|
||||
this.rotationRotor2 = rotationRotor2;
|
||||
}
|
||||
|
||||
public int getRotationRotor3() {
|
||||
return rotationRotor3;
|
||||
}
|
||||
|
||||
public void setRotationRotor3(int rotationRotor3) {
|
||||
this.rotationRotor3 = rotationRotor3;
|
||||
}
|
||||
|
||||
public int getRotationRotor4() {
|
||||
return rotationRotor4;
|
||||
}
|
||||
|
||||
public void setRotationRotor4(int rotationRotor4) {
|
||||
this.rotationRotor4 = rotationRotor4;
|
||||
}
|
||||
|
||||
public int getRingSettingRotor1() {
|
||||
return ringSettingRotor1;
|
||||
}
|
||||
|
||||
public void setRingSettingRotor1(int ringSettingRotor1) {
|
||||
this.ringSettingRotor1 = ringSettingRotor1;
|
||||
}
|
||||
|
||||
public int getRingSettingRotor2() {
|
||||
return ringSettingRotor2;
|
||||
}
|
||||
|
||||
public void setRingSettingRotor2(int ringSettingRotor2) {
|
||||
this.ringSettingRotor2 = ringSettingRotor2;
|
||||
}
|
||||
|
||||
public int getRingSettingRotor3() {
|
||||
return ringSettingRotor3;
|
||||
}
|
||||
|
||||
public void setRingSettingRotor3(int ringSettingRotor3) {
|
||||
this.ringSettingRotor3 = ringSettingRotor3;
|
||||
}
|
||||
|
||||
public int getRingSettingRotor4() {
|
||||
return ringSettingRotor4;
|
||||
}
|
||||
|
||||
public void setRingSettingRotor4(int ringSettingRotor4) {
|
||||
this.ringSettingRotor4 = ringSettingRotor4;
|
||||
}
|
||||
|
||||
public int getTypeReflector() {
|
||||
return typeReflector;
|
||||
}
|
||||
|
||||
public void setTypeReflector(int typeReflector) {
|
||||
this.typeReflector = typeReflector;
|
||||
}
|
||||
|
||||
public int getTypeEntryWheel() {
|
||||
return typeEntryWheel;
|
||||
}
|
||||
|
||||
public void setTypeEntryWheel(int typeEntryWheel) {
|
||||
this.typeEntryWheel = typeEntryWheel;
|
||||
}
|
||||
|
||||
public int[] getConfigurationPlugboard() {
|
||||
return configurationPlugboard;
|
||||
}
|
||||
|
||||
public void setConfigurationPlugboard(int[] configurationPlugboard) {
|
||||
this.configurationPlugboard = configurationPlugboard;
|
||||
}
|
||||
|
||||
public int[] getConfigurationReflector() {
|
||||
return configurationReflector;
|
||||
}
|
||||
|
||||
public void setConfigurationReflector(int[] configurationReflector) {
|
||||
this.configurationReflector = configurationReflector;
|
||||
}
|
||||
|
||||
public int getRotationReflector() {
|
||||
return rotationReflector;
|
||||
}
|
||||
|
||||
public void setRotationReflector(int rotationReflector) {
|
||||
this.rotationReflector = rotationReflector;
|
||||
}
|
||||
|
||||
public int getRingSettingReflector() {
|
||||
return ringSettingReflector;
|
||||
}
|
||||
|
||||
public void setRingSettingReflector(int ringSettingReflector) {
|
||||
this.ringSettingReflector = ringSettingReflector;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,221 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.enigma;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.EntryWheel;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Plugboard;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Reflector;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Rotor;
|
||||
|
||||
/**
|
||||
* Concrete implementation of an enigma machine of name D
|
||||
* This machine has a rewirable UKW, non changeable rotors.
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
*/
|
||||
public class Enigma_D extends Enigma {
|
||||
|
||||
private EntryWheel entryWheel;
|
||||
private Rotor rotor1;
|
||||
private Rotor rotor2;
|
||||
private Rotor rotor3;
|
||||
private Reflector reflector;
|
||||
|
||||
public Enigma_D()
|
||||
{
|
||||
super();
|
||||
machineType = "D";
|
||||
Log.d(MainActivity.APP_ID, "Created Enigma D");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void establishAvailableParts()
|
||||
{
|
||||
addAvailableEntryWheel(new EntryWheel.EntryWheel_QWERTZ());
|
||||
|
||||
addAvailableRotor(new Rotor.Rotor_K_D_I(0, 0));
|
||||
addAvailableRotor(new Rotor.Rotor_K_D_II(0, 0));
|
||||
addAvailableRotor(new Rotor.Rotor_K_D_III(0, 0));
|
||||
|
||||
addAvailableReflector(new Reflector.ReflectorEnigma_D_G31());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize()
|
||||
{
|
||||
this.entryWheel = availableEntryWheels.get(0);
|
||||
this.rotor1 = availableRotors.get(0);
|
||||
this.rotor2 = availableRotors.get(1);
|
||||
this.rotor3 = availableRotors.get(2);
|
||||
this.reflector = availableReflectors.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextState()
|
||||
{
|
||||
rotor1.rotate();
|
||||
if (rotor1.isAtTurnoverPosition() || this.doAnomaly)
|
||||
{
|
||||
rotor2.rotate();
|
||||
this.doAnomaly = rotor2.doubleTurnAnomaly();
|
||||
if (rotor2.isAtTurnoverPosition())
|
||||
{
|
||||
rotor3.rotate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateState() {
|
||||
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.setRotation(rot1).setRingSetting(ring1);
|
||||
this.rotor2.setRotation(rot2).setRingSetting(ring2);
|
||||
this.rotor3.setRotation(rot3).setRingSetting(ring3);
|
||||
|
||||
this.reflector.setRotation(rotRef).setRingSetting(ringRef)
|
||||
.setConfiguration(Plugboard.seedToReflectorConfiguration(rand));
|
||||
}
|
||||
|
||||
@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 = getEntryWheel(state.getTypeEntryWheel());
|
||||
this.rotor1 = getRotor(state.getTypeRotor1(), state.getRotationRotor1(), state.getRingSettingRotor1());
|
||||
this.rotor2 = getRotor(state.getTypeRotor2(), state.getRotationRotor2(), state.getRingSettingRotor2());
|
||||
this.rotor3 = getRotor(state.getTypeRotor3(), state.getRotationRotor3(), state.getRingSettingRotor3());
|
||||
this.reflector = getReflector(state.getTypeReflector(),
|
||||
state.getRotationReflector(),
|
||||
state.getRingSettingReflector())
|
||||
.setConfiguration(state.getConfigurationReflector());
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnigmaStateBundle getState()
|
||||
{
|
||||
EnigmaStateBundle state = new EnigmaStateBundle();
|
||||
|
||||
state.setTypeEntryWheel(entryWheel.getIndex());
|
||||
|
||||
state.setTypeRotor1(rotor1.getIndex());
|
||||
state.setTypeRotor2(rotor2.getIndex());
|
||||
state.setTypeRotor3(rotor3.getIndex());
|
||||
|
||||
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.getIndex());
|
||||
state.setRotationReflector(reflector.getRotation());
|
||||
state.setRingSettingReflector(reflector.getRingSetting());
|
||||
state.setConfigurationReflector(reflector.getConfiguration());
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreState(BigInteger s, int protocol_version)
|
||||
{
|
||||
switch(protocol_version)
|
||||
{
|
||||
case 1:
|
||||
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);
|
||||
s = removeDigit(s, 26);
|
||||
|
||||
this.rotor1 = getRotor(0, rot1, ring1);
|
||||
this.rotor2 = getRotor(1, rot2, ring2);
|
||||
this.rotor3 = getRotor(2, rot3, ring3);
|
||||
this.reflector = getReflector(0, rotRef, ringRef);
|
||||
this.reflector.setConfiguration(s);
|
||||
break;
|
||||
|
||||
default: Log.e(MainActivity.APP_ID, "Unsupported protocol version "+protocol_version);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getEncodedState(int protocol_version) {
|
||||
BigInteger s = Plugboard.configurationToBigInteger(reflector.getConfiguration());
|
||||
s = addDigit(s, reflector.getRingSetting(), 26);
|
||||
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, 20); //Machine #6
|
||||
s = addDigit(s, protocol_version, MainActivity.max_protocol_version);
|
||||
return s;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.enigma;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.EntryWheel;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Reflector;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Rotor;
|
||||
|
||||
/**
|
||||
* Implementation of the Enigma machine of name G31 (Abwehr)
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
*/
|
||||
public class Enigma_G260 extends Enigma_G31
|
||||
{
|
||||
public Enigma_G260()
|
||||
{
|
||||
super();
|
||||
machineType = "G260";
|
||||
Log.d(MainActivity.APP_ID, "Created Enigma G260");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void establishAvailableParts()
|
||||
{
|
||||
addAvailableEntryWheel(new EntryWheel.EntryWheel_QWERTZ());
|
||||
addAvailableRotor(new Rotor.Rotor_G260_I(0, 0));
|
||||
addAvailableRotor(new Rotor.Rotor_G260_II(0, 0));
|
||||
addAvailableRotor(new Rotor.Rotor_G260_III(0, 0));
|
||||
addAvailableReflector(new Reflector.Reflector_K_G260());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getEncodedState(int protocol_version)
|
||||
{
|
||||
BigInteger s = BigInteger.valueOf(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.getIndex(), availableRotors.size());
|
||||
s = addDigit(s, rotor2.getIndex(), availableRotors.size());
|
||||
s = addDigit(s, rotor1.getIndex(), availableRotors.size());
|
||||
|
||||
s = addDigit(s, 5, 20); //Machine #5
|
||||
s = addDigit(s, protocol_version, MainActivity.max_protocol_version);
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,230 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.enigma;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.EntryWheel;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Reflector;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Rotor;
|
||||
|
||||
/**
|
||||
* Implementation of the Enigma machine of name G31 (Abwehr)
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
*/
|
||||
public class Enigma_G31 extends Enigma
|
||||
{
|
||||
private EntryWheel entryWheel;
|
||||
Rotor rotor1;
|
||||
Rotor rotor2;
|
||||
Rotor rotor3;
|
||||
Reflector reflector;
|
||||
|
||||
public Enigma_G31()
|
||||
{
|
||||
super();
|
||||
machineType = "G31";
|
||||
Log.d(MainActivity.APP_ID, "Created Enigma G31");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void establishAvailableParts()
|
||||
{
|
||||
addAvailableEntryWheel(new EntryWheel.EntryWheel_QWERTZ());
|
||||
addAvailableRotor(new Rotor.Rotor_G31_I(0, 0));
|
||||
addAvailableRotor(new Rotor.Rotor_G31_II(0, 0));
|
||||
addAvailableRotor(new Rotor.Rotor_G31_III(0, 0));
|
||||
addAvailableReflector(new Reflector.ReflectorEnigma_D_G31());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize()
|
||||
{
|
||||
this.entryWheel = getEntryWheel(0);
|
||||
this.rotor1 = getRotor(0);
|
||||
this.rotor2 = getRotor(1);
|
||||
this.rotor3 = getRotor(2);
|
||||
this.reflector = getReflector(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextState()
|
||||
{
|
||||
rotor1.rotate();
|
||||
if (rotor1.isAtTurnoverPosition())
|
||||
{
|
||||
rotor2.rotate();
|
||||
if (rotor2.isAtTurnoverPosition())
|
||||
{
|
||||
rotor3.rotate();
|
||||
if(rotor3.isAtTurnoverPosition())
|
||||
{
|
||||
reflector.setRotation(reflector.getRotation()+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void generateState()
|
||||
{
|
||||
int r1, r2=-1, r3;
|
||||
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);
|
||||
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.entryWheel = getEntryWheel(0);
|
||||
this.rotor1 = getRotor(r1, rot1, ring1);
|
||||
this.rotor2 = getRotor(r2, rot2, ring2);
|
||||
this.rotor3 = getRotor(r3, rot3, ring3);
|
||||
this.reflector = getReflector(0, rotRef, 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 = getEntryWheel(state.getTypeEntryWheel());
|
||||
this.rotor1 = getRotor(state.getTypeRotor1(), state.getRotationRotor1(), state.getRingSettingRotor1());
|
||||
this.rotor2 = getRotor(state.getTypeRotor2(), state.getRotationRotor2(), state.getRingSettingRotor2());
|
||||
this.rotor3 = getRotor(state.getTypeRotor3(), state.getRotationRotor3(), state.getRingSettingRotor3());
|
||||
this.reflector = getReflector(state.getTypeReflector(),
|
||||
state.getRotationReflector(), state.getRingSettingReflector());
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnigmaStateBundle getState() {
|
||||
EnigmaStateBundle state = new EnigmaStateBundle();
|
||||
|
||||
state.setTypeEntryWheel(entryWheel.getIndex());
|
||||
|
||||
state.setTypeRotor1(rotor1.getIndex());
|
||||
state.setTypeRotor2(rotor2.getIndex());
|
||||
state.setTypeRotor3(rotor3.getIndex());
|
||||
|
||||
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.getIndex());
|
||||
state.setRotationReflector(reflector.getRotation());
|
||||
state.setRingSettingReflector(reflector.getRingSetting());
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreState(BigInteger s, int protocol_version)
|
||||
{
|
||||
switch (protocol_version)
|
||||
{
|
||||
case 1:
|
||||
int r1 = getValue(s, availableRotors.size());
|
||||
s = removeDigit(s, availableRotors.size());
|
||||
int r2 = getValue(s, availableRotors.size());
|
||||
s = removeDigit(s, availableRotors.size());
|
||||
int r3 = getValue(s, availableRotors.size());
|
||||
s = removeDigit(s, availableRotors.size());
|
||||
|
||||
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.entryWheel = getEntryWheel(0);
|
||||
this.rotor1 = getRotor(r1, rot1, ring1);
|
||||
this.rotor2 = getRotor(r2, rot2, ring2);
|
||||
this.rotor3 = getRotor(r3, rot3, ring3);
|
||||
this.reflector = getReflector(0, rotRef, ringRef);
|
||||
break;
|
||||
|
||||
default: Log.e(MainActivity.APP_ID, "Unsupported protocol version "+protocol_version);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getEncodedState(int protocol_version)
|
||||
{
|
||||
BigInteger s = BigInteger.valueOf(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.getIndex(), availableRotors.size());
|
||||
s = addDigit(s, rotor2.getIndex(), availableRotors.size());
|
||||
s = addDigit(s, rotor1.getIndex(), availableRotors.size());
|
||||
|
||||
s = addDigit(s, 3, 20); //Machine #3
|
||||
s = addDigit(s, protocol_version, MainActivity.max_protocol_version);
|
||||
return s;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.enigma;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.EntryWheel;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Reflector;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Rotor;
|
||||
|
||||
/**
|
||||
* Implementation of the Enigma machine of name G31 (Abwehr)
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
*/
|
||||
public class Enigma_G312 extends Enigma_G31
|
||||
{
|
||||
public Enigma_G312()
|
||||
{
|
||||
super();
|
||||
machineType = "G312";
|
||||
Log.d(MainActivity.APP_ID, "Created Enigma G312");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void establishAvailableParts()
|
||||
{
|
||||
addAvailableEntryWheel(new EntryWheel.EntryWheel_QWERTZ());
|
||||
addAvailableRotor(new Rotor.Rotor_G312_I(0, 0));
|
||||
addAvailableRotor(new Rotor.Rotor_G312_II(0, 0));
|
||||
addAvailableRotor(new Rotor.Rotor_G312_III(0, 0));
|
||||
addAvailableReflector(new Reflector.Reflector_G312());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getEncodedState(int protocol_version)
|
||||
{
|
||||
BigInteger s = BigInteger.valueOf(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.getIndex(), availableRotors.size());
|
||||
s = addDigit(s, rotor2.getIndex(), availableRotors.size());
|
||||
s = addDigit(s, rotor1.getIndex(), availableRotors.size());
|
||||
|
||||
s = addDigit(s, 4, 20); //Machine #4
|
||||
s = addDigit(s, protocol_version, MainActivity.max_protocol_version);
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
|
@ -1,171 +1,239 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.enigma;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.enigma.rotors.Reflector;
|
||||
import de.vanitasvitae.enigmandroid.enigma.rotors.Rotor;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.EntryWheel;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Plugboard;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Reflector;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Rotor;
|
||||
|
||||
/**
|
||||
* Concrete implementation of an enigma machine of type I
|
||||
* Concrete implementation of an enigma machine of name I
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* @author vanitasvitae
|
||||
*/
|
||||
public class Enigma_I extends Enigma {
|
||||
protected Rotor rotor1;
|
||||
protected Rotor rotor2;
|
||||
protected Rotor rotor3;
|
||||
public class Enigma_I extends Enigma
|
||||
{
|
||||
EntryWheel entryWheel;
|
||||
Rotor rotor1;
|
||||
Rotor rotor2;
|
||||
Rotor rotor3;
|
||||
Reflector reflector;
|
||||
|
||||
protected Reflector reflector;
|
||||
Plugboard plugboard;
|
||||
|
||||
protected Plugboard plugboard;
|
||||
public Enigma_I()
|
||||
{
|
||||
super();
|
||||
machineType = "I";
|
||||
Log.d(MainActivity.APP_ID, "Created Enigma I");
|
||||
}
|
||||
|
||||
public Enigma_I() {
|
||||
machineType = "I";
|
||||
}
|
||||
@Override
|
||||
protected void establishAvailableParts() {
|
||||
addAvailableEntryWheel(new EntryWheel.EntryWheel_ABCDEF());
|
||||
addAvailableRotor(new Rotor.Rotor_I(0, 0));
|
||||
addAvailableRotor(new Rotor.Rotor_II(0,0));
|
||||
addAvailableRotor(new Rotor.Rotor_III(0,0));
|
||||
addAvailableRotor(new Rotor.Rotor_IV(0,0));
|
||||
addAvailableRotor(new Rotor.Rotor_V(0,0));
|
||||
addAvailableReflector(new Reflector.Reflector_A());
|
||||
addAvailableReflector(new Reflector.Reflector_B());
|
||||
addAvailableReflector(new Reflector.Reflector_C());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize()
|
||||
{
|
||||
this.setPlugboard(new Plugboard());
|
||||
//I,II,III, A, 0,0,0, 0,0,0
|
||||
this.setConfiguration(new int[]{1,2,3,1,0,0,0,0,0,0});
|
||||
}
|
||||
@Override
|
||||
public void initialize()
|
||||
{
|
||||
this.plugboard= new Plugboard();
|
||||
this.entryWheel = getEntryWheel(0);
|
||||
this.rotor1 = getRotor(0, 0, 0);
|
||||
this.rotor2 = getRotor(1, 0, 0);
|
||||
this.rotor3 = getRotor(2, 0, 0);
|
||||
this.reflector = getReflector(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextState()
|
||||
{
|
||||
rotor1.rotate();
|
||||
if (rotor1.isAtTurnoverPosition() || (this.doAnomaly && prefAnomaly))
|
||||
{
|
||||
rotor2.rotate();
|
||||
this.doAnomaly = rotor2.doubleTurnAnomaly();
|
||||
if (rotor2.isAtTurnoverPosition())
|
||||
{
|
||||
rotor3.rotate();
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void nextState()
|
||||
{
|
||||
rotor1.rotate();
|
||||
if (rotor1.isAtTurnoverPosition() || this.doAnomaly)
|
||||
{
|
||||
rotor2.rotate();
|
||||
this.doAnomaly = rotor2.doubleTurnAnomaly();
|
||||
if (rotor2.isAtTurnoverPosition())
|
||||
{
|
||||
rotor3.rotate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public char encryptChar(char k)
|
||||
{
|
||||
nextState();
|
||||
int x = ((int) k)-65; //Cast to int and remove Unicode Offset (A=65 in Unicode.)
|
||||
//Encryption
|
||||
//forward direction
|
||||
x = plugboard.encrypt(x);
|
||||
x = normalize(x + rotor1.getRotation() - rotor1.getRingSetting());
|
||||
x = rotor1.encryptForward(x);
|
||||
x = normalize(x - rotor1.getRotation() + rotor1.getRingSetting() + rotor2.getRotation() - rotor2.getRingSetting());
|
||||
x = rotor2.encryptForward(x);
|
||||
x = normalize(x - rotor2.getRotation() + rotor2.getRingSetting() + rotor3.getRotation() - rotor3.getRingSetting());
|
||||
x = rotor3.encryptForward(x);
|
||||
x = normalize(x - rotor3.getRotation() + rotor3.getRingSetting());
|
||||
//TODO: CHECK
|
||||
//backward direction
|
||||
x = reflector.encrypt(x);
|
||||
x = normalize(x + rotor3.getRotation() - rotor3.getRingSetting());
|
||||
x = rotor3.encryptBackward(x);
|
||||
x = normalize(x + rotor2.getRotation() - rotor2.getRingSetting() - rotor3.getRotation() + rotor3.getRingSetting());
|
||||
x = rotor2.encryptBackward(x);
|
||||
x = normalize(x + rotor1.getRotation() - rotor1.getRingSetting() - rotor2.getRotation() + rotor2.getRingSetting());
|
||||
x = rotor1.encryptBackward(x);
|
||||
x = normalize(x - rotor1.getRotation() + rotor1.getRingSetting());
|
||||
x = plugboard.encrypt(x);
|
||||
return (char) (x + 65); //Add Offset again, cast back to char and return
|
||||
}
|
||||
@Override
|
||||
protected void generateState() {
|
||||
int r1, r2=-1, r3=-1;
|
||||
r1 = rand.nextInt(5);
|
||||
while(r2 == -1 || r2 == r1) r2 = rand.nextInt(5);
|
||||
while(r3 == -1 || r3 == r2 || r3 == r1) r3 = rand.nextInt(5);
|
||||
int ref = rand.nextInt(3);
|
||||
|
||||
@Override
|
||||
public int normalize(int input) {
|
||||
return (input+26) % 26;
|
||||
}
|
||||
int rot1 = rand.nextInt(26);
|
||||
int rot2 = rand.nextInt(26);
|
||||
int rot3 = rand.nextInt(26);
|
||||
int ring1 = rand.nextInt(26);
|
||||
int ring2 = rand.nextInt(26);
|
||||
int ring3 = rand.nextInt(26);
|
||||
|
||||
@Override
|
||||
public void setPlugboard(Plugboard p)
|
||||
{
|
||||
this.plugboard = p;
|
||||
}
|
||||
this.rotor1 = getRotor(r1, rot1, ring1);
|
||||
this.rotor2 = getRotor(r2, rot2, ring2);
|
||||
this.rotor3 = getRotor(r3, rot3, ring3);
|
||||
this.reflector = getReflector(ref);
|
||||
|
||||
@Override
|
||||
public int[] getConfiguration()
|
||||
{
|
||||
int[] conf = new int[10];
|
||||
conf[0] = rotor1.getType();
|
||||
conf[1] = rotor2.getType();
|
||||
conf[2] = rotor3.getType();
|
||||
conf[3] = reflector.getType();
|
||||
conf[4] = rotor1.getRotation();
|
||||
conf[5] = rotor2.getRotation();
|
||||
conf[6] = rotor3.getRotation();
|
||||
conf[7] = rotor1.getRingSetting();
|
||||
conf[8] = rotor2.getRingSetting();
|
||||
conf[9] = rotor3.getRingSetting();
|
||||
return conf;
|
||||
}
|
||||
this.plugboard = new Plugboard();
|
||||
plugboard.setConfiguration(Plugboard.seedToPlugboardConfiguration(rand));
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* conf:
|
||||
* 0..2 -> rotor1..rotor3 type
|
||||
* 3 -> reflector type
|
||||
* 4..6 -> rotor1..rotor3 rotation
|
||||
* 7..9 -> rotor1..rotor3 ringSetting
|
||||
*/
|
||||
public void setConfiguration(int[] conf)
|
||||
{
|
||||
this.setRotor(1,conf[0],conf[7],conf[4]);
|
||||
this.setRotor(2,conf[1],conf[8],conf[5]);
|
||||
this.setRotor(3,conf[2],conf[9],conf[6]);
|
||||
this.setReflector(conf[3]);
|
||||
}
|
||||
@Override
|
||||
public char encryptChar(char k)
|
||||
{
|
||||
nextState();
|
||||
int x = ((int) k)-65; //Cast to int and remove Unicode Offset (A=65 in Unicode.)
|
||||
//Encryption
|
||||
//forward direction
|
||||
x = plugboard.encrypt(x);
|
||||
x = 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());
|
||||
//backward direction
|
||||
x = reflector.encrypt(x);
|
||||
x = rotor1.normalize(x + rotor3.getRotation() - rotor3.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);
|
||||
x = plugboard.encrypt(x);
|
||||
return (char) (x + 65); //Add Offset again, cast back to char and return
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setRotor(int pos, int type, int ringSetting, int rotation)
|
||||
{
|
||||
if(pos >= 1 && pos <= 3) {
|
||||
if (type >= 1 && type <= 5) {
|
||||
Rotor rotor = Rotor.createRotor(type, ringSetting, rotation);
|
||||
switch (pos) {
|
||||
case 1:
|
||||
rotor1 = rotor;
|
||||
break;
|
||||
case 2:
|
||||
rotor2 = rotor;
|
||||
break;
|
||||
default:
|
||||
rotor3 = rotor;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Log.d("EnigmAndroid/M3/setRot", "Error: Type " + type + " at position " + pos);
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public void setState(EnigmaStateBundle state)
|
||||
{
|
||||
plugboard.setConfiguration(state.getConfigurationPlugboard());
|
||||
entryWheel = getEntryWheel(state.getTypeEntryWheel());
|
||||
rotor1 = getRotor(state.getTypeRotor1(), state.getRotationRotor1(), state.getRingSettingRotor1());
|
||||
rotor2 = getRotor(state.getTypeRotor2(), state.getRotationRotor2(), state.getRingSettingRotor2());
|
||||
rotor3 = getRotor(state.getTypeRotor3(), state.getRotationRotor3(), state.getRingSettingRotor3());
|
||||
reflector = getReflector(state.getTypeReflector());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setReflector(int type)
|
||||
{
|
||||
if(type >= 1 && type <= 3)
|
||||
{
|
||||
reflector = Reflector.createReflector(type);
|
||||
return true;
|
||||
}
|
||||
Log.d("EnigmAndroid/I/setRef", "Error: Can't set type "+type);
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public EnigmaStateBundle getState()
|
||||
{
|
||||
EnigmaStateBundle state = new EnigmaStateBundle();
|
||||
|
||||
state.setConfigurationPlugboard(plugboard.getConfiguration());
|
||||
|
||||
state.setTypeEntryWheel(entryWheel.getIndex());
|
||||
|
||||
state.setTypeRotor1(rotor1.getIndex());
|
||||
state.setTypeRotor2(rotor2.getIndex());
|
||||
state.setTypeRotor3(rotor3.getIndex());
|
||||
|
||||
state.setTypeReflector(reflector.getIndex());
|
||||
|
||||
state.setRotationRotor1(rotor1.getRotation());
|
||||
state.setRotationRotor2(rotor2.getRotation());
|
||||
state.setRotationRotor3(rotor3.getRotation());
|
||||
|
||||
state.setRingSettingRotor1(rotor1.getRingSetting());
|
||||
state.setRingSettingRotor2(rotor2.getRingSetting());
|
||||
state.setRingSettingRotor3(rotor3.getRingSetting());
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreState(BigInteger s, int protocol_version)
|
||||
{
|
||||
switch (protocol_version)
|
||||
{
|
||||
case 1:
|
||||
int r1 = getValue(s, availableRotors.size());
|
||||
s = removeDigit(s, availableRotors.size());
|
||||
int r2 = getValue(s, availableRotors.size());
|
||||
s = removeDigit(s, availableRotors.size());
|
||||
int r3 = getValue(s, availableRotors.size());
|
||||
s = removeDigit(s, availableRotors.size());
|
||||
int ref = getValue(s, availableReflectors.size());
|
||||
s = removeDigit(s, availableReflectors.size());
|
||||
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);
|
||||
|
||||
this.entryWheel = getEntryWheel(0);
|
||||
this.rotor1 = getRotor(r1, rot1, ring1);
|
||||
this.rotor2 = getRotor(r2, rot2, ring2);
|
||||
this.rotor3 = getRotor(r3, rot3, ring3);
|
||||
this.reflector = getReflector(ref);
|
||||
|
||||
this.plugboard = new Plugboard();
|
||||
plugboard.setConfiguration(s);
|
||||
break;
|
||||
|
||||
default: Log.e(MainActivity.APP_ID, "Unsupported protocol version "+protocol_version);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getEncodedState(int protocol_version) {
|
||||
BigInteger s = Plugboard.configurationToBigInteger(plugboard.getConfiguration());
|
||||
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.getIndex(), availableReflectors.size());
|
||||
s = addDigit(s, rotor3.getIndex(), availableRotors.size());
|
||||
s = addDigit(s, rotor2.getIndex(), availableRotors.size());
|
||||
s = addDigit(s, rotor1.getIndex(), availableRotors.size());
|
||||
|
||||
s = addDigit(s, 0, 20); //Machine #0
|
||||
s = addDigit(s, protocol_version, MainActivity.max_protocol_version);
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,227 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.enigma;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.EntryWheel;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Reflector;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Rotor;
|
||||
|
||||
/**
|
||||
* Implementation of the Enigma machine of name K
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
*/
|
||||
public class Enigma_K extends Enigma
|
||||
{
|
||||
private EntryWheel entryWheel;
|
||||
Rotor rotor1;
|
||||
Rotor rotor2;
|
||||
Rotor rotor3;
|
||||
Reflector reflector;
|
||||
|
||||
public Enigma_K()
|
||||
{
|
||||
super();
|
||||
machineType = "K";
|
||||
Log.d(MainActivity.APP_ID, "Created Enigma K");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void establishAvailableParts()
|
||||
{
|
||||
addAvailableEntryWheel(new EntryWheel.EntryWheel_QWERTZ());
|
||||
addAvailableRotor(new Rotor.Rotor_K_D_I(0, 0));
|
||||
addAvailableRotor(new Rotor.Rotor_K_D_II(0,0));
|
||||
addAvailableRotor(new Rotor.Rotor_K_D_III(0,0));
|
||||
addAvailableReflector(new Reflector.Reflector_K_G260());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize()
|
||||
{
|
||||
this.entryWheel = getEntryWheel(0);
|
||||
this.rotor1 = getRotor(0, 0, 0);
|
||||
this.rotor2 = getRotor(1, 0, 0);
|
||||
this.rotor3 = getRotor(2, 0, 0);
|
||||
this.reflector = getReflector(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextState()
|
||||
{
|
||||
rotor1.rotate();
|
||||
if (rotor1.isAtTurnoverPosition() || this.doAnomaly)
|
||||
{
|
||||
rotor2.rotate();
|
||||
this.doAnomaly = rotor2.doubleTurnAnomaly();
|
||||
if (rotor2.isAtTurnoverPosition())
|
||||
{
|
||||
rotor3.rotate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateState() {
|
||||
int r1, r2=-1, r3;
|
||||
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);
|
||||
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.entryWheel = getEntryWheel(0);
|
||||
this.rotor1 = getRotor(r1, rot1, ring1);
|
||||
this.rotor2 = getRotor(r2, rot2, ring2);
|
||||
this.rotor3 = getRotor(r3, rot3, ring3);
|
||||
this.reflector = getReflector(0, rotRef, 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 = getEntryWheel(state.getTypeEntryWheel());
|
||||
this.rotor1 = getRotor(state.getTypeRotor1(), state.getRotationRotor1(), state.getRingSettingRotor1());
|
||||
this.rotor2 = getRotor(state.getTypeRotor2(), state.getRotationRotor2(), state.getRingSettingRotor2());
|
||||
this.rotor3 = getRotor(state.getTypeRotor3(), state.getRotationRotor3(), state.getRingSettingRotor3());
|
||||
this.reflector = getReflector(state.getTypeReflector(), state.getRotationReflector(), state.getRingSettingReflector());
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnigmaStateBundle getState()
|
||||
{
|
||||
EnigmaStateBundle state = new EnigmaStateBundle();
|
||||
|
||||
state.setTypeEntryWheel(entryWheel.getIndex());
|
||||
|
||||
state.setTypeRotor1(rotor1.getIndex());
|
||||
state.setTypeRotor2(rotor2.getIndex());
|
||||
state.setTypeRotor3(rotor3.getIndex());
|
||||
|
||||
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.getIndex());
|
||||
state.setRotationReflector(reflector.getRotation());
|
||||
state.setRingSettingReflector(reflector.getRingSetting());
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreState(BigInteger s, int protocol_version)
|
||||
{
|
||||
switch (protocol_version)
|
||||
{
|
||||
case 1:
|
||||
int r1 = getValue(s,availableRotors.size());
|
||||
s = removeDigit(s,availableRotors.size());
|
||||
int r2 = getValue(s,availableRotors.size());
|
||||
s = removeDigit(s,availableRotors.size());
|
||||
int r3 = getValue(s,availableRotors.size());
|
||||
s = removeDigit(s,availableRotors.size());
|
||||
|
||||
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.entryWheel = getEntryWheel(0);
|
||||
this.rotor1 = getRotor(r1, rot1, ring1);
|
||||
this.rotor2 = getRotor(r2, rot2, ring2);
|
||||
this.rotor3 = getRotor(r3, rot3, ring3);
|
||||
this.reflector = getReflector(0, rotRef, ringRef);
|
||||
break;
|
||||
|
||||
default: Log.e(MainActivity.APP_ID, "Unsupported protocol version "+protocol_version);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getEncodedState(int protocol_version)
|
||||
{
|
||||
BigInteger s = BigInteger.valueOf(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.getIndex(), availableRotors.size());
|
||||
s = addDigit(s, rotor2.getIndex(), availableRotors.size());
|
||||
s = addDigit(s, rotor1.getIndex(), availableRotors.size());
|
||||
|
||||
s = addDigit(s, 7, 20); //Machine #7
|
||||
s = addDigit(s, protocol_version, MainActivity.max_protocol_version);
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,240 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.enigma;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.EntryWheel;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Plugboard;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Reflector;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Rotor;
|
||||
|
||||
/**
|
||||
* Concrete implementation of an enigma machine of name D
|
||||
* This machine has a rewirable UKW, non changeable rotors.
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
*/
|
||||
public class Enigma_KD extends Enigma {
|
||||
|
||||
private EntryWheel entryWheel;
|
||||
private Rotor rotor1;
|
||||
private Rotor rotor2;
|
||||
private Rotor rotor3;
|
||||
private Reflector reflector;
|
||||
|
||||
public Enigma_KD()
|
||||
{
|
||||
super();
|
||||
machineType = "KD";
|
||||
Log.d(MainActivity.APP_ID, "Created Enigma KD");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void establishAvailableParts()
|
||||
{
|
||||
addAvailableEntryWheel(new EntryWheel.EntryWheel_QWERTZ());
|
||||
|
||||
addAvailableRotor(new Rotor.Rotor_KD_I(0, 0));
|
||||
addAvailableRotor(new Rotor.Rotor_KD_II(0, 0));
|
||||
addAvailableRotor(new Rotor.Rotor_KD_III(0, 0));
|
||||
|
||||
addAvailableReflector(new Reflector.ReflectorEnigma_KD());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize()
|
||||
{
|
||||
this.entryWheel = availableEntryWheels.get(0);
|
||||
this.rotor1 = availableRotors.get(0);
|
||||
this.rotor2 = availableRotors.get(1);
|
||||
this.rotor3 = availableRotors.get(2);
|
||||
this.reflector = availableReflectors.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextState()
|
||||
{
|
||||
rotor1.rotate();
|
||||
if (rotor1.isAtTurnoverPosition() || this.doAnomaly)
|
||||
{
|
||||
rotor2.rotate();
|
||||
this.doAnomaly = rotor2.doubleTurnAnomaly();
|
||||
if (rotor2.isAtTurnoverPosition())
|
||||
{
|
||||
rotor3.rotate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateState() {
|
||||
int r1, r2=-1, r3;
|
||||
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);
|
||||
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.entryWheel = getEntryWheel(0);
|
||||
this.rotor1 = getRotor(r1, rot1, ring1);
|
||||
this.rotor2 = getRotor(r2, rot2, ring2);
|
||||
this.rotor3 = getRotor(r3, rot3, ring3);
|
||||
this.reflector = getReflector(0, rotRef, ringRef);
|
||||
this.reflector.setRotation(rotRef).setRingSetting(ringRef)
|
||||
.setConfiguration(Plugboard.seedToReflectorConfiguration(rand));
|
||||
}
|
||||
|
||||
@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 = getEntryWheel(state.getTypeEntryWheel());
|
||||
this.rotor1 = getRotor(state.getTypeRotor1(), state.getRotationRotor1(), state.getRingSettingRotor1());
|
||||
this.rotor2 = getRotor(state.getTypeRotor2(), state.getRotationRotor2(), state.getRingSettingRotor2());
|
||||
this.rotor3 = getRotor(state.getTypeRotor3(), state.getRotationRotor3(), state.getRingSettingRotor3());
|
||||
this.reflector = getReflector(state.getTypeReflector(),
|
||||
state.getRotationReflector(),
|
||||
state.getRingSettingReflector())
|
||||
.setConfiguration(state.getConfigurationReflector());
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnigmaStateBundle getState()
|
||||
{
|
||||
EnigmaStateBundle state = new EnigmaStateBundle();
|
||||
|
||||
state.setTypeEntryWheel(entryWheel.getIndex());
|
||||
|
||||
state.setTypeRotor1(rotor1.getIndex());
|
||||
state.setTypeRotor2(rotor2.getIndex());
|
||||
state.setTypeRotor3(rotor3.getIndex());
|
||||
|
||||
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.getIndex());
|
||||
state.setRotationReflector(reflector.getRotation());
|
||||
state.setRingSettingReflector(reflector.getRingSetting());
|
||||
state.setConfigurationReflector(reflector.getConfiguration());
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreState(BigInteger s, int protocol_version)
|
||||
{
|
||||
switch (protocol_version)
|
||||
{
|
||||
case 1:
|
||||
int r1 = getValue(s, availableRotors.size());
|
||||
s = removeDigit(s, availableRotors.size());
|
||||
int r2 = getValue(s, availableRotors.size());
|
||||
s = removeDigit(s, availableRotors.size());
|
||||
int r3 = getValue(s, availableRotors.size());
|
||||
s = removeDigit(s, availableRotors.size());
|
||||
|
||||
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);
|
||||
s = removeDigit(s, 26);
|
||||
|
||||
this.rotor1 = getRotor(r1, rot1, ring1);
|
||||
this.rotor2 = getRotor(r2, rot2, ring2);
|
||||
this.rotor3 = getRotor(r3, rot3, ring3);
|
||||
this.reflector = getReflector(0, rotRef, ringRef);
|
||||
this.reflector.setConfiguration(s);
|
||||
break;
|
||||
|
||||
default: Log.e(MainActivity.APP_ID, "Unsupported protocol version "+protocol_version);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getEncodedState(int protocol_version) {
|
||||
BigInteger s = Plugboard.configurationToBigInteger(reflector.getConfiguration());
|
||||
s = addDigit(s, reflector.getRingSetting(), 26);
|
||||
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.getIndex(), availableRotors.size());
|
||||
s = addDigit(s, rotor2.getIndex(), availableRotors.size());
|
||||
s = addDigit(s, rotor1.getIndex(), availableRotors.size());
|
||||
|
||||
s = addDigit(s, 12, 20); //Machine #12
|
||||
s = addDigit(s, protocol_version, MainActivity.max_protocol_version);
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.enigma;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.EntryWheel;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Reflector;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Rotor;
|
||||
|
||||
/**
|
||||
* Implementation of the Enigma machine of name K (Switzerland, Airforce)
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
*/
|
||||
public class Enigma_K_Swiss_Airforce extends Enigma_K
|
||||
{
|
||||
public Enigma_K_Swiss_Airforce()
|
||||
{
|
||||
super();
|
||||
machineType = "KSA";
|
||||
Log.d(MainActivity.APP_ID, "Created Enigma KSA");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void establishAvailableParts()
|
||||
{
|
||||
addAvailableEntryWheel(new EntryWheel.EntryWheel_QWERTZ());
|
||||
addAvailableRotor(new Rotor.Rotor_K_Swiss_Airforce_I(0,0));
|
||||
addAvailableRotor(new Rotor.Rotor_K_Swiss_Airforce_II(0,0));
|
||||
addAvailableRotor(new Rotor.Rotor_K_Swiss_Airforce_III(0,0));
|
||||
addAvailableReflector(new Reflector.Reflector_K_G260());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getEncodedState(int protocol_version)
|
||||
{
|
||||
BigInteger s = BigInteger.valueOf(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.getIndex(), availableRotors.size());
|
||||
s = addDigit(s, rotor2.getIndex(), availableRotors.size());
|
||||
s = addDigit(s, rotor1.getIndex(), availableRotors.size());
|
||||
|
||||
s = addDigit(s, 9, 20); //Machine #9
|
||||
s = addDigit(s, protocol_version, MainActivity.max_protocol_version);
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.enigma;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.EntryWheel;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Reflector;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Rotor;
|
||||
|
||||
/**
|
||||
* Implementation of the Enigma machine of name K (Switzerland)
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
*/
|
||||
public class Enigma_K_Swiss_Standard extends Enigma_K
|
||||
{
|
||||
public Enigma_K_Swiss_Standard()
|
||||
{
|
||||
super();
|
||||
machineType = "KS";
|
||||
Log.d(MainActivity.APP_ID, "Created Enigma KS");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void establishAvailableParts()
|
||||
{
|
||||
addAvailableEntryWheel(new EntryWheel.EntryWheel_QWERTZ());
|
||||
addAvailableRotor(new Rotor.Rotor_KSwiss_Standard_I(0,0));
|
||||
addAvailableRotor(new Rotor.Rotor_KSwiss_Standard_II(0,0));
|
||||
addAvailableRotor(new Rotor.Rotor_KSwiss_Standard_III(0,0));
|
||||
addAvailableReflector(new Reflector.Reflector_K_G260());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getEncodedState(int protocol_version)
|
||||
{
|
||||
BigInteger s = BigInteger.valueOf(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.getIndex(), availableRotors.size());
|
||||
s = addDigit(s, rotor2.getIndex(), availableRotors.size());
|
||||
s = addDigit(s, rotor1.getIndex(), availableRotors.size());
|
||||
|
||||
s = addDigit(s, 8, 20); //Machine #8
|
||||
s = addDigit(s, protocol_version, MainActivity.max_protocol_version);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,75 +1,99 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.enigma;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.enigma.rotors.Reflector;
|
||||
import de.vanitasvitae.enigmandroid.enigma.rotors.Rotor;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.EntryWheel;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Plugboard;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Reflector;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Rotor;
|
||||
|
||||
/**
|
||||
* Concrete implementation of an enigma machine model M3
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* @author vanitasvitae
|
||||
*/
|
||||
public class Enigma_M3 extends Enigma_I
|
||||
{
|
||||
public Enigma_M3()
|
||||
{
|
||||
machineType = "M3";
|
||||
}
|
||||
@Override
|
||||
public void initialize()
|
||||
{
|
||||
this.setPlugboard(new Plugboard());
|
||||
//I,II,III, B, 0,0,0, 0,0,0
|
||||
this.setConfiguration(new int[]{1,2,3,2,0,0,0,0,0,0});
|
||||
}
|
||||
@Override
|
||||
public boolean setRotor(int pos, int type, int ringSetting, int rotation)
|
||||
{
|
||||
if(pos >= 1 && pos <= 3) {
|
||||
if (type >= 1 && type <= 8) {
|
||||
Rotor rotor = Rotor.createRotor(type, ringSetting, rotation);
|
||||
switch (pos) {
|
||||
case 1:
|
||||
rotor1 = rotor;
|
||||
break;
|
||||
case 2:
|
||||
rotor2 = rotor;
|
||||
break;
|
||||
default:
|
||||
rotor3 = rotor;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Log.d("EnigmAndroid/M3/setRot", "Error: Type " + type + " at position " + pos);
|
||||
return false;
|
||||
}
|
||||
public Enigma_M3()
|
||||
{
|
||||
super();
|
||||
machineType = "M3";
|
||||
Log.d(MainActivity.APP_ID, "Created Enigma M3");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setReflector(int type)
|
||||
{
|
||||
if(type >= 2 && type <= 3)
|
||||
{
|
||||
reflector = Reflector.createReflector(type);
|
||||
return true;
|
||||
}
|
||||
Log.d("EnigmAndroid/M3/setRef", "Error: Can't set type "+type);
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
protected void establishAvailableParts()
|
||||
{
|
||||
addAvailableEntryWheel(new EntryWheel.EntryWheel_ABCDEF());
|
||||
addAvailableRotor(new Rotor.Rotor_I(0, 0));
|
||||
addAvailableRotor(new Rotor.Rotor_II(0,0));
|
||||
addAvailableRotor(new Rotor.Rotor_III(0,0));
|
||||
addAvailableRotor(new Rotor.Rotor_IV(0,0));
|
||||
addAvailableRotor(new Rotor.Rotor_V(0,0));
|
||||
addAvailableRotor(new Rotor.Rotor_VI(0,0));
|
||||
addAvailableRotor(new Rotor.Rotor_VII(0,0));
|
||||
addAvailableRotor(new Rotor.Rotor_VIII(0,0));
|
||||
addAvailableReflector(new Reflector.Reflector_B());
|
||||
addAvailableReflector(new Reflector.Reflector_C());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateState() {
|
||||
int r1, r2=-1, r3=-1;
|
||||
r1 = rand.nextInt(8);
|
||||
while(r2 == -1 || r2 == r1) r2 = rand.nextInt(8);
|
||||
while(r3 == -1 || r3 == r2 || r3 == r1) r3 = rand.nextInt(8);
|
||||
int ref = rand.nextInt(2);
|
||||
|
||||
int rot1 = rand.nextInt(26);
|
||||
int rot2 = rand.nextInt(26);
|
||||
int rot3 = rand.nextInt(26);
|
||||
int ring1 = rand.nextInt(26);
|
||||
int ring2 = rand.nextInt(26);
|
||||
int ring3 = rand.nextInt(26);
|
||||
|
||||
this.entryWheel = getEntryWheel(0);
|
||||
this.rotor1 = getRotor(r1, rot1, ring1);
|
||||
this.rotor2 = getRotor(r2, rot2, ring2);
|
||||
this.rotor3 = getRotor(r3, rot3, ring3);
|
||||
this.reflector = getReflector(ref);
|
||||
|
||||
this.plugboard = new Plugboard();
|
||||
plugboard.setConfiguration(Plugboard.seedToPlugboardConfiguration(rand));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getEncodedState(int protocol_version) {
|
||||
BigInteger s = Plugboard.configurationToBigInteger(plugboard.getConfiguration());
|
||||
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.getIndex(), availableReflectors.size());
|
||||
s = addDigit(s, rotor3.getIndex(), availableRotors.size());
|
||||
s = addDigit(s, rotor2.getIndex(), availableRotors.size());
|
||||
s = addDigit(s, rotor1.getIndex(), availableRotors.size());
|
||||
s = addDigit(s, 1, 20); //Machine #1
|
||||
s = addDigit(s, protocol_version, MainActivity.max_protocol_version);
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,214 +1,320 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.enigma;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.enigma.rotors.Reflector;
|
||||
import de.vanitasvitae.enigmandroid.enigma.rotors.Rotor;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.EntryWheel;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Plugboard;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Reflector;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Rotor;
|
||||
|
||||
/**
|
||||
* Concrete Implementation of the Enigma Machine type M4 of the german Kriegsmarine
|
||||
* Concrete Implementation of the Enigma Machine name M4 of the german Kriegsmarine
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* @author vanitasvitae
|
||||
*/
|
||||
public class Enigma_M4 extends Enigma
|
||||
{
|
||||
private Rotor rotor1;
|
||||
private Rotor rotor2;
|
||||
private Rotor rotor3;
|
||||
private ArrayList<Rotor> availableThinRotors;
|
||||
private EntryWheel entryWheel;
|
||||
private Rotor rotor1;
|
||||
private Rotor rotor2;
|
||||
private Rotor rotor3;
|
||||
|
||||
private Rotor rotor4;
|
||||
private Reflector thinReflector;
|
||||
private Rotor rotor4;
|
||||
|
||||
private Plugboard plugboard;
|
||||
private Reflector reflector;
|
||||
|
||||
public Enigma_M4()
|
||||
{
|
||||
machineType = "M4";
|
||||
}
|
||||
private Plugboard plugboard;
|
||||
|
||||
@Override
|
||||
public boolean setRotor(int pos, int type, int ringSetting, int rotation)
|
||||
{
|
||||
if(pos >= 1 && pos <= 3)
|
||||
{
|
||||
if(type >= 1 && type <= 8)
|
||||
{
|
||||
Rotor rotor = Rotor.createRotor(type, ringSetting, rotation);
|
||||
switch (pos)
|
||||
{
|
||||
case 1: rotor1 = rotor;
|
||||
break;
|
||||
case 2: rotor2 = rotor;
|
||||
break;
|
||||
default: rotor3 = rotor;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.d("EnigmAndroid/M4/setRot", "Error: Type " + type + " at position " + pos);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//Thin rotor
|
||||
else if(pos == 4)
|
||||
{
|
||||
if(type >=9 && type <=10) {
|
||||
rotor4 = Rotor.createRotor(type, ringSetting, rotation);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Log.d("EnigmAndroid/M3/setRot", "Error: Type " + type + " at position " + pos);
|
||||
return false;
|
||||
}
|
||||
public Enigma_M4()
|
||||
{
|
||||
super();
|
||||
machineType = "M4";
|
||||
Log.d(MainActivity.APP_ID, "Created Enigma M4");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setReflector(int type)
|
||||
{
|
||||
if(type >= 4 && type <=5)
|
||||
{
|
||||
this.thinReflector = Reflector.createReflector(type);
|
||||
return true;
|
||||
}
|
||||
Log.d("EnigmAndroid/M4/setRef","Error: Can't set type "+type);
|
||||
return false;
|
||||
}
|
||||
private void addAvailableThinRotor(Rotor r)
|
||||
{
|
||||
if(availableThinRotors == null) availableThinRotors = new ArrayList<>();
|
||||
availableThinRotors.add(availableThinRotors.size(), r.setIndex(availableThinRotors.size()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize()
|
||||
{
|
||||
this.setPlugboard(new Plugboard());
|
||||
this.setConfiguration(new int[]{1,2,3,9,4,0,0,0,0,0,0,0,0});
|
||||
this.prefAnomaly = true;
|
||||
}
|
||||
private Rotor getThinRotor(int index)
|
||||
{
|
||||
if(availableThinRotors == null || availableThinRotors.size() == 0) return null;
|
||||
return availableThinRotors.get(index % availableThinRotors.size()).getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Set the enigma into the next mechanical state.
|
||||
* This rotates the first rotor and eventually also the second/third.
|
||||
* Also this method handles the anomaly in case it should happen.
|
||||
*/
|
||||
public void nextState()
|
||||
{
|
||||
//Rotate rotors
|
||||
rotor1.rotate();
|
||||
//Eventually turn next rotor (usual turnOver or anomaly)
|
||||
if (rotor1.isAtTurnoverPosition() || (this.doAnomaly && prefAnomaly))
|
||||
{
|
||||
rotor2.rotate();
|
||||
//Set doAnomaly for next call of encryptChar
|
||||
this.doAnomaly = rotor2.doubleTurnAnomaly();
|
||||
//Eventually rotate next rotor
|
||||
if (rotor2.isAtTurnoverPosition())
|
||||
{
|
||||
rotor3.rotate();
|
||||
}
|
||||
}
|
||||
}
|
||||
private Rotor getThinRotor(int index, int rotation, int ringSettings)
|
||||
{
|
||||
Rotor r = getThinRotor(index);
|
||||
if(r == null) return null;
|
||||
return r.setRotation(rotation).setRingSetting(ringSettings);
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Substitute char k by sending the signal through the enigma.
|
||||
* The signal passes the plugboard, the rotors and returns back after going through the
|
||||
* reflector wheel.
|
||||
*
|
||||
* @param k input char
|
||||
* @return substituted output char
|
||||
*/
|
||||
public char encryptChar(char k)
|
||||
{
|
||||
nextState(); //Rotate rotors
|
||||
int x = ((int) k)-65; //Cast to int and remove Unicode Offset (A=65 in Unicode.)
|
||||
//Encryption
|
||||
//forward direction
|
||||
x = plugboard.encrypt(x);
|
||||
x = normalize(x + rotor1.getRotation() - rotor1.getRingSetting());
|
||||
x = rotor1.encryptForward(x);
|
||||
x = normalize(x - rotor1.getRotation() + rotor1.getRingSetting() + rotor2.getRotation() - rotor2.getRingSetting());
|
||||
x = rotor2.encryptForward(x);
|
||||
x = normalize(x - rotor2.getRotation() + rotor2.getRingSetting() + rotor3.getRotation() - rotor3.getRingSetting());
|
||||
x = rotor3.encryptForward(x);
|
||||
x = normalize(x - rotor3.getRotation() + rotor3.getRingSetting() + rotor4.getRotation() - rotor4.getRingSetting());
|
||||
x = rotor4.encryptForward(x);
|
||||
x = normalize(x - rotor4.getRotation() + rotor4.getRingSetting());
|
||||
//backward direction
|
||||
x = thinReflector.encrypt(x);
|
||||
x = normalize(x + rotor4.getRotation() - rotor4.getRingSetting());
|
||||
x = rotor4.encryptBackward(x);
|
||||
x = normalize(x + rotor3.getRotation() - rotor3.getRingSetting() - rotor4.getRotation() + rotor4.getRingSetting());
|
||||
x = rotor3.encryptBackward(x);
|
||||
x = normalize(x + rotor2.getRotation() - rotor2.getRingSetting() - rotor3.getRotation() + rotor3.getRingSetting());
|
||||
x = rotor2.encryptBackward(x);
|
||||
x = normalize(x + rotor1.getRotation() - rotor1.getRingSetting() - rotor2.getRotation() + rotor2.getRingSetting());
|
||||
x = rotor1.encryptBackward(x);
|
||||
x = normalize(x - rotor1.getRotation() + rotor1.getRingSetting());
|
||||
x = plugboard.encrypt(x);
|
||||
return (char) (x + 65); //Add Offset again and cast back to char
|
||||
}
|
||||
@Override
|
||||
protected void establishAvailableParts()
|
||||
{
|
||||
Log.d(MainActivity.APP_ID, "Established");
|
||||
addAvailableEntryWheel(new EntryWheel.EntryWheel_ABCDEF());
|
||||
addAvailableRotor(new Rotor.Rotor_I(0, 0));
|
||||
addAvailableRotor(new Rotor.Rotor_II(0,0));
|
||||
addAvailableRotor(new Rotor.Rotor_III(0,0));
|
||||
addAvailableRotor(new Rotor.Rotor_IV(0,0));
|
||||
addAvailableRotor(new Rotor.Rotor_V(0,0));
|
||||
addAvailableRotor(new Rotor.Rotor_VI(0,0));
|
||||
addAvailableRotor(new Rotor.Rotor_VII(0, 0));
|
||||
addAvailableRotor(new Rotor.Rotor_VIII(0,0));
|
||||
addAvailableThinRotor(new Rotor.Rotor_M4_Beta(0, 0));
|
||||
addAvailableThinRotor(new Rotor.Rotor_M4_Gamma(0, 0));
|
||||
addAvailableReflector(new Reflector.Reflector_Thin_B());
|
||||
addAvailableReflector(new Reflector.ReflectorThinC());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int normalize(int input) {
|
||||
return (input + 26) % 26;
|
||||
}
|
||||
@Override
|
||||
public void initialize()
|
||||
{
|
||||
Log.d(MainActivity.APP_ID, "Initialized");
|
||||
this.plugboard = new Plugboard();
|
||||
this.entryWheel = getEntryWheel(0);
|
||||
this.rotor1 = getRotor(0, 0, 0);
|
||||
this.rotor2 = getRotor(1, 0, 0);
|
||||
this.rotor3 = getRotor(2, 0, 0);
|
||||
this.rotor4 = getThinRotor(0, 0, 0);
|
||||
this.reflector = getReflector(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlugboard(Plugboard p)
|
||||
{
|
||||
this.plugboard = p;
|
||||
}
|
||||
@Override
|
||||
/**
|
||||
* Set the enigma into the next mechanical state.
|
||||
* This rotates the first rotor and eventually also the second/third.
|
||||
* Also this method handles the anomaly in case it should happen.
|
||||
*/
|
||||
public void nextState()
|
||||
{
|
||||
//Rotate rotors
|
||||
rotor1.rotate();
|
||||
//Eventually turn next rotor (usual turnOver or anomaly)
|
||||
if (rotor1.isAtTurnoverPosition() || this.doAnomaly)
|
||||
{
|
||||
rotor2.rotate();
|
||||
//Set doAnomaly for next call of encryptChar
|
||||
this.doAnomaly = rotor2.doubleTurnAnomaly();
|
||||
//Eventually rotate next rotor
|
||||
if (rotor2.isAtTurnoverPosition())
|
||||
{
|
||||
rotor3.rotate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getConfiguration() {
|
||||
int[] configuration = new int[13];
|
||||
configuration[0] = rotor1.getType();
|
||||
configuration[1] = rotor2.getType();
|
||||
configuration[2] = rotor3.getType();
|
||||
configuration[3] = rotor4.getType();
|
||||
@Override
|
||||
protected void generateState() {
|
||||
int r1, r2=-1, r3=-1;
|
||||
int r4;
|
||||
int ref;
|
||||
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);
|
||||
|
||||
configuration[4] = thinReflector.getType();
|
||||
int rot1 = rand.nextInt(26);
|
||||
int rot2 = rand.nextInt(26);
|
||||
int rot3 = rand.nextInt(26);
|
||||
int rot4 = rand.nextInt(26);
|
||||
int rotRef = rand.nextInt(26);
|
||||
int ring1 = rand.nextInt(26);
|
||||
int ring2 = rand.nextInt(26);
|
||||
int ring3 = rand.nextInt(26);
|
||||
int ring4 = rand.nextInt(26);
|
||||
int ringRef = rand.nextInt(26);
|
||||
|
||||
configuration[5] = rotor1.getRotation();
|
||||
configuration[6] = rotor2.getRotation();
|
||||
configuration[7] = rotor3.getRotation();
|
||||
configuration[8] = rotor4.getRotation();
|
||||
this.entryWheel = getEntryWheel(0);
|
||||
this.rotor1 = getRotor(r1, rot1, ring1);
|
||||
this.rotor2 = getRotor(r2, rot2, ring2);
|
||||
this.rotor3 = getRotor(r3, rot3, ring3);
|
||||
this.rotor4 = getThinRotor(r4, rot4, ring4);
|
||||
|
||||
configuration[9] = rotor1.getRingSetting();
|
||||
configuration[10] = rotor2.getRingSetting();
|
||||
configuration[11] = rotor3.getRingSetting();
|
||||
this.reflector = getReflector(ref, rotRef, ringRef);
|
||||
|
||||
configuration[12] = rotor4.getRingSetting();
|
||||
return configuration;
|
||||
}
|
||||
this.plugboard = new Plugboard();
|
||||
this.plugboard.setConfiguration(Plugboard.seedToPlugboardConfiguration(rand));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConfiguration(int[] conf)
|
||||
{
|
||||
if(conf.length != 13)
|
||||
{
|
||||
Log.d("EnigmAndroid/M4/setCon", "Invalid conf array length. conf array length " +
|
||||
"should be 13 (is "+conf.length+")");
|
||||
}
|
||||
else
|
||||
{
|
||||
setRotor(1, conf[0], conf[9], conf[5]);
|
||||
setRotor(2, conf[1], conf[10], conf[6]);
|
||||
setRotor(3, conf[2], conf[11], conf[7]);
|
||||
setRotor(4, conf[3], conf[12], conf[8]);
|
||||
setReflector(conf[4]);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
/**
|
||||
* Substitute char k by sending the signal through the enigma.
|
||||
* The signal passes the plugboard, the rotors and returns back after going through the
|
||||
* reflector wheel.
|
||||
*
|
||||
* @param k input char
|
||||
* @return substituted output char
|
||||
*/
|
||||
public char encryptChar(char k)
|
||||
{
|
||||
nextState(); //Rotate rotors
|
||||
int x = ((int) k)-65; //Cast to int and remove Unicode Offset (A=65 in Unicode.)
|
||||
//Encryption
|
||||
//forward direction
|
||||
x = plugboard.encrypt(x);
|
||||
x = 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() + rotor4.getRotation() - rotor4.getRingSetting());
|
||||
x = rotor4.encryptForward(x);
|
||||
x = rotor1.normalize(x - rotor4.getRotation() + rotor4.getRingSetting());
|
||||
//backward direction
|
||||
x = reflector.encrypt(x);
|
||||
x = rotor1.normalize(x + rotor4.getRotation() - rotor4.getRingSetting());
|
||||
x = rotor4.encryptBackward(x);
|
||||
x = rotor1.normalize(x + rotor3.getRotation() - rotor3.getRingSetting() - rotor4.getRotation() + rotor4.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);
|
||||
x = plugboard.encrypt(x);
|
||||
return (char) (x + 65); //Add Offset again and cast back to char
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setState(EnigmaStateBundle state)
|
||||
{
|
||||
rotor1 = getRotor(state.getTypeRotor1(), state.getRotationRotor1(), state.getRingSettingRotor1());
|
||||
rotor2 = getRotor(state.getTypeRotor2(), state.getRotationRotor2(), state.getRingSettingRotor2());
|
||||
rotor3 = getRotor(state.getTypeRotor3(), state.getRotationRotor3(), state.getRingSettingRotor3());
|
||||
rotor4 = getThinRotor(state.getTypeRotor4(), state.getRotationRotor4(), state.getRingSettingRotor4());
|
||||
reflector = getReflector(state.getTypeReflector());
|
||||
plugboard.setConfiguration(state.getConfigurationPlugboard());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnigmaStateBundle getState()
|
||||
{
|
||||
EnigmaStateBundle state = new EnigmaStateBundle();
|
||||
state.setTypeEntryWheel(entryWheel.getIndex());
|
||||
|
||||
state.setTypeRotor1(rotor1.getIndex());
|
||||
state.setTypeRotor2(rotor2.getIndex());
|
||||
state.setTypeRotor3(rotor3.getIndex());
|
||||
state.setTypeRotor4(rotor4.getIndex());
|
||||
|
||||
state.setRotationRotor1(rotor1.getRotation());
|
||||
state.setRotationRotor2(rotor2.getRotation());
|
||||
state.setRotationRotor3(rotor3.getRotation());
|
||||
state.setRotationRotor4(rotor4.getRotation());
|
||||
|
||||
state.setRingSettingRotor1(rotor1.getRingSetting());
|
||||
state.setRingSettingRotor2(rotor2.getRingSetting());
|
||||
state.setRingSettingRotor3(rotor3.getRingSetting());
|
||||
state.setRingSettingRotor4(rotor4.getRingSetting());
|
||||
|
||||
state.setTypeReflector(reflector.getIndex());
|
||||
|
||||
state.setConfigurationPlugboard(plugboard.getConfiguration());
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreState(BigInteger s, int protocol_version)
|
||||
{
|
||||
switch (protocol_version)
|
||||
{
|
||||
case 1:
|
||||
int r1 = getValue(s, availableRotors.size());
|
||||
s = removeDigit(s, availableRotors.size());
|
||||
int r2 = getValue(s, availableRotors.size());
|
||||
s = removeDigit(s,availableRotors.size());
|
||||
int r3 = getValue(s, availableRotors.size());
|
||||
s = removeDigit(s,availableRotors.size());
|
||||
int r4 = getValue(s, availableThinRotors.size());
|
||||
s = removeDigit(s,availableThinRotors.size());
|
||||
int ref = getValue(s, availableReflectors.size());
|
||||
s = removeDigit(s,availableReflectors.size());
|
||||
|
||||
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);
|
||||
s = removeDigit(s, 26);
|
||||
|
||||
this.rotor1 = getRotor(r1, rot1, ring1);
|
||||
this.rotor2 = getRotor(r2, rot2, ring2);
|
||||
this.rotor3 = getRotor(r3, rot3, ring3);
|
||||
this.rotor4 = getThinRotor(r4, rot4, ring4);
|
||||
this.reflector = getReflector(ref, rotRef, ringRef);
|
||||
this.plugboard = new Plugboard();
|
||||
plugboard.setConfiguration(s);
|
||||
break;
|
||||
|
||||
default: Log.e(MainActivity.APP_ID, "Unsupported protocol version "+protocol_version);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getEncodedState(int protocol_version) {
|
||||
BigInteger s = Plugboard.configurationToBigInteger(plugboard.getConfiguration());
|
||||
s = addDigit(s, reflector.getRingSetting(), 26);
|
||||
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.getIndex(), availableReflectors.size());
|
||||
s = addDigit(s, rotor4.getIndex(), availableThinRotors.size());
|
||||
s = addDigit(s, rotor3.getIndex(), availableRotors.size());
|
||||
s = addDigit(s, rotor2.getIndex(), availableRotors.size());
|
||||
s = addDigit(s, rotor1.getIndex(), availableRotors.size());
|
||||
|
||||
s = addDigit(s, 2, 20);
|
||||
s = addDigit(s, protocol_version, MainActivity.max_protocol_version);
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,231 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.enigma;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.EntryWheel;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Reflector;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Rotor;
|
||||
|
||||
/**
|
||||
* Implementation of the Enigma machine of name R ("Rocket", Reichsbahn)
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
*/
|
||||
public class Enigma_R extends Enigma
|
||||
{
|
||||
private EntryWheel entryWheel;
|
||||
private Rotor rotor1;
|
||||
private Rotor rotor2;
|
||||
private Rotor rotor3;
|
||||
|
||||
private Reflector reflector;
|
||||
|
||||
public Enigma_R()
|
||||
{
|
||||
super();
|
||||
machineType = "R";
|
||||
Log.d(MainActivity.APP_ID, "Created Enigma R");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void establishAvailableParts() {
|
||||
addAvailableEntryWheel(new EntryWheel.EntryWheel_QWERTZ());
|
||||
addAvailableRotor(new Rotor.Rotor_R_I(0, 0));
|
||||
addAvailableRotor(new Rotor.Rotor_R_II(0,0));
|
||||
addAvailableRotor(new Rotor.Rotor_R_III(0,0));
|
||||
addAvailableReflector(new Reflector.Reflector_R());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize()
|
||||
{
|
||||
this.entryWheel = getEntryWheel(0);
|
||||
this.rotor1 = getRotor(0);
|
||||
this.rotor2 = getRotor(1);
|
||||
this.rotor3 = getRotor(2);
|
||||
this.reflector = getReflector(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextState()
|
||||
{
|
||||
rotor1.rotate();
|
||||
if (rotor1.isAtTurnoverPosition() || this.doAnomaly)
|
||||
{
|
||||
rotor2.rotate();
|
||||
this.doAnomaly = rotor2.doubleTurnAnomaly();
|
||||
if (rotor2.isAtTurnoverPosition())
|
||||
{
|
||||
rotor3.rotate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateState()
|
||||
{
|
||||
int r1, r2=-1, r3;
|
||||
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);
|
||||
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.entryWheel = getEntryWheel(0);
|
||||
this.rotor1 = getRotor(r1, rot1, ring1);
|
||||
this.rotor2 = getRotor(r2, rot2, ring2);
|
||||
this.rotor3 = getRotor(r3, rot3, ring3);
|
||||
this.reflector = getReflector(0, rotRef, 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 = getEntryWheel(state.getTypeEntryWheel());
|
||||
this.rotor1 = getRotor(state.getTypeRotor1(), state.getRotationRotor1(), state.getRingSettingRotor1());
|
||||
this.rotor2 = getRotor(state.getTypeRotor2(), state.getRotationRotor2(), state.getRingSettingRotor2());
|
||||
this.rotor3 = getRotor(state.getTypeRotor3(), state.getRotationRotor3(), state.getRingSettingRotor3());
|
||||
this.reflector = getReflector(state.getTypeReflector(), state.getRotationReflector(), state.getRingSettingReflector());
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnigmaStateBundle getState() {
|
||||
EnigmaStateBundle state = new EnigmaStateBundle();
|
||||
|
||||
state.setTypeEntryWheel(entryWheel.getIndex());
|
||||
|
||||
state.setTypeRotor1(rotor1.getIndex());
|
||||
state.setTypeRotor2(rotor2.getIndex());
|
||||
state.setTypeRotor3(rotor3.getIndex());
|
||||
|
||||
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.getIndex());
|
||||
state.setRotationReflector(reflector.getRotation());
|
||||
state.setRingSettingReflector(reflector.getRingSetting());
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreState(BigInteger s, int protocol_version)
|
||||
{
|
||||
switch (protocol_version)
|
||||
{
|
||||
case 1:
|
||||
int r1 = getValue(s,availableRotors.size());
|
||||
s = removeDigit(s,availableRotors.size());
|
||||
int r2 = getValue(s,availableRotors.size());
|
||||
s = removeDigit(s,availableRotors.size());
|
||||
int r3 = getValue(s,availableRotors.size());
|
||||
s = removeDigit(s,availableRotors.size());
|
||||
|
||||
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);
|
||||
s = removeDigit(s, 26);
|
||||
|
||||
this.entryWheel = getEntryWheel(0);
|
||||
this.rotor1 = getRotor(r1, rot1, ring1);
|
||||
this.rotor2 = getRotor(r2, rot2, ring2);
|
||||
this.rotor3 = getRotor(r3, rot3, ring3);
|
||||
this.reflector = getReflector(0, rotRef, ringRef);
|
||||
break;
|
||||
|
||||
default: Log.e(MainActivity.APP_ID, "Unsupported protocol version "+protocol_version);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getEncodedState(int protocol_version)
|
||||
{
|
||||
BigInteger s = BigInteger.valueOf(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.getIndex(), availableRotors.size());
|
||||
s = addDigit(s, rotor2.getIndex(), availableRotors.size());
|
||||
s = addDigit(s, rotor1.getIndex(), availableRotors.size());
|
||||
|
||||
s = addDigit(s, 10, 20); //Machine #10
|
||||
s = addDigit(s, protocol_version, MainActivity.max_protocol_version);
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,228 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.enigma;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.EntryWheel;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Reflector;
|
||||
import de.vanitasvitae.enigmandroid.enigma.parts.Rotor;
|
||||
|
||||
/**
|
||||
* Implementation of the Enigma machine of name T Tirpitz
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
*/
|
||||
public class Enigma_T extends Enigma
|
||||
{
|
||||
private EntryWheel entryWheel;
|
||||
private Rotor rotor1;
|
||||
private Rotor rotor2;
|
||||
private Rotor rotor3;
|
||||
private Reflector reflector;
|
||||
|
||||
public Enigma_T()
|
||||
{
|
||||
super();
|
||||
machineType = "T";
|
||||
Log.d(MainActivity.APP_ID, "Created Enigma T");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void establishAvailableParts() {
|
||||
addAvailableEntryWheel(new EntryWheel.EntryWheel_T());
|
||||
addAvailableRotor(new Rotor.Rotor_T_I(0, 0));
|
||||
addAvailableRotor(new Rotor.Rotor_T_II(0,0));
|
||||
addAvailableRotor(new Rotor.Rotor_T_III(0,0));
|
||||
addAvailableRotor(new Rotor.Rotor_T_IV(0,0));
|
||||
addAvailableRotor(new Rotor.Rotor_T_V(0,0));
|
||||
addAvailableRotor(new Rotor.Rotor_T_VI(0,0));
|
||||
addAvailableRotor(new Rotor.Rotor_T_VII(0,0));
|
||||
addAvailableRotor(new Rotor.Rotor_T_VIII(0,0));
|
||||
addAvailableReflector(new Reflector.ReflectorEnigma_T());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
this.entryWheel = getEntryWheel(0);
|
||||
this.rotor1 = getRotor(0);
|
||||
this.rotor2 = getRotor(1);
|
||||
this.rotor3 = getRotor(2);
|
||||
this.reflector = getReflector(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextState()
|
||||
{
|
||||
rotor1.rotate();
|
||||
if (rotor1.isAtTurnoverPosition() || this.doAnomaly)
|
||||
{
|
||||
rotor2.rotate();
|
||||
this.doAnomaly = rotor2.doubleTurnAnomaly();
|
||||
if (rotor2.isAtTurnoverPosition())
|
||||
{
|
||||
rotor3.rotate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateState() {
|
||||
int r1, r2=-1, r3=-1;
|
||||
r1 = rand.nextInt(8);
|
||||
while(r2 == -1 || r2 == r1) r2 = rand.nextInt(8);
|
||||
while(r3 == -1 || r3 == r2 || r3 == r1) r3 = rand.nextInt(8);
|
||||
|
||||
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.entryWheel = getEntryWheel(0);
|
||||
this.rotor1 = getRotor(r1, rot1, ring1);
|
||||
this.rotor2 = getRotor(r2, rot2, ring2);
|
||||
this.rotor3 = getRotor(r3, rot3, ring3);
|
||||
this.reflector = getReflector(0, rotRef, 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 = getEntryWheel(0);
|
||||
this.rotor1 = getRotor(state.getTypeRotor1(), state.getRotationRotor1(), state.getRingSettingRotor1());
|
||||
this.rotor2 = getRotor(state.getTypeRotor2(), state.getRotationRotor2(), state.getRingSettingRotor2());
|
||||
this.rotor3 = getRotor(state.getTypeRotor3(), state.getRotationRotor3(), state.getRingSettingRotor3());
|
||||
this.reflector = getReflector(state.getTypeReflector(), state.getRotationReflector(), state.getRingSettingReflector());
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnigmaStateBundle getState()
|
||||
{
|
||||
EnigmaStateBundle state = new EnigmaStateBundle();
|
||||
|
||||
state.setTypeRotor1(rotor1.getIndex());
|
||||
state.setTypeRotor2(rotor2.getIndex());
|
||||
state.setTypeRotor3(rotor3.getIndex());
|
||||
|
||||
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.getIndex());
|
||||
state.setRotationReflector(reflector.getRotation());
|
||||
state.setRingSettingReflector(reflector.getRingSetting());
|
||||
state.setTypeEntryWheel(entryWheel.getIndex());
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreState(BigInteger s, int protocol_version)
|
||||
{
|
||||
switch (protocol_version)
|
||||
{
|
||||
case 1:
|
||||
int r1 = getValue(s,availableRotors.size());
|
||||
s = removeDigit(s,availableRotors.size());
|
||||
int r2 = getValue(s,availableRotors.size());
|
||||
s = removeDigit(s,availableRotors.size());
|
||||
int r3 = getValue(s,availableRotors.size());
|
||||
s = removeDigit(s,availableRotors.size());
|
||||
|
||||
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 = getRotor(r1, rot1, ring1);
|
||||
this.rotor2 = getRotor(r2, rot2, ring2);
|
||||
this.rotor3 = getRotor(r3, rot3, ring3);
|
||||
this.reflector = getReflector(0, rotRef, ringRef);
|
||||
break;
|
||||
|
||||
default: Log.e(MainActivity.APP_ID, "Unsupported protocol version "+protocol_version);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigInteger getEncodedState(int protocol_version)
|
||||
{
|
||||
BigInteger s = BigInteger.valueOf(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.getIndex(), availableRotors.size());
|
||||
s = addDigit(s, rotor2.getIndex(), availableRotors.size());
|
||||
s = addDigit(s, rotor1.getIndex(), availableRotors.size());
|
||||
|
||||
s = addDigit(s, 11, 20); //Machine #11
|
||||
s = addDigit(s, protocol_version, MainActivity.max_protocol_version);
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
|
@ -1,164 +0,0 @@
|
|||
package de.vanitasvitae.enigmandroid.enigma;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.R;
|
||||
|
||||
/**
|
||||
* Plugboard of the enigma
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* @author vanitasvitae
|
||||
*/
|
||||
public class Plugboard
|
||||
{
|
||||
Integer[] plugs;
|
||||
|
||||
public Plugboard()
|
||||
{
|
||||
plugs = new Integer[26];
|
||||
}
|
||||
|
||||
public Plugboard(int[][] configuration)
|
||||
{
|
||||
setConfiguration(configuration);
|
||||
}
|
||||
|
||||
public Plugboard(String configuration)
|
||||
{
|
||||
setConfiguration(parseConfigurationString(configuration));
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the plugboard according to the given array.
|
||||
*
|
||||
* @param configuration two dimensional array of plugs
|
||||
*/
|
||||
public void setConfiguration(int[][] configuration)
|
||||
{
|
||||
if(configuration != null) {
|
||||
boolean validConfiguration = true;
|
||||
plugs = new Integer[26];
|
||||
for (int[] p : configuration) {
|
||||
if (!setPlugs(p[0], p[1])) {
|
||||
validConfiguration = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!validConfiguration) plugs = new Integer[26];
|
||||
}
|
||||
else plugs = new Integer[26];
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse configuration from input string
|
||||
* input must have the following form: "" or "XY" or "XY,VW" or "XY,...,AB"
|
||||
* A character must not be inside the input multiple times. Exception is ','
|
||||
* This is not catched here!
|
||||
* @param input String that codes the configuration
|
||||
* @return two dimensional array of plugged symbols
|
||||
*/
|
||||
public static int[][] parseConfigurationString(String input)
|
||||
{
|
||||
Activity activity = MainActivity.ActivitySingleton.getInstance().getActivity();
|
||||
//If length != 0,2,5,8... ( ,XY, XY-VW, ...)
|
||||
if(((input.length()+1)%3)!=0&&input.length()!=0)
|
||||
{
|
||||
Toast.makeText(activity.getApplicationContext(), R.string.error_parsing_plugs,
|
||||
Toast.LENGTH_LONG).show();
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
input = input.toUpperCase();
|
||||
ArrayList<int[]> plugList = new ArrayList<>();
|
||||
int[] plug = new int[2];
|
||||
for (int i = 0; i < input.length(); i++) {
|
||||
int c = input.charAt(i) - 65;
|
||||
if (c < 0 || c > 25) {
|
||||
if (i % 3 != 2) {
|
||||
Toast.makeText(activity.getApplicationContext(), R.string.error_parsing_plugs,
|
||||
Toast.LENGTH_LONG).show();
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
if (i % 3 == 0) {
|
||||
plug = new int[2];
|
||||
plug[0] = c;
|
||||
}
|
||||
if (i % 3 == 1) {
|
||||
plug[1] = c;
|
||||
plugList.add(plug);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
int[][] parsedConfiguration = new int[plugList.size()][2];
|
||||
for(int i=0; i<plugList.size(); i++)
|
||||
{
|
||||
parsedConfiguration[i] = plugList.get(i);
|
||||
}
|
||||
return parsedConfiguration;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the given plugs (connect a and b)
|
||||
* Return false, if something goes wrong (plugs already used somehow)
|
||||
* @param a first plug
|
||||
* @param b second plug
|
||||
* @return success
|
||||
*/
|
||||
public boolean setPlugs(int a, int b)
|
||||
{
|
||||
Activity activity = MainActivity.ActivitySingleton.getInstance().getActivity();
|
||||
if(a==b)
|
||||
{
|
||||
Toast.makeText(activity.getApplication().getApplicationContext(),
|
||||
activity.getResources().getText(R.string.error_unable_to_plug_a_b).toString()
|
||||
+" "+(char)(a+65)+","+(char) (b+65),Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
if(plugs[a] != null || plugs[b] != null)
|
||||
{
|
||||
Toast.makeText(activity.getApplication().getApplicationContext(),
|
||||
activity.getResources().getText(R.string.error_plug_already_in_use).toString()
|
||||
+" "+(char) (a+65)+","+(char)(b +65), Toast.LENGTH_SHORT).show();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
plugs[a] = b;
|
||||
plugs[b] = a;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt input via plugboard connections
|
||||
* @param input input symbol to encrypt
|
||||
* @return encrypted symbol
|
||||
*/
|
||||
public int encrypt(int input)
|
||||
{
|
||||
if(plugs[input]==null) return input;
|
||||
else return plugs[input];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.enigma.inputPreparer;
|
||||
|
||||
import android.widget.EditText;
|
||||
|
||||
/**
|
||||
* Adapter-like connector between text fields and string-outputting-whatever blah
|
||||
* Use this to modify the way strings get displayed without modifying the string itself.
|
||||
*/
|
||||
public abstract class EditTextAdapter
|
||||
{
|
||||
EditText editText;
|
||||
String content;
|
||||
|
||||
EditTextAdapter(EditText editText)
|
||||
{
|
||||
this.editText = editText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unmodified text
|
||||
* @return content
|
||||
*/
|
||||
public String getText()
|
||||
{
|
||||
if(editText.getText().length() != 0)
|
||||
return content;
|
||||
else return content = "";
|
||||
}
|
||||
|
||||
public String getModifiedText()
|
||||
{
|
||||
return editText.getText().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text to both the content and the editText without modifying it
|
||||
* @param text text
|
||||
*/
|
||||
public void setRawText(String text)
|
||||
{
|
||||
this.content = text;
|
||||
this.editText.setText(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method needs to be overwritten by the programmer.
|
||||
* The coder has to make sure, content gets set to text and also that the editText element
|
||||
* gets updated with the modified text
|
||||
* @param text text
|
||||
*/
|
||||
public abstract void setText(String text);
|
||||
|
||||
public static EditTextAdapter createEditTextAdapter(EditText editText, String type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case "4": return new EditTextAdapterGap(editText, 4);
|
||||
case "5": return new EditTextAdapterGap(editText, 5);
|
||||
case "6": return new EditTextAdapterGap(editText, 6);
|
||||
case "no": return new EditTextAdapterNoGap(editText);
|
||||
default: return new EditTextAdapterNoGap(editText);
|
||||
}
|
||||
}
|
||||
|
||||
public static class EditTextAdapterNoGap extends EditTextAdapter
|
||||
{
|
||||
public EditTextAdapterNoGap(EditText editText)
|
||||
{
|
||||
super(editText);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setText(String text)
|
||||
{
|
||||
this.content = text;
|
||||
this.editText.setText(text);
|
||||
}
|
||||
}
|
||||
|
||||
public static class EditTextAdapterGap extends EditTextAdapter
|
||||
{
|
||||
int blockSize;
|
||||
public EditTextAdapterGap(EditText editText, int blockSize)
|
||||
{
|
||||
super(editText);
|
||||
this.blockSize = blockSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setText(String text)
|
||||
{
|
||||
this.content = text;
|
||||
String out = "";
|
||||
int i;
|
||||
for(i=0; i<text.length()/blockSize; i++)
|
||||
{
|
||||
out = out + text.substring(i*blockSize, (i+1)*blockSize);
|
||||
out = out + " ";
|
||||
}
|
||||
out = out + text.substring(i*blockSize);
|
||||
this.editText.setText(out);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,146 +1,253 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.enigma.inputPreparer;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.R;
|
||||
import de.vanitasvitae.enigmandroid.SettingsActivity;
|
||||
|
||||
/**
|
||||
* Preparer class that prepares input text to only consist of [A..Z]
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* @author vanitasvitae
|
||||
*/
|
||||
public abstract class InputPreparer
|
||||
{
|
||||
/**
|
||||
* Prepare the input String in a way that it only contains letters from [A..Z].
|
||||
* Replace special characters, remove spaces and spell numbers.
|
||||
* @param input String
|
||||
* @return prepared String
|
||||
*/
|
||||
public String prepareString(String input)
|
||||
{
|
||||
input = input.toUpperCase();
|
||||
input = input.replace("Ä","AE").replace("Ö","OE").replace("Ü","UE").replace("ß","SS");
|
||||
String output = "";
|
||||
public abstract class InputPreparer {
|
||||
InputPreparer child;
|
||||
|
||||
for (char x : input.toCharArray())
|
||||
public String prepareString(String in) {
|
||||
if (child != null)
|
||||
return child.prepareString(this.prepare(in));
|
||||
else
|
||||
return prepare(in);
|
||||
}
|
||||
|
||||
protected abstract String prepare(String input);
|
||||
|
||||
public static InputPreparer createInputPreparer()
|
||||
{
|
||||
MainActivity main = (MainActivity) MainActivity.ActivitySingleton.getInstance().getActivity();
|
||||
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(main);
|
||||
|
||||
boolean replaceSpecialChars = sharedPreferences.getBoolean(SettingsActivity.PREF_REPLACE_SPECIAL_CHARACTERS, true);
|
||||
String num_lang = sharedPreferences.getString(SettingsActivity.PREF_NUMERIC_LANGUAGE, main.getResources().
|
||||
getStringArray(R.array.pref_alias_numeric_spelling_language)[0]);
|
||||
InputPreparer inPrep = new RemoveIllegalCharacters();
|
||||
if(replaceSpecialChars) inPrep = new ReplaceSpecialCharacters(inPrep);
|
||||
switch (num_lang)
|
||||
{
|
||||
if (x >= 65 && x <= 90) //x in [A..Z]
|
||||
{
|
||||
output = output + x;
|
||||
}
|
||||
else if (x >= 48 && x <= 57) //x in [0..9]
|
||||
{
|
||||
output = output + replaceNumber(x);
|
||||
}
|
||||
//x is special symbol
|
||||
else if (x != ' ')
|
||||
{
|
||||
output = output + 'X';
|
||||
}
|
||||
case "de": inPrep = new ReplaceNumbersGerman(inPrep);
|
||||
break;
|
||||
case "en": inPrep = new ReplaceNumbersEnglish(inPrep);
|
||||
break;
|
||||
case "fr": inPrep = new ReplaceNumbersFrench(inPrep);
|
||||
break;
|
||||
case "sp": inPrep = new ReplaceNumbersSpanish(inPrep);
|
||||
break;
|
||||
case "it": inPrep = new ReplaceNumbersItalian(inPrep);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return inPrep;
|
||||
}
|
||||
|
||||
public static class ReplaceSpecialCharacters extends InputPreparer {
|
||||
// --Commented out by Inspection START (07.11.15 19:47):
|
||||
// public ReplaceSpecialCharacters() {
|
||||
// this.child = null;
|
||||
// }
|
||||
// --Commented out by Inspection STOP (07.11.15 19:47)
|
||||
|
||||
public ReplaceSpecialCharacters(InputPreparer child) {
|
||||
this.child = child;
|
||||
}
|
||||
|
||||
protected String prepare(String input) {
|
||||
input = input.toUpperCase();
|
||||
return input.replace("Ä", "AE").replace("Ö", "OE").replace("Ü", "UE").replace("ß", "SS").replace(" ","");
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract method that spells numbers in a certain language specified by the implementation
|
||||
* @param input character
|
||||
* @return spelled number
|
||||
* Concrete implementation of a german InputPreparer
|
||||
*/
|
||||
public abstract String replaceNumber(char input);
|
||||
public static class ReplaceNumbersGerman extends InputPreparer {
|
||||
// --Commented out by Inspection START (07.11.15 19:47):
|
||||
// public ReplaceNumbersGerman() {
|
||||
// this.child = null;
|
||||
// }
|
||||
// --Commented out by Inspection STOP (07.11.15 19:47)
|
||||
|
||||
public ReplaceNumbersGerman(InputPreparer child) {
|
||||
this.child = child;
|
||||
}
|
||||
|
||||
protected String prepare(String input) {
|
||||
input = input.replace("0", "NULL")
|
||||
.replace("1", "EINS")
|
||||
.replace("2", "ZWEI")
|
||||
.replace("3", "DREI")
|
||||
.replace("4", "VIER")
|
||||
.replace("5", "FUENF")
|
||||
.replace("6", "SECHS")
|
||||
.replace("7", "SIEBEN")
|
||||
.replace("8", "ACHT")
|
||||
.replace("9", "NEUN");
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method that creates a specific InputPreparer
|
||||
* @param language language alias that specifies the language (de,fr,en)
|
||||
* @return concrete InputPreparer
|
||||
* Concrete implementation of a french InputPreparer
|
||||
*/
|
||||
public static InputPreparer createInputPreparer(String language)
|
||||
public static class ReplaceNumbersFrench extends InputPreparer {
|
||||
// --Commented out by Inspection START (07.11.15 19:47):
|
||||
// public ReplaceNumbersFrench() {
|
||||
// this.child = null;
|
||||
// }
|
||||
// --Commented out by Inspection STOP (07.11.15 19:47)
|
||||
|
||||
public ReplaceNumbersFrench(InputPreparer child) {
|
||||
this.child = child;
|
||||
}
|
||||
|
||||
protected String prepare(String input) {
|
||||
input = input.replace("0", "ZERO")
|
||||
.replace("1", "UN")
|
||||
.replace("2", "DEUX")
|
||||
.replace("3", "TROIS")
|
||||
.replace("4", "QUATRE")
|
||||
.replace("5", "CINQ")
|
||||
.replace("6", "SIX")
|
||||
.replace("7", "SEPT")
|
||||
.replace("8", "HUIT")
|
||||
.replace("9", "NEUF");
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of an english InputPreparer
|
||||
*/
|
||||
public static class ReplaceNumbersEnglish extends InputPreparer {
|
||||
// --Commented out by Inspection START (07.11.15 19:47):
|
||||
// public ReplaceNumbersEnglish() {
|
||||
// this.child = null;
|
||||
// }
|
||||
// --Commented out by Inspection STOP (07.11.15 19:47)
|
||||
|
||||
public ReplaceNumbersEnglish(InputPreparer child) {
|
||||
this.child = child;
|
||||
}
|
||||
|
||||
protected String prepare(String input) {
|
||||
input = input.replace("0", "ZERO")
|
||||
.replace("1", "ONE")
|
||||
.replace("2", "TWO")
|
||||
.replace("3", "THREE")
|
||||
.replace("4", "FOUR")
|
||||
.replace("5", "FIVE")
|
||||
.replace("6", "SIX")
|
||||
.replace("7", "SEVEN")
|
||||
.replace("8", "EIGHT")
|
||||
.replace("9", "NINE");
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of a spanish InputPreparer
|
||||
*/
|
||||
public static class ReplaceNumbersSpanish extends InputPreparer {
|
||||
// --Commented out by Inspection START (07.11.15 19:47):
|
||||
// public ReplaceNumbersSpanish() {
|
||||
// this.child = null;
|
||||
// }
|
||||
// --Commented out by Inspection STOP (07.11.15 19:47)
|
||||
|
||||
public ReplaceNumbersSpanish(InputPreparer child) {
|
||||
this.child = child;
|
||||
}
|
||||
|
||||
protected String prepare(String input) {
|
||||
input = input.replace("0", "CERO")
|
||||
.replace("1", "UNO")
|
||||
.replace("2", "DOS")
|
||||
.replace("3", "TRES")
|
||||
.replace("4", "CUATRO")
|
||||
.replace("5", "CINCO")
|
||||
.replace("6", "SEIS")
|
||||
.replace("7", "SIETE")
|
||||
.replace("8", "OCHO")
|
||||
.replace("9", "NUEVE");
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of a spanish InputPreparer
|
||||
*/
|
||||
public static class ReplaceNumbersItalian extends InputPreparer {
|
||||
// --Commented out by Inspection START (07.11.15 19:47):
|
||||
// public ReplaceNumbersItalian() {
|
||||
// this.child = null;
|
||||
// }
|
||||
// --Commented out by Inspection STOP (07.11.15 19:47)
|
||||
|
||||
public ReplaceNumbersItalian(InputPreparer child) {
|
||||
this.child = child;
|
||||
}
|
||||
|
||||
protected String prepare(String input) {
|
||||
input = input.replace("0", "ZERO")
|
||||
.replace("1", "UNO")
|
||||
.replace("2", "DUE")
|
||||
.replace("3", "TRE")
|
||||
.replace("4", "QUATTRO")
|
||||
.replace("5", "CINQUE")
|
||||
.replace("6", "SEI")
|
||||
.replace("7", "SETTE")
|
||||
.replace("8", "OTTO")
|
||||
.replace("9", "NOVE");
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* "Final Stage" of Input preparing. This should always be called last
|
||||
* (choose this as the inner most capsule of InputPreparers)
|
||||
* This cant have child InputPreparers.
|
||||
* This Input preparer removes all characters from the string besides A..Z
|
||||
*/
|
||||
public static class RemoveIllegalCharacters extends InputPreparer
|
||||
{
|
||||
switch (language)
|
||||
public RemoveIllegalCharacters()
|
||||
{
|
||||
case "de": return new InputPreparerGerman();
|
||||
case "fr": return new InputPreparerFrench();
|
||||
default: return new InputPreparerEnglish();
|
||||
this.child = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of a german InputPreparer
|
||||
*/
|
||||
class InputPreparerGerman extends InputPreparer
|
||||
{
|
||||
@Override
|
||||
public String replaceNumber(char input) {
|
||||
switch (input)
|
||||
protected String prepare(String in)
|
||||
{
|
||||
case '0': return "NULL";
|
||||
case '1': return "EINS";
|
||||
case '2': return "ZWEI";
|
||||
case '3': return "DREI";
|
||||
case '4': return "VIER";
|
||||
case '5': return "FUENF";
|
||||
case '6': return "SECHS";
|
||||
case '7': return "SIEBEN";
|
||||
case '8': return "ACHT";
|
||||
default: return "NEUN";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of an english InputPreparer
|
||||
*/
|
||||
class InputPreparerEnglish extends InputPreparer
|
||||
{
|
||||
@Override
|
||||
public String replaceNumber(char input)
|
||||
{
|
||||
switch (input) {
|
||||
case '0': return "ZERO";
|
||||
case '1': return "ONE";
|
||||
case '2': return "TWO";
|
||||
case '3': return "THREE";
|
||||
case '4': return "FOUR";
|
||||
case '5': return "FIVE";
|
||||
case '6': return "SIX";
|
||||
case '7': return "SEVEN";
|
||||
case '8': return "EIGHT";
|
||||
default: return "NINE";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of a french InputPreparer
|
||||
*/
|
||||
class InputPreparerFrench extends InputPreparer
|
||||
{
|
||||
|
||||
@Override
|
||||
public String replaceNumber(char input)
|
||||
{
|
||||
switch (input) {
|
||||
case '0': return "ZERO";
|
||||
case '1': return "UN";
|
||||
case '2': return "DEUX";
|
||||
case '3': return "TROIS";
|
||||
case '4': return "QUATRE";
|
||||
case '5': return "CINQ";
|
||||
case '6': return "SIX";
|
||||
case '7': return "SEPT";
|
||||
case '8': return "HUIT";
|
||||
default: return "NEUF";
|
||||
String out = "";
|
||||
for(char c : in.toUpperCase().toCharArray())
|
||||
{
|
||||
if(c>=65 && c<=90) out = out+c;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.enigma.parts;
|
||||
|
||||
/**
|
||||
* Implementation of several EntryWheels
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
*/
|
||||
public class EntryWheel
|
||||
{
|
||||
private final int type;
|
||||
private final String name;
|
||||
private int index;
|
||||
private final String summary;
|
||||
private final Integer[] connections;
|
||||
private final Integer[] reversedConnections;
|
||||
|
||||
EntryWheel(int type, String name, String summary, Integer[] connections, Integer[] reversedConnections)
|
||||
{
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.summary = summary;
|
||||
this.connections = connections;
|
||||
this.reversedConnections = reversedConnections;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new EntryWheel of the same type as the callee
|
||||
* @return new EntryWheel
|
||||
*/
|
||||
public EntryWheel getInstance()
|
||||
{
|
||||
return createEntryWheel(this.type).setIndex(this.getIndex());
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt an input signal via the internal wiring in "forward" direction towards the reflector
|
||||
* (using connections)
|
||||
* @param input signal
|
||||
* @return encrypted signal
|
||||
*/
|
||||
public int encryptForward(int input)
|
||||
{
|
||||
return this.connections[normalize(input)];
|
||||
}
|
||||
|
||||
private int normalize(int input)
|
||||
{
|
||||
return (input+this.connections.length)%this.connections.length;
|
||||
}
|
||||
|
||||
public EntryWheel setIndex(int index)
|
||||
{
|
||||
this.index = index;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getIndex()
|
||||
{
|
||||
return this.index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt an input signal via the internal wiring in "backwards" direction (using
|
||||
* reversedConnections)
|
||||
* @param input signal
|
||||
* @return encrypted signal
|
||||
*/
|
||||
public int encryptBackward(int input)
|
||||
{
|
||||
return this.reversedConnections[normalize(input)];
|
||||
}
|
||||
|
||||
private EntryWheel createEntryWheel(int type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case 1:
|
||||
return new EntryWheel_QWERTZ();
|
||||
case 2:
|
||||
return new EntryWheel_T();
|
||||
default: return new EntryWheel_ABCDEF();
|
||||
}
|
||||
}
|
||||
|
||||
public static class EntryWheel_ABCDEF extends EntryWheel
|
||||
{
|
||||
public EntryWheel_ABCDEF()
|
||||
{
|
||||
super(0, "ABCDEF", "abcdefghijklmnopqrstuvwxyz",
|
||||
new Integer[]{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25},
|
||||
new Integer[]{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* EntryWheel as used in the Enigma models D, K, G
|
||||
* Q W E R T Z U I O A S D F G H J K P Y X C V B N M L
|
||||
*/
|
||||
public static class EntryWheel_QWERTZ extends EntryWheel
|
||||
{
|
||||
public EntryWheel_QWERTZ()
|
||||
{
|
||||
super(1, "QWERTZ", "qwertzuioasdfghjkpyxcvbnml",
|
||||
new Integer[]{9,22,20,11,2,12,13,14,7,15,16,25,24,23,8,17,0,3,10,4,6,21,1,19,18,5},
|
||||
new Integer[]{16,22,4,17,19,25,20,8,14,0,18,3,5,6,7,9,10,15,24,23,2,21,1,13,12,11});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* EntryWheel as used only in the Enigma Type T Tirpitz
|
||||
* K Z R O U Q H Y A I G B L W V S T D X F P N M C J E
|
||||
*/
|
||||
public static class EntryWheel_T extends EntryWheel
|
||||
{
|
||||
public EntryWheel_T()
|
||||
{
|
||||
super(2, "KZROUQ", "kzrouqhyaigblwvstdxfpnmcje",
|
||||
new Integer[]{8,11,23,17,25,19,10,6,9,24,0,12,22,21,3,20,5,2,15,16,4,14,13,18,7,1},
|
||||
new Integer[]{10,25,17,14,20,16,7,24,0,8,6,1,11,22,21,18,19,3,23,5,15,13,12,2,9,4});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,219 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.enigma.parts;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.enigma.Enigma;
|
||||
import de.vanitasvitae.enigmandroid.enigma.inputPreparer.InputPreparer;
|
||||
|
||||
/**
|
||||
* Plugboard of the enigma
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
*/
|
||||
public class Plugboard
|
||||
{
|
||||
private static final int[] empty = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25};
|
||||
private int[] plugs;
|
||||
|
||||
public Plugboard()
|
||||
{
|
||||
plugs = Arrays.copyOf(empty, empty.length);
|
||||
}
|
||||
|
||||
public Plugboard(int[] conf)
|
||||
{
|
||||
this.plugs = conf;
|
||||
}
|
||||
|
||||
public void setConfiguration(int[] conf)
|
||||
{
|
||||
this.plugs = conf;
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnusedReturnValue")
|
||||
public BigInteger setConfiguration(BigInteger b)
|
||||
{
|
||||
String s = "";
|
||||
|
||||
int x;
|
||||
while((x = Enigma.getValue(b, 27)) != 26 && b.compareTo(BigInteger.ZERO) > 1)
|
||||
{
|
||||
s = ((char) (x+65))+s;
|
||||
b = Enigma.removeDigit(b, 27);
|
||||
}
|
||||
this.setConfiguration(stringToConfiguration(s));
|
||||
return b;
|
||||
}
|
||||
|
||||
public int[] getConfiguration()
|
||||
{
|
||||
return this.plugs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt input via plugboard connections
|
||||
* @param input input symbol to encryptString
|
||||
* @return encrypted symbol
|
||||
*/
|
||||
public int encrypt(int input)
|
||||
{
|
||||
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 = Arrays.copyOf(empty, empty.length);
|
||||
//Check if in is too long or odd
|
||||
int l = pairs.length();
|
||||
if(l>1 && (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 = Arrays.copyOf(empty,empty.length);
|
||||
for (int i=0; i<out.length/2; i++) {
|
||||
int rA = rand.nextInt(26);
|
||||
while (out[rA] != rA) rA = (rA + 27) % 26;
|
||||
int rB = rand.nextInt(26);
|
||||
while (out[rB] != rB || rA == rB) rB = (rB + 27) % 26;
|
||||
out[rA] = rB;
|
||||
out[rB] = rA;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a configurations array back to a String representation
|
||||
* @param c array
|
||||
* @return String representation
|
||||
*/
|
||||
private 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;
|
||||
}
|
||||
|
||||
public static BigInteger configurationToBigInteger(int[] a)
|
||||
{
|
||||
String s = configurationToString(a);
|
||||
BigInteger l = BigInteger.ZERO;
|
||||
l = Enigma.addDigit(l,26,27);
|
||||
for(char c : s.toCharArray())
|
||||
{
|
||||
int i = (int) (c);
|
||||
i-=65;
|
||||
l = Enigma.addDigit(l,i,27);
|
||||
}
|
||||
Log.d(MainActivity.APP_ID, "Save configuration plugs: "+l.toString());
|
||||
return l;
|
||||
}
|
||||
|
||||
public static int[] bigIntegerToConfiguration(BigInteger b)
|
||||
{
|
||||
String s = "";
|
||||
int x;
|
||||
while((x = Enigma.getValue(b, 27)) != 26 && b.compareTo(BigInteger.ZERO) > 1)
|
||||
{
|
||||
s = ((char) (x+65))+s;
|
||||
b = Enigma.removeDigit(b, 27);
|
||||
}
|
||||
Log.d(MainActivity.APP_ID, "Restored: "+s);
|
||||
return stringToConfiguration(s);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,355 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.enigma.parts;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.enigma.Enigma;
|
||||
|
||||
/**
|
||||
* Reflector of the enigma machine.
|
||||
* The reflector was used to reflect the scrambled signal at the end of the wiring back to
|
||||
* go through another (reversed but not inverting) process of scrambling.
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
*/
|
||||
public class Reflector
|
||||
{
|
||||
private final int type;
|
||||
private final String name;
|
||||
private int index;
|
||||
private final String summary;
|
||||
private int[] connections;
|
||||
private int rotation;
|
||||
private int ringSetting;
|
||||
|
||||
/**
|
||||
* This constructor is not accessible from outside this class file.
|
||||
* Use the one of the createReflector* methods instead to create concrete Reflectors from
|
||||
* outside this class file
|
||||
* @param type name indicator of the reflector
|
||||
* @param connections wiring of the reflector as Integer array
|
||||
*/
|
||||
Reflector(int type, String name, String summary, int[] connections)
|
||||
{
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.summary = summary;
|
||||
this.connections = connections;
|
||||
}
|
||||
|
||||
public Reflector getInstance()
|
||||
{
|
||||
//noinspection ConstantConditions
|
||||
return createReflector(this.type).setIndex(this.getIndex());
|
||||
}
|
||||
|
||||
public Reflector getInstance(int rotation, int ringSetting)
|
||||
{
|
||||
//noinspection ConstantConditions
|
||||
return createReflector(this.type).setIndex(this.getIndex())
|
||||
.setRotation(rotation).setRingSetting(ringSetting);
|
||||
}
|
||||
|
||||
public Reflector setIndex(int index)
|
||||
{
|
||||
this.index = index;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getIndex()
|
||||
{
|
||||
return this.index;
|
||||
}
|
||||
|
||||
public int getRotation()
|
||||
{
|
||||
return rotation;
|
||||
}
|
||||
|
||||
public int getRingSetting()
|
||||
{
|
||||
return ringSetting;
|
||||
}
|
||||
|
||||
public Reflector setRotation(int rotation)
|
||||
{
|
||||
this.rotation = rotation;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Reflector setRingSetting(int ringSetting)
|
||||
{
|
||||
this.ringSetting = ringSetting;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Reflector setConfiguration(int[] c)
|
||||
{
|
||||
this.connections = c;
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnusedReturnValue")
|
||||
public BigInteger setConfiguration(BigInteger b)
|
||||
{
|
||||
String s = "";
|
||||
|
||||
int x;
|
||||
while((x = Enigma.getValue(b, 27)) != 26 || b.compareTo(BigInteger.ZERO) > 1)
|
||||
{
|
||||
s = ((char) (x+65))+s;
|
||||
b = Enigma.removeDigit(b, 27);
|
||||
}
|
||||
Log.d(MainActivity.APP_ID, "Restored: " + s);
|
||||
this.setConfiguration(Plugboard.stringToConfiguration(s));
|
||||
return b;
|
||||
}
|
||||
|
||||
public int[] getConfiguration()
|
||||
{
|
||||
return connections;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to create reflectors.
|
||||
* @param type name of the created reflector
|
||||
* 1 -> ReflectorA
|
||||
* 2 -> ReflectorB
|
||||
* 3 -> ReflectorC
|
||||
* 4 -> ReflectorThinB
|
||||
* 5 -> ReflectorThinC
|
||||
* 6 -> ReflectorEnigma_D_KD_G31
|
||||
* 7 -> Reflector_K
|
||||
* 8 -> Reflector_T
|
||||
* 9 -> Reflector_G312
|
||||
* 10 -> Reflector_G260
|
||||
* 11 -> Reflector_R
|
||||
* default -> ReflectorB
|
||||
* @return Reflector
|
||||
*/
|
||||
private static Reflector createReflector(int type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case 0: return new Reflector_A();
|
||||
case 1: return new Reflector_B();
|
||||
case 2: return new Reflector_C();
|
||||
case 10: return new Reflector_Thin_B();
|
||||
case 11: return new ReflectorThinC();
|
||||
case 20: return new ReflectorEnigma_D_G31();
|
||||
case 21: return new ReflectorEnigma_KD();
|
||||
case 30: return new Reflector_G312();
|
||||
case 40: return new Reflector_K_G260();
|
||||
case 50: return new Reflector_R();
|
||||
case 60: return new ReflectorEnigma_T();
|
||||
|
||||
default:
|
||||
Log.e(MainActivity.APP_ID," Tried to create Reflector of invalid name "+type);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Substitute an input signal via the wiring of the reflector with a different (!) output.
|
||||
* The output MUST not be equal to the input for any input, since this was not possible
|
||||
* due to the electronic implementation of the historical enigma machine.
|
||||
* @param input input signal
|
||||
* @return encrypted (substituted) output
|
||||
*/
|
||||
public int encrypt(int input)
|
||||
{
|
||||
return this.connections[normalize(input)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the size (ie the number of wires/length of the connections array) of the reflector
|
||||
* @return size
|
||||
*/
|
||||
private int getRotorSize()
|
||||
{
|
||||
return this.connections.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize the input.
|
||||
* Normalizing means keeping the input via modulo in the range from 0 to n-1, where n is equal
|
||||
* to the size of the reflector. This is necessary since java allows negative modulo values,
|
||||
* which can break this implementation
|
||||
* @param input input signal
|
||||
* @return "normalized" input signal
|
||||
*/
|
||||
private int normalize(int input)
|
||||
{
|
||||
return (input + this.getRotorSize()) % this.getRotorSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of ReflectorA
|
||||
* Used in Enigma I
|
||||
* AE BJ CM DZ FL GY HX IV KW NR OQ PU ST
|
||||
*/
|
||||
public static class Reflector_A extends Reflector
|
||||
{
|
||||
public Reflector_A()
|
||||
{
|
||||
super(0, "A", "EJMZALYXVBWFCRQUONTSPIKHGD",
|
||||
new int[]{4,9,12,25,0,11,24,23,21,1,22,5,2,17,16,20,14,13,19,18,15,8,10,7,6,3});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of ReflectorB
|
||||
* Used in Enigma I, M3
|
||||
* AY BR CU DH EQ FS GL IP JX KN MO TZ VW
|
||||
*/
|
||||
public static class Reflector_B extends Reflector
|
||||
{
|
||||
public Reflector_B()
|
||||
{
|
||||
super(1, "B", "YRUHQSLDPXNGOKMIEBFZCWVJAT",
|
||||
new int[]{24,17,20,7,16,18,11,3,15,23,13,6,14,10,12,8,4,1,5,25,2,22,21,9,0,19});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of ReflectorC
|
||||
* Used in Enigma I, M3
|
||||
* AF BV CP DJ EI GO HY KR LZ MX NW QT SU
|
||||
*/
|
||||
public static class Reflector_C extends Reflector
|
||||
{
|
||||
public Reflector_C()
|
||||
{
|
||||
super(2, "C", "FVPJIAOYEDRZXWGCTKUGSBNMHL",
|
||||
new int[]{5,21,15,9,8,0,14,24,4,3,17,25,23,22,6,2,19,10,20,16,18,1,13,12,7,11});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of thin reflector name b (not equal to normal name b!)
|
||||
* When used with Rotor Beta on rotation 0, the pair was equivalent to normal reflector B
|
||||
* S->Beta->ThinB->Beta'->X == X->UKWB->S
|
||||
* Used in Enigma M4
|
||||
* E N K Q A U Y W J I C O P B L M D X Z V F T H R G S
|
||||
*/
|
||||
public static class Reflector_Thin_B extends Reflector
|
||||
{
|
||||
public Reflector_Thin_B()
|
||||
{
|
||||
super(10, "Thin-B", "ENKQAUYWJICOPBLMDXZVFTHRGS",
|
||||
new int[]{4,13,10,16,0,20,24,22,9,8,2,14,15,1,11,12,3,23,25,21,5,19,7,17,6,18});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of thin reflector name c (not equal to normal name c!)
|
||||
* When used with Rotor Gamma on rotation 0, the pair was equivalent to normal reflector C
|
||||
* S->Gamma->ThinC->Gamma'->X == X->UKWC->S
|
||||
* Used in Enigma M4
|
||||
* R D O B J N T K V E H M L F C W Z A X G Y I P S U Q
|
||||
*/
|
||||
public static class ReflectorThinC extends Reflector
|
||||
{
|
||||
public ReflectorThinC()
|
||||
{
|
||||
super(11, "ThinC", "RDOBJNTKVEHMLFCWZAXGYIPSUQ",
|
||||
new int[]{17,3,14,1,9,13,19,10,21,4,7,12,11,5,2,22,25,0,23,6,24,8,15,18,20,16});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pluggable Reflector of the Enigma machine of name D and G31
|
||||
* Standard wiring: AI,BM,CE,DT,FG,HR,JY,KS,LQ,NZ,OX,PW,UV
|
||||
* Has additional ringSetting and can rotate
|
||||
*/
|
||||
public static class ReflectorEnigma_D_G31 extends Reflector
|
||||
{
|
||||
public static final int[] defaultWiring_D_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 ReflectorEnigma_D_G31()
|
||||
{
|
||||
super(20, "Ref-D", "Default: IMETCGFRAYSQBZXWLHKDVUPOJN", Arrays.copyOf(defaultWiring_D_G31,defaultWiring_D_G31.length));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pluggable Reflector as used in the Enigma of Type KD
|
||||
* Standard wiring: KOTVPNLMJIAGHFBEWYXCZDQSRU
|
||||
* Has additional ringSetting and can rotate
|
||||
*/
|
||||
public static class ReflectorEnigma_KD extends Reflector
|
||||
{
|
||||
public static final int[] defaultWiring_KD = {10,14,19,21,15,13,11,12,9,8,0,6,7,5,1,4,22,24,23,2,25,3,16,18,17,20};
|
||||
public ReflectorEnigma_KD()
|
||||
{
|
||||
super(21, "Ref-KD", "Default: KOTVPNLMJIAGHFBEWYXCZDQSRU", Arrays.copyOf(defaultWiring_KD, defaultWiring_KD.length));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reflector as used in the Enigma name G-312 Abwehr
|
||||
* R U L Q M Z J S Y G O C E T K W D A H N B X P V I F
|
||||
*/
|
||||
public static class Reflector_G312 extends Reflector
|
||||
{
|
||||
public Reflector_G312()
|
||||
{
|
||||
super(30, "Ref-G312", "RULQMZJSYGOCETKWDAHNBXPVIF",
|
||||
new int[]{17,20,11,16,12,25,9,18,24,6,14,2,4,19,10,22,3,0,7,13,1,23,15,21,8,5});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reflector as used in the Enigma name G-260 Abwehr
|
||||
* I M E T C G F R A Y S Q B Z X W L H K D V U P O J N
|
||||
*/
|
||||
public static class Reflector_K_G260 extends Reflector
|
||||
{
|
||||
public Reflector_K_G260()
|
||||
{
|
||||
super(40,"Ref-K/G260", "IMETCGFRAYSQBZXWLHKDVUPOJN",
|
||||
new int[]{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});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reflector as used in the Enigma Type R "Rocket" (Reichsbahn)
|
||||
* Q Y H O G N E C V P U Z T F D J A X W M K J S R B L
|
||||
*/
|
||||
public static class Reflector_R extends Reflector
|
||||
{
|
||||
public Reflector_R()
|
||||
{
|
||||
super(50, "Ref-R", "QYHOGNECVPUZTFDJAXWMKJSRBL",
|
||||
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});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reflector as used in the Enigma name T (Tirpitz)
|
||||
* G E K P B T A U M O C N I L J D X Z Y F H W V Q S R
|
||||
*/
|
||||
public static class ReflectorEnigma_T extends Reflector
|
||||
{
|
||||
public ReflectorEnigma_T()
|
||||
{
|
||||
super(60, "Ref-T", "GEKPBTAUMOCNILJDXZYFHWVQSR",
|
||||
new int[]{6,4,10,15,1,19,0,20,12,14,2,13,8,11,9,3,23,25,24,5,7,22,21,16,18,17});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,186 +0,0 @@
|
|||
package de.vanitasvitae.enigmandroid.enigma.rotors;
|
||||
|
||||
/**
|
||||
* Reflector of the enigma machine.
|
||||
* The reflector was used to reflect the scrambled signal at the end of the wiring back to
|
||||
* go through another (reversed but not inverting) process of scrambling.
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* @author vanitasvitae
|
||||
*/
|
||||
public class Reflector
|
||||
{
|
||||
protected String name;
|
||||
protected int type;
|
||||
protected Integer[] connections;
|
||||
|
||||
/**
|
||||
* This constructor is not accessible from outside this class file.
|
||||
* Use the one of the createReflector* methods instead to create concrete Reflectors from
|
||||
* outside this class file
|
||||
* @param name phonetic name of the reflector (usually A,B,C)
|
||||
* @param type type indicator of the reflector (A->1,...,C->3)
|
||||
* @param connections wiring of the reflector as Integer array
|
||||
*/
|
||||
protected Reflector(String name, int type, Integer[] connections)
|
||||
{
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.connections = connections;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to create reflectors.
|
||||
* @param type type of the created reflector
|
||||
* 1 -> ReflectorA
|
||||
* 2 -> ReflectorB
|
||||
* anything else -> ReflectorC
|
||||
* @return ReflectorA | ReflectorB | ReflectorC
|
||||
*/
|
||||
public static Reflector createReflector(int type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case 1: return new ReflectorA();
|
||||
case 2: return new ReflectorB();
|
||||
case 3: return new ReflectorC();
|
||||
case 4: return new ReflectorThinB();
|
||||
default: return new ReflectorThinC();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Substitute an input signal via the wiring of the reflector with a different (!) output.
|
||||
* The output MUST not be equal to the input for any input, since this was not possible
|
||||
* due to the electronic implementation of the historical enigma machine.
|
||||
* @param input input signal
|
||||
* @return encrypted (substituted) output
|
||||
*/
|
||||
public int encrypt(int input)
|
||||
{
|
||||
return this.connections[normalize(input)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type indicator of the reflector
|
||||
* @return type
|
||||
*/
|
||||
public int getType()
|
||||
{
|
||||
return this.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return phonetic name of the reflector
|
||||
* @return name
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the size (ie the number of wires/length of the connections array) of the reflector
|
||||
* @return size
|
||||
*/
|
||||
private int getRotorSize()
|
||||
{
|
||||
return this.connections.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize the input.
|
||||
* Normalizing means keeping the input via modulo in the range from 0 to n-1, where n is equal
|
||||
* to the size of the reflector. This is necessary since java allows negative modulo values,
|
||||
* which can break this implementation
|
||||
* @param input input signal
|
||||
* @return "normalized" input signal
|
||||
*/
|
||||
private int normalize(int input)
|
||||
{
|
||||
return (input + this.getRotorSize()) % this.getRotorSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of ReflectorA
|
||||
* Used in Enigma I
|
||||
* AE BJ CM DZ FL GY HX IV KW NR OQ PU ST
|
||||
*/
|
||||
private static class ReflectorA extends Reflector
|
||||
{
|
||||
public ReflectorA()
|
||||
{
|
||||
super("A", 1, new Integer[]{4,9,12,25,0,11,24,23,21,1,22,5,2,17,16,20,14,13,19,18,15,8,10,7,6,3});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of ReflectorB
|
||||
* Used in Enigma I, M3
|
||||
* AY BR CU DH EQ FS GL IP JX KN MO TZ VW
|
||||
*/
|
||||
private static class ReflectorB extends Reflector
|
||||
{
|
||||
public ReflectorB()
|
||||
{
|
||||
super("B", 2, new Integer[]{24,17,20,7,16,18,11,3,15,23,13,6,14,10,12,8,4,1,5,25,2,22,21,9,0,19});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of ReflectorC
|
||||
* Used in Enigma I, M3
|
||||
* AF BV CP DJ EI GO HY KR LZ MX NW QT SU
|
||||
*/
|
||||
private static class ReflectorC extends Reflector
|
||||
{
|
||||
public ReflectorC()
|
||||
{
|
||||
super("C", 3, new Integer[]{5,21,15,9,8,0,14,24,4,3,17,25,23,22,6,2,19,10,20,16,18,1,13,12,7,11});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of thin reflector type b (not equal to normal type b!)
|
||||
* When used with Rotor Beta on rotation 0, the pair was equivalent to normal reflector B
|
||||
* S->Beta->ThinB->Beta'->X == X->UKWB->S
|
||||
* Used in Enigma M4
|
||||
* E N K Q A U Y W J I C O P B L M D X Z V F T H R G S
|
||||
*/
|
||||
private static class ReflectorThinB extends Reflector
|
||||
{
|
||||
public ReflectorThinB()
|
||||
{
|
||||
super("B", 4, new Integer[]{4,13,10,16,0,20,24,22,9,8,2,14,15,1,11,12,3,23,25,21,5,19,7,17,6,18});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of thin reflector type c (not equal to normal type c!)
|
||||
* When used with Rotor Gamma on rotation 0, the pair was equivalent to normal reflector C
|
||||
* S->Gamma->ThinC->Gamma'->X == X->UKWC->S
|
||||
* Used in Enigma M4
|
||||
* R D O B J N T K V E H M L F C W Z A X G Y I P S U Q
|
||||
*/
|
||||
private static class ReflectorThinC extends Reflector
|
||||
{
|
||||
public ReflectorThinC()
|
||||
{
|
||||
super("B", 5, new Integer[]{17,3,14,1,9,13,19,10,21,4,7,12,11,5,2,22,25,0,23,6,24,8,15,18,20,16});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,413 +0,0 @@
|
|||
package de.vanitasvitae.enigmandroid.enigma.rotors;
|
||||
|
||||
/**
|
||||
* Rotor super class and inner concrete implementations
|
||||
* The rotors were the key feature of the enigma used to scramble up input signals into
|
||||
* encrypted signals difficult to predict. The rotors rotated to achieve a poly-alphabetic
|
||||
* substitution which was hard to break. Each signal passes the rotor twice. Once in "forward"-
|
||||
* direction and once in "backwards"-direction. There was a set of 3 out of 5 rotors inside the
|
||||
* enigma machine M4.
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* @author vanitasvitae
|
||||
*/
|
||||
public class Rotor
|
||||
{
|
||||
protected String name;
|
||||
protected int type;
|
||||
protected Integer[] connections;
|
||||
protected Integer[] reversedConnections;
|
||||
protected Integer[] turnOverNotches;
|
||||
|
||||
protected int ringSetting;
|
||||
protected int rotation;
|
||||
|
||||
/**
|
||||
* This constructor is not accessible from outside this class file.
|
||||
* Use one of the createRotor* factory methods instead to create concrete Rotors.
|
||||
* Note that connections and reversedConnections MUST be of the same size and that
|
||||
* neither connections nor reversedConnections respectively MUST have any number between
|
||||
* 0 and connections.length-1 only once (ie they represent permutations)
|
||||
* @param name phonetic name of the rotor (usually I,II,...V)
|
||||
* @param type type indicator (I -> 1,...,V -> 5)
|
||||
* @param connections wiring of the rotor as Integer array
|
||||
* @param reversedConnections inverse wiring used to encrypt in the opposite direction
|
||||
* (connections[reversedConnections[i]] = i
|
||||
* for all i in 0..getRotorSize()-1.
|
||||
* @param turnOverNotches Position(s) of the turnover notch(es)
|
||||
* @param ringSetting setting of the ring that holds the letters
|
||||
* @param rotation rotation of the rotor
|
||||
*/
|
||||
protected Rotor(String name, int type, Integer[] connections, Integer[] reversedConnections,
|
||||
Integer[] turnOverNotches, int ringSetting, int rotation)
|
||||
{
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.connections = connections;
|
||||
this.reversedConnections = reversedConnections;
|
||||
this.turnOverNotches = turnOverNotches;
|
||||
this.ringSetting = ringSetting;
|
||||
this.rotation = rotation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method that creates a rotor accordingly to the type.
|
||||
* Also initialize the rotor with ringSetting and rotation.
|
||||
* @param type type indicator (1..10)
|
||||
* 1..8 -> I..VIII
|
||||
* 9,10 -> Beta, Gamma
|
||||
* @param ringSetting setting of the outer ring (0..25)
|
||||
* @param rotation rotation of the rotor
|
||||
* @return Concrete rotor
|
||||
*/
|
||||
public static Rotor createRotor(int type, int ringSetting, int rotation)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case 1: return new RotorI(ringSetting, rotation);
|
||||
case 2: return new RotorII(ringSetting, rotation);
|
||||
case 3: return new RotorIII(ringSetting, rotation);
|
||||
case 4: return new RotorIV(ringSetting, rotation);
|
||||
case 5: return new RotorV(ringSetting, rotation);
|
||||
case 6: return new RotorVI(ringSetting, rotation);
|
||||
case 7: return new RotorVII(ringSetting, rotation);
|
||||
case 8: return new RotorVIII(ringSetting, rotation);
|
||||
case 9: return new RotorBeta(ringSetting, rotation);
|
||||
default: return new RotorGamma(ringSetting, rotation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt an input signal via the internal wiring in "forward" direction towards the reflector
|
||||
* (using connections)
|
||||
* @param input signal
|
||||
* @return encrypted signal
|
||||
*/
|
||||
public int encryptForward(int input)
|
||||
{
|
||||
return this.connections[normalize(input)];// - this.ringSetting)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt an input signal via the internal wiring in "backwards" direction (using
|
||||
* reversedConnections)
|
||||
* @param input signal
|
||||
* @return encrypted signal
|
||||
*/
|
||||
public int encryptBackward(int input)
|
||||
{
|
||||
return this.reversedConnections[normalize(input)];// + this.ringSetting)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type indicator (usually 1..5)
|
||||
* @return type indicator
|
||||
*/
|
||||
public int getType()
|
||||
{
|
||||
return this.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current rotation of the rotor.
|
||||
* The rotation consists of the actual rotation - the ringSetting
|
||||
* @return rotation-ringSetting
|
||||
*/
|
||||
public int getRotation()
|
||||
{
|
||||
return this.rotation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment rotation of the rotor by one.
|
||||
*/
|
||||
public void rotate()
|
||||
{
|
||||
this.rotation = normalize(this.getRotation()+1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true, if the rotor is at a position, where it turns over the next rotor by one
|
||||
* @return rotation==turnOverNotch
|
||||
*/
|
||||
public boolean isAtTurnoverPosition()
|
||||
{
|
||||
for(int x : getTurnOverNotches())
|
||||
{
|
||||
//if(x == this.rotation + this.ringSetting) return true;
|
||||
if(x == this.rotation) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true, if the rotor is in a position where the double turn anomaly happens.
|
||||
* The double turn anomaly (german: Doppelsprung-Anomalie) is an anomaly in the rotor movement
|
||||
* caused by the mechanical implementation of the enigma.
|
||||
* Whenever the rightmost rotor turns the middle rotor AND the middle rotor is only one move
|
||||
* from turning the leftmost rotor, the middle rotor turns again with the next character.
|
||||
* So technically there are only 26*25*26 possible rotor settings for any but firmly 3 rotors.
|
||||
* @return rotation == turnOverNotch-1
|
||||
*/
|
||||
public boolean doubleTurnAnomaly()
|
||||
{
|
||||
for(int x : getTurnOverNotches())
|
||||
{
|
||||
if(this.rotation == x-1) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the positions of the turnover notches in a array
|
||||
* @return turnOverNotches
|
||||
*/
|
||||
public Integer[] getTurnOverNotches()
|
||||
{
|
||||
return this.turnOverNotches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return ringSettings of the rotor
|
||||
* @return ringSetting
|
||||
*/
|
||||
public int getRingSetting()
|
||||
{
|
||||
return this.ringSetting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the phonetic name of the rotor
|
||||
* @return name
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size (ie the number of wires/size of the connections array)
|
||||
* of the rotor
|
||||
* @return size
|
||||
*/
|
||||
public int getRotorSize()
|
||||
{
|
||||
return this.connections.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize the input.
|
||||
* Normalizing means keeping the input via modulo in the range from 0 to n-1, where n is equal
|
||||
* to the size of the rotor. This is necessary since java allows negative modulo values,
|
||||
* which can break this implementation
|
||||
* @param input input signal
|
||||
* @return "normalized" input signal
|
||||
*/
|
||||
public int normalize(int input)
|
||||
{
|
||||
return (input + this.getRotorSize()) % this.getRotorSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of Rotor of type 1 (I)
|
||||
* Used in Enigma I, M3, M4
|
||||
* E K M F L G D Q V Z N T O W Y H X U S P A I B R C J
|
||||
*/
|
||||
private static class RotorI extends Rotor
|
||||
{
|
||||
public RotorI(int ringSetting, int rotation)
|
||||
{
|
||||
super("I", 1,
|
||||
new Integer[]{4, 10, 12, 5, 11, 6, 3, 16, 21, 25, 13, 19, 14, 22, 24, 7, 23, 20, 18, 15, 0, 8, 1, 17, 2, 9},
|
||||
new Integer[]{20, 22, 24, 6, 0, 3, 5, 15, 21, 25, 1, 4, 2, 10, 12, 19, 7, 23, 18, 11, 17, 8, 13, 16, 14, 9},
|
||||
new Integer[]{17}, ringSetting, rotation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of Rotor of type 2 (II)
|
||||
* Used in Enigma I, M3, M4
|
||||
* A J D K S I R U X B L H W T M C Q G Z N P Y F V O E
|
||||
*/
|
||||
private static class RotorII extends Rotor
|
||||
{
|
||||
public RotorII(int ringSetting, int rotation)
|
||||
{
|
||||
super("II", 2,
|
||||
new Integer[]{0, 9, 3, 10, 18, 8, 17, 20, 23, 1, 11, 7, 22, 19, 12, 2, 16, 6, 25, 13, 15, 24, 5, 21, 14, 4},
|
||||
new Integer[]{0, 9, 15, 2, 25, 22, 17, 11, 5, 1, 3, 10, 14, 19, 24, 20, 16, 6, 4, 13, 7, 23, 12, 8, 21, 18},
|
||||
new Integer[]{5}, ringSetting, rotation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of Rotor of type 3 (III)
|
||||
* Used in Enigma I, M3, M4
|
||||
* B D F H J L C P R T X V Z N Y E I W G A K M U S Q O
|
||||
*/
|
||||
private static class RotorIII extends Rotor
|
||||
{
|
||||
public RotorIII(int ringSetting, int rotation)
|
||||
{
|
||||
super("III", 3,
|
||||
new Integer[]{1, 3, 5, 7, 9, 11, 2, 15, 17, 19, 23, 21, 25, 13, 24, 4, 8, 22, 6, 0, 10, 12, 20, 18, 16, 14},
|
||||
new Integer[]{19, 0, 6, 1, 15, 2, 18, 3, 16, 4, 20, 5, 21, 13, 25, 7, 24, 8, 23, 9, 22, 11, 17, 10, 14, 12},
|
||||
new Integer[]{22}, ringSetting, rotation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of Rotor of type 4 (IV)
|
||||
* Used in Enigma M3, M4
|
||||
* E S O V P Z J A Y Q U I R H X L N F T G K D C M W B
|
||||
*/
|
||||
private static class RotorIV extends Rotor
|
||||
{
|
||||
public RotorIV(int ringSetting, int rotation)
|
||||
{
|
||||
super("IV", 4,
|
||||
new Integer[]{4, 18, 14, 21, 15, 25, 9, 0, 24, 16, 20, 8, 17, 7, 23, 11, 13, 5, 19, 6, 10, 3, 2, 12, 22, 1},
|
||||
new Integer[]{7, 25, 22, 21, 0, 17, 19, 13, 11, 6, 20, 15, 23, 16, 2, 4, 9, 12, 1, 18, 10, 3, 24, 14, 8, 5},
|
||||
new Integer[]{10}, ringSetting, rotation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of Rotor of type 5 (V)
|
||||
* Used in Enigma M3, M4
|
||||
* V Z B R G I T Y U P S D N H L X A W M J Q O F E C K
|
||||
*/
|
||||
private static class RotorV extends Rotor
|
||||
{
|
||||
public RotorV(int ringSetting, int rotation)
|
||||
{
|
||||
super("V", 5,
|
||||
new Integer[]{21, 25, 1, 17, 6, 8, 19, 24, 20, 15, 18, 3, 13, 7, 11, 23, 0, 22, 12, 9, 16, 14, 5, 4, 2, 10},
|
||||
new Integer[]{16, 2, 24, 11, 23, 22, 4, 13, 5, 19, 25, 14, 18, 12, 21, 9, 20, 3, 10, 6, 8, 0, 17, 15, 7, 1},
|
||||
new Integer[]{0}, ringSetting, rotation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of Rotor of type 6 (VI)
|
||||
* Used in Enigma M3, M4
|
||||
* J P G V O U M F Y Q B E N H Z R D K A S X L I C T W
|
||||
*/
|
||||
private static class RotorVI extends Rotor
|
||||
{
|
||||
public RotorVI(int ringSetting, int rotation)
|
||||
{
|
||||
super("VI", 6,
|
||||
new Integer[]{9,15,6,21,14,20,12,5,24,16,1,4,13,7,25,17,3,10,0,18,23,11,8,2,19,22},
|
||||
new Integer[]{18,10,23,16,11,7,2,13,22,0,17,21,6,12,4,1,9,15,19,24,5,3,25,20,8,14},
|
||||
new Integer[]{0,13}, ringSetting, rotation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of Rotor of type 7 (VII)
|
||||
* Used in Enigma M3, M4
|
||||
* N Z J H G R C X M Y S W B O U F A I V L P E K Q D T
|
||||
*/
|
||||
private static class RotorVII extends Rotor
|
||||
{
|
||||
public RotorVII(int ringSetting, int rotation)
|
||||
{
|
||||
super("VII", 7,
|
||||
new Integer[]{13,25,9,7,6,17,2,23,12,24,18,22,1,14,20,5,0,8,21,11,15,4,10,16,3,19},
|
||||
new Integer[]{16,12,6,24,21,15,4,3,17,2,22,19,8,0,13,20,23,5,10,25,14,18,11,7,9,1},
|
||||
new Integer[]{0,13}, ringSetting, rotation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of Rotor of type 8 (VIII)
|
||||
* Used in Enigma M3, M4
|
||||
* F K Q H T L X O C B J S P D Z R A M E W N I U Y G V
|
||||
*/
|
||||
private static class RotorVIII extends Rotor
|
||||
{
|
||||
public RotorVIII(int ringSetting, int rotation)
|
||||
{
|
||||
super("VIII", 8,
|
||||
new Integer[]{5,10,16,7,19,11,23,14,2,1,9,18,15,3,25,17,0,12,4,22,13,8,20,24,6,21},
|
||||
new Integer[]{16,9,8,13,18,0,24,3,21,10,1,5,17,20,7,12,2,15,11,4,22,25,19,6,23,14},
|
||||
new Integer[]{0,13}, ringSetting, rotation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of Rotor of type beta (Griechenwalze Beta)
|
||||
* Beta was used as a "thin" rotor in the M4. It was thinner than a "normal" rotor, so it
|
||||
* could be used together with one of the two thin reflectors as one rotor.
|
||||
* When used together with ReflectorThinB, Beta was equivalent to Reflector B (if rotation == 0)
|
||||
* That way the M4 was backwards compatible to the M3
|
||||
* Used in M4
|
||||
*/
|
||||
private static class RotorBeta extends Rotor
|
||||
{
|
||||
public RotorBeta(int ringSetting, int rotation)
|
||||
{
|
||||
super("Beta",9,
|
||||
new Integer[]{11,4,24,9,21,2,13,8,23,22,15,1,16,12,3,17,19,0,10,25,6,5,20,7,14,18},
|
||||
new Integer[]{17,11,5,14,1,21,20,23,7,3,18,0,13,6,24,10,12,15,25,16,22,4,9,8,2,19},
|
||||
new Integer[]{}, ringSetting, rotation);
|
||||
}
|
||||
@Override
|
||||
public void rotate()
|
||||
{
|
||||
//Thin rotors are fixed in position, so they dont rotate
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doubleTurnAnomaly()
|
||||
{
|
||||
//Nope, no anomaly
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete implementation of Rotor of type gamma (Griechenwalze Gamma)
|
||||
* Gamma was used as a "thin" rotor in the M4. It was thinner than a "normal" rotor, so it
|
||||
* could be used together with one of the two thin reflectors as one rotor.
|
||||
* When used together with ReflectorThinC, Gamma is equivalent to Reflector C
|
||||
* (if rotation == 0). That way the M4 was backwards compatible to the M3
|
||||
* Used in M4
|
||||
*/
|
||||
private static class RotorGamma extends Rotor
|
||||
{
|
||||
public RotorGamma(int ringSetting, int rotation)
|
||||
{
|
||||
super("Gamma",10,
|
||||
new Integer[]{5,18,14,10,0,13,20,4,17,7,12,1,19,8,24,2,22,11,16,15,25,23,21,6,9,3},
|
||||
new Integer[]{4,11,15,25,7,0,23,9,13,24,3,17,10,5,2,19,18,8,1,12,6,22,16,21,14,20},
|
||||
new Integer[]{}, ringSetting, rotation);
|
||||
}
|
||||
@Override
|
||||
public void rotate()
|
||||
{
|
||||
//Thin rotors are fixed in position, so they don't rotate
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doubleTurnAnomaly()
|
||||
{
|
||||
//Thin rotors don't do such weird stuff, they're normal just like you and me.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
package de.vanitasvitae.enigmandroid.enigma.util;
|
||||
|
||||
/**
|
||||
* Used to create wiring arrays from strings
|
||||
* Use strings like "E K M F L G D Q V Z N T O W Y H X U S P A I B R C J" as input
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* @author vanitasvitae
|
||||
*/
|
||||
public class RotorMaker
|
||||
{
|
||||
public static final int l = 26;
|
||||
public static void main(String[] args)
|
||||
{
|
||||
if(args.length == l) makeRotor(args);
|
||||
else if(args.length == 1) makeRotor(prepare(args[0]));
|
||||
else System.out.println("wrong input format!");
|
||||
}
|
||||
|
||||
public static void makeRotor(String input)
|
||||
{
|
||||
makeRotor(prepare(input));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the string (add spaces)
|
||||
* @param in input string
|
||||
* @return prepared string
|
||||
*/
|
||||
public static String[] prepare(String in)
|
||||
{
|
||||
String[] out = new String[l];
|
||||
int pos = 0;
|
||||
for(char x : in.toCharArray())
|
||||
{
|
||||
if(x != ' ')
|
||||
{
|
||||
try
|
||||
{
|
||||
out[pos] = ""+x;
|
||||
}
|
||||
catch (ArrayIndexOutOfBoundsException e)
|
||||
{
|
||||
System.out.println("String too long!");
|
||||
return null;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
if(pos!=l)
|
||||
{
|
||||
System.out.println("String too short!");
|
||||
return null;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate Array initializer for the given rotor configuration
|
||||
* @param input String describing the rotor
|
||||
*/
|
||||
public static void makeRotor(String[] input)
|
||||
{
|
||||
if(input.length != l) System.out.println("Wrong length! Input must have length "+l+"!");
|
||||
else
|
||||
{
|
||||
Integer[] out1 = new Integer[l];
|
||||
for(int i=0; i<l; i++)
|
||||
{
|
||||
String x = input[i].toUpperCase();
|
||||
char xc = x.charAt(0);
|
||||
int xint = (int) xc;
|
||||
xint = xint - 65;
|
||||
out1[i] = xint;
|
||||
}
|
||||
Integer[] out2 = new Integer[l];
|
||||
for(int i=0; i<l; i++)
|
||||
{
|
||||
out2[out1[i]] = i;
|
||||
}
|
||||
String output1 = "{";
|
||||
String output2 = "{";
|
||||
for(int i=0; i<l; i++)
|
||||
{
|
||||
output1 = output1 + out1[i]+",";
|
||||
output2 = output2 + out2[i]+",";
|
||||
}
|
||||
output1 = output1.substring(0,output1.length()-1) + "}";
|
||||
output2 = output2.substring(0,output2.length()-1) + "}";
|
||||
System.out.println("connections :" + output1);
|
||||
System.out.println("revConnects :" + output2);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,78 +1,192 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.layout;
|
||||
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Spinner;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.R;
|
||||
import de.vanitasvitae.enigmandroid.SettingsActivity;
|
||||
import de.vanitasvitae.enigmandroid.enigma.Enigma;
|
||||
import de.vanitasvitae.enigmandroid.enigma.EnigmaStateBundle;
|
||||
import de.vanitasvitae.enigmandroid.enigma.inputPreparer.EditTextAdapter;
|
||||
import de.vanitasvitae.enigmandroid.enigma.inputPreparer.InputPreparer;
|
||||
|
||||
/**
|
||||
* Abstract LayoutContainer for Enigma machines
|
||||
* This class contains the layout and controls the layout elements such as spinners and stuff
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* @author vanitasvitae
|
||||
*/
|
||||
public abstract class LayoutContainer
|
||||
{
|
||||
protected MainActivity main;
|
||||
protected Enigma enigma;
|
||||
final EditText inputView;
|
||||
private final EditText outputView;
|
||||
|
||||
protected EditText inputView;
|
||||
protected EditText outputView;
|
||||
EditTextAdapter input;
|
||||
EditTextAdapter output;
|
||||
|
||||
protected int[] ringSettings;
|
||||
InputPreparer inputPreparer;
|
||||
final MainActivity main;
|
||||
|
||||
public LayoutContainer()
|
||||
{
|
||||
this.main = (MainActivity) MainActivity.ActivitySingleton.getInstance().getActivity();
|
||||
}
|
||||
public abstract Enigma getEnigma();
|
||||
protected abstract void assembleLayout();
|
||||
public abstract void resetLayout();
|
||||
protected abstract void setLayoutState(EnigmaStateBundle state);
|
||||
public abstract void syncStateFromLayoutToEnigma();
|
||||
public void syncStateFromEnigmaToLayout()
|
||||
{
|
||||
this.setLayoutState(getEnigma().getState());
|
||||
}
|
||||
public abstract void showRingSettingsDialog();
|
||||
|
||||
abstract void initialize();
|
||||
public abstract void reset();
|
||||
public abstract void updateLayout();
|
||||
public abstract int[] createConfiguration();
|
||||
public abstract int[][] createPlugboardConfiguration();
|
||||
public abstract void showRingSettingsDialog();
|
||||
LayoutContainer()
|
||||
{
|
||||
main = (MainActivity) MainActivity.ActivitySingleton.getInstance().getActivity();
|
||||
setEnigmaLayout();
|
||||
this.inputView = (EditText) main.findViewById(R.id.input);
|
||||
this.outputView = (EditText) main.findViewById(R.id.output);
|
||||
input = EditTextAdapter.createEditTextAdapter(inputView,
|
||||
SettingsActivity.SettingsSingleton.getInstance().getPrefMessageFormatting());
|
||||
output = EditTextAdapter.createEditTextAdapter(outputView,
|
||||
SettingsActivity.SettingsSingleton.getInstance().getPrefMessageFormatting());
|
||||
inputPreparer = InputPreparer.createInputPreparer();
|
||||
assembleLayout();
|
||||
finishLayout();
|
||||
}
|
||||
|
||||
public Enigma getEnigma()
|
||||
{
|
||||
return enigma;
|
||||
}
|
||||
public void doCrypto()
|
||||
{
|
||||
if(inputView.getText().length()!=0)
|
||||
{
|
||||
syncStateFromLayoutToEnigma();
|
||||
String message = inputView.getText().toString();
|
||||
message = inputPreparer.prepareString(message);
|
||||
input.setText(message);
|
||||
output.setText(getEnigma().encryptString(message));
|
||||
setLayoutState(getEnigma().getState());
|
||||
}
|
||||
}
|
||||
|
||||
public EditText getInputView()
|
||||
{
|
||||
return this.inputView;
|
||||
}
|
||||
public EditTextAdapter getInput()
|
||||
{
|
||||
return this.input;
|
||||
}
|
||||
|
||||
public EditText getOutputView()
|
||||
{
|
||||
return this.outputView;
|
||||
}
|
||||
public EditTextAdapter getOutput()
|
||||
{
|
||||
return this.output;
|
||||
}
|
||||
|
||||
public static LayoutContainer createLayoutContainer(String type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case "M4":
|
||||
return new LayoutContainer_M4();
|
||||
case "M3":
|
||||
return new LayoutContainer_M3();
|
||||
default:
|
||||
return new LayoutContainer_I();
|
||||
}
|
||||
}
|
||||
}
|
||||
public static LayoutContainer createLayoutContainer()
|
||||
{
|
||||
return createLayoutContainer(SettingsActivity.SettingsSingleton.getInstance().getPrefMachineType());
|
||||
}
|
||||
|
||||
private static LayoutContainer createLayoutContainer(String enigmaType)
|
||||
{
|
||||
switch (enigmaType) {
|
||||
case "I":
|
||||
return new LayoutContainer_I();
|
||||
case "M3":
|
||||
return new LayoutContainer_M3();
|
||||
case "M4":
|
||||
return new LayoutContainer_M4();
|
||||
case "D":
|
||||
return new LayoutContainer_D();
|
||||
case "K":
|
||||
return new LayoutContainer_K();
|
||||
case "KS":
|
||||
return new LayoutContainer_K_Swiss();
|
||||
case "KSA":
|
||||
return new LayoutContainer_K_Swiss_Airforce();
|
||||
case "T":
|
||||
return new LayoutContainer_T();
|
||||
case "R":
|
||||
return new LayoutContainer_R();
|
||||
case "G31":
|
||||
return new LayoutContainer_G31();
|
||||
case "G312":
|
||||
return new LayoutContainer_G312();
|
||||
case "G260":
|
||||
return new LayoutContainer_G260();
|
||||
case "KD":
|
||||
return new LayoutContainer_KD();
|
||||
default:
|
||||
return new LayoutContainer_I();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add ArrayAdapter, contents and layouts to Spinner
|
||||
* @param view Spinner
|
||||
* @param resourceID ID of the referenced array (eg. R.array.rotor_1_8)
|
||||
*/
|
||||
void prepareSpinnerAdapter(Spinner view, int resourceID) {
|
||||
MainActivity main = (MainActivity) MainActivity.ActivitySingleton.getInstance().getActivity();
|
||||
|
||||
ArrayAdapter<CharSequence> ad = new ArrayAdapter<CharSequence>(main,
|
||||
android.R.layout.simple_spinner_item,
|
||||
main.getResources().getTextArray(resourceID));
|
||||
|
||||
ad.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
ad.setDropDownViewTheme(main.getTheme());
|
||||
view.setAdapter(ad);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add ArrayAdapter, contents and layouts to Spinner
|
||||
* @param view Spinner
|
||||
* @param array Character array
|
||||
*/
|
||||
void prepareSpinnerAdapter(Spinner view, Character[] array)
|
||||
{
|
||||
MainActivity main = (MainActivity) MainActivity.ActivitySingleton.getInstance().getActivity();
|
||||
ArrayAdapter<Character> adapter = new ArrayAdapter<>(main,
|
||||
android.R.layout.simple_spinner_item, array);
|
||||
adapter.setDropDownViewResource(
|
||||
android.R.layout.simple_spinner_dropdown_item);
|
||||
adapter.setDropDownViewTheme(main.getTheme());
|
||||
view.setAdapter(adapter);
|
||||
}
|
||||
|
||||
public void setInputPreparer(InputPreparer inputPreparer)
|
||||
{
|
||||
this.inputPreparer = inputPreparer;
|
||||
}
|
||||
|
||||
public void setEditTextAdapter(String type)
|
||||
{
|
||||
String in = input.getText();
|
||||
String out = output.getText();
|
||||
input = EditTextAdapter.createEditTextAdapter(inputView, type);
|
||||
input.setText(in);
|
||||
output = EditTextAdapter.createEditTextAdapter(outputView, type);
|
||||
output.setText(out);
|
||||
}
|
||||
|
||||
protected void setMainActivityLayout()
|
||||
{
|
||||
setEnigmaLayout();
|
||||
}
|
||||
|
||||
abstract protected void setEnigmaLayout();
|
||||
|
||||
private void finishLayout()
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.layout;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.Spinner;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.R;
|
||||
import de.vanitasvitae.enigmandroid.enigma.EnigmaStateBundle;
|
||||
import de.vanitasvitae.enigmandroid.enigma.Enigma_D;
|
||||
|
||||
/**
|
||||
* Concrete LayoutContainer for the D layout.
|
||||
* This class contains the layout and controls the layout elements such as spinners and stuff
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
*/
|
||||
public class LayoutContainer_D extends LayoutContainer
|
||||
{
|
||||
private Enigma_D enigma;
|
||||
|
||||
private Spinner rotor1PositionView;
|
||||
private Spinner rotor2PositionView;
|
||||
private Spinner rotor3PositionView;
|
||||
private Spinner reflectorPositionView;
|
||||
|
||||
public LayoutContainer_D()
|
||||
{
|
||||
super();
|
||||
main.setTitle("D - EnigmAndroid");
|
||||
this.resetLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setEnigmaLayout()
|
||||
{
|
||||
MainActivity.ActivitySingleton.getInstance().getActivity().setContentView(R.layout.activity_main_d);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assembleLayout()
|
||||
{
|
||||
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);
|
||||
Button reflectorWiring = (Button) main.findViewById(R.id.button_reflector);
|
||||
reflectorWiring.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
new PluggableDialogBuilder(getEnigma().getState()).showDialogReflector();
|
||||
}
|
||||
});
|
||||
|
||||
Character[] rotorPositionArray = new Character[26];
|
||||
for(int i=0; i<26; i++) {rotorPositionArray[i] = (char) (65+i); /*Fill with A..Z*/}
|
||||
|
||||
prepareSpinnerAdapter(rotor1PositionView, rotorPositionArray);
|
||||
prepareSpinnerAdapter(rotor2PositionView, rotorPositionArray);
|
||||
prepareSpinnerAdapter(rotor3PositionView, rotorPositionArray);
|
||||
prepareSpinnerAdapter(reflectorPositionView, rotorPositionArray);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetLayout()
|
||||
{
|
||||
enigma = new Enigma_D();
|
||||
setLayoutState(enigma.getState());
|
||||
output.setText("");
|
||||
input.setText("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLayoutState(EnigmaStateBundle state)
|
||||
{
|
||||
this.rotor1PositionView.setSelection(state.getRotationRotor1());
|
||||
this.rotor2PositionView.setSelection(state.getRotationRotor2());
|
||||
this.rotor3PositionView.setSelection(state.getRotationRotor3());
|
||||
this.reflectorPositionView.setSelection(state.getRotationReflector());
|
||||
}
|
||||
|
||||
@Override
|
||||
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()
|
||||
{
|
||||
return this.enigma;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showRingSettingsDialog()
|
||||
{
|
||||
new RingSettingsDialogBuilder.RingSettingsDialogBuilderRotRotRotRef().
|
||||
createRingSettingsDialog(getEnigma().getState());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.layout;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.enigma.Enigma_G260;
|
||||
|
||||
/**
|
||||
* LayoutContainer for the Enigma Model G260
|
||||
* This class contains the layout and controls the layout elements such as spinners and stuff
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
*/
|
||||
public class LayoutContainer_G260 extends LayoutContainer_G31
|
||||
{
|
||||
public LayoutContainer_G260()
|
||||
{
|
||||
super();
|
||||
main.setTitle("G260 - EnigmAndroid");
|
||||
this.resetLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetLayout() {
|
||||
enigma = new Enigma_G260();
|
||||
setLayoutState(enigma.getState());
|
||||
output.setText("");
|
||||
input.setText("");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.layout;
|
||||
|
||||
import android.widget.Spinner;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.R;
|
||||
import de.vanitasvitae.enigmandroid.enigma.Enigma;
|
||||
import de.vanitasvitae.enigmandroid.enigma.EnigmaStateBundle;
|
||||
import de.vanitasvitae.enigmandroid.enigma.Enigma_G31;
|
||||
|
||||
/**
|
||||
* LayoutContainer for the Enigma Model G31
|
||||
* This class contains the layout and controls the layout elements such as spinners and stuff
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
*/
|
||||
public class LayoutContainer_G31 extends LayoutContainer
|
||||
{
|
||||
Enigma enigma;
|
||||
|
||||
private Spinner rotor1View;
|
||||
private Spinner rotor2View;
|
||||
private Spinner rotor3View;
|
||||
|
||||
private Spinner rotor1PositionView;
|
||||
private Spinner rotor2PositionView;
|
||||
private Spinner rotor3PositionView;
|
||||
private Spinner reflectorPositionView;
|
||||
|
||||
public LayoutContainer_G31()
|
||||
{
|
||||
super();
|
||||
main.setTitle("G31 - EnigmAndroid");
|
||||
this.resetLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setEnigmaLayout()
|
||||
{
|
||||
MainActivity.ActivitySingleton.getInstance().getActivity().setContentView(R.layout.activity_main_g_k_r_t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enigma getEnigma() {
|
||||
return this.enigma;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assembleLayout() {
|
||||
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_G31();
|
||||
setLayoutState(enigma.getState());
|
||||
output.setText("");
|
||||
input.setText("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLayoutState(EnigmaStateBundle state)
|
||||
{
|
||||
this.rotor1View.setSelection(state.getTypeRotor1());
|
||||
this.rotor2View.setSelection(state.getTypeRotor2());
|
||||
this.rotor3View.setSelection(state.getTypeRotor3());
|
||||
this.rotor1PositionView.setSelection(state.getRotationRotor1());
|
||||
this.rotor2PositionView.setSelection(state.getRotationRotor2());
|
||||
this.rotor3PositionView.setSelection(state.getRotationRotor3());
|
||||
this.reflectorPositionView.setSelection(state.getRotationReflector());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syncStateFromLayoutToEnigma()
|
||||
{
|
||||
EnigmaStateBundle state = getEnigma().getState();
|
||||
state.setTypeRotor1(rotor1View.getSelectedItemPosition());
|
||||
state.setTypeRotor2(rotor2View.getSelectedItemPosition());
|
||||
state.setTypeRotor3(rotor3View.getSelectedItemPosition());
|
||||
state.setRotationRotor1(rotor1PositionView.getSelectedItemPosition());
|
||||
state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition());
|
||||
state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition());
|
||||
state.setRotationReflector(reflectorPositionView.getSelectedItemPosition());
|
||||
getEnigma().setState(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showRingSettingsDialog()
|
||||
{
|
||||
new RingSettingsDialogBuilder.RingSettingsDialogBuilderRotRotRotRef().
|
||||
createRingSettingsDialog(getEnigma().getState());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.layout;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.enigma.Enigma_G312;
|
||||
|
||||
/**
|
||||
* LayoutContainer for the Enigma Model G312
|
||||
* This class contains the layout and controls the layout elements such as spinners and stuff
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
*/
|
||||
public class LayoutContainer_G312 extends LayoutContainer_G31
|
||||
{
|
||||
public LayoutContainer_G312()
|
||||
{
|
||||
super();
|
||||
main.setTitle("G312 - EnigmAndroid");
|
||||
this.resetLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetLayout() {
|
||||
enigma = new Enigma_G312();
|
||||
setLayoutState(enigma.getState());
|
||||
output.setText("");
|
||||
input.setText("");
|
||||
}
|
||||
}
|
|
@ -1,224 +1,132 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.layout;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Button;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.Toast;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.R;
|
||||
import de.vanitasvitae.enigmandroid.enigma.EnigmaStateBundle;
|
||||
import de.vanitasvitae.enigmandroid.enigma.Enigma_I;
|
||||
import de.vanitasvitae.enigmandroid.enigma.Plugboard;
|
||||
|
||||
/**
|
||||
* Concrete LayoutContainer for the Enigma I layout.
|
||||
* This class contains the layout and controls the layout elements such as spinners and stuff
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* @author vanitasvitae
|
||||
*/
|
||||
public class LayoutContainer_I extends LayoutContainer
|
||||
{
|
||||
protected Spinner rotor1View;
|
||||
protected Spinner rotor2View;
|
||||
protected Spinner rotor3View;
|
||||
protected Spinner reflectorView;
|
||||
protected Spinner rotor1PositionView;
|
||||
protected Spinner rotor2PositionView;
|
||||
protected Spinner rotor3PositionView;
|
||||
private Enigma_I enigma;
|
||||
|
||||
protected EditText plugboardView;
|
||||
Spinner rotor1View;
|
||||
Spinner rotor2View;
|
||||
Spinner rotor3View;
|
||||
Spinner reflectorView;
|
||||
Spinner rotor1PositionView;
|
||||
Spinner rotor2PositionView;
|
||||
Spinner rotor3PositionView;
|
||||
|
||||
public LayoutContainer_I()
|
||||
{
|
||||
super();
|
||||
main.setTitle("I - EnigmAndroid");
|
||||
this.enigma = new Enigma_I();
|
||||
this.ringSettings = new int[]{0,0,0};
|
||||
this.resetLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setEnigmaLayout()
|
||||
{
|
||||
MainActivity.ActivitySingleton.getInstance().getActivity().setContentView(R.layout.activity_main_i_m3);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assembleLayout()
|
||||
{
|
||||
this.rotor1View = (Spinner) main.findViewById(R.id.rotor1);
|
||||
this.rotor2View = (Spinner) main.findViewById(R.id.rotor2);
|
||||
this.rotor3View = (Spinner) main.findViewById(R.id.rotor3);
|
||||
this.reflectorView = (Spinner) main.findViewById(R.id.reflector);
|
||||
this.rotor1PositionView = (Spinner) main.findViewById(R.id.rotor1position);
|
||||
this.rotor2PositionView = (Spinner) main.findViewById(R.id.rotor2position);
|
||||
this.rotor3PositionView = (Spinner) main.findViewById(R.id.rotor3position);
|
||||
this.plugboardView = (EditText) main.findViewById(R.id.plugboard);
|
||||
this.inputView = (EditText) main.findViewById(R.id.input);
|
||||
this.outputView = (EditText) main.findViewById(R.id.output);
|
||||
this.reflectorView = (Spinner) main.findViewById(R.id.reflector);
|
||||
Button setPlugboardButton = (Button) main.findViewById(R.id.button_plugboard);
|
||||
setPlugboardButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
new PluggableDialogBuilder(getEnigma().getState()).showDialogPlugboard();
|
||||
}
|
||||
});
|
||||
|
||||
initialize();
|
||||
reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
void initialize()
|
||||
{
|
||||
Character[] rotorPositionArray = new Character[26];
|
||||
for(int i=0; i<26; i++) {rotorPositionArray[i] = (char) (65+i); /**Fill with A..Z*/}
|
||||
for(int i=0; i<26; i++) {rotorPositionArray[i] = (char) (65+i); /*Fill with A..Z*/}
|
||||
|
||||
ArrayAdapter<CharSequence> rotor1Adapter = ArrayAdapter.createFromResource(main, R.array.rotors_1_5,
|
||||
android.R.layout.simple_spinner_item);
|
||||
rotor1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor1View.setAdapter(rotor1Adapter);
|
||||
ArrayAdapter<CharSequence> rotor2Adapter = ArrayAdapter.createFromResource(main, R.array.rotors_1_5,
|
||||
android.R.layout.simple_spinner_item);
|
||||
rotor2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor2View.setAdapter(rotor2Adapter);
|
||||
ArrayAdapter<CharSequence> rotor3Adapter = ArrayAdapter.createFromResource(main, R.array.rotors_1_5,
|
||||
android.R.layout.simple_spinner_item);
|
||||
rotor3Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor3View.setAdapter(rotor3Adapter);
|
||||
|
||||
ArrayAdapter<CharSequence> reflectorAdapter = ArrayAdapter.createFromResource(main, R.array.reflectors_a_c,
|
||||
android.R.layout.simple_spinner_item);
|
||||
reflectorAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
reflectorView.setAdapter(reflectorAdapter);
|
||||
|
||||
ArrayAdapter<Character> rotor1PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(),
|
||||
android.R.layout.simple_spinner_item,rotorPositionArray);
|
||||
rotor1PositionAdapter.setDropDownViewResource(
|
||||
android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor1PositionView.setAdapter(rotor1PositionAdapter);
|
||||
ArrayAdapter<Character> rotor2PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(),
|
||||
android.R.layout.simple_spinner_item,rotorPositionArray);
|
||||
rotor2PositionAdapter.setDropDownViewResource(
|
||||
android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor2PositionView.setAdapter(rotor2PositionAdapter);
|
||||
ArrayAdapter<Character> rotor3PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(),
|
||||
android.R.layout.simple_spinner_item,rotorPositionArray);
|
||||
rotor3PositionAdapter.setDropDownViewResource(
|
||||
android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor3PositionView.setAdapter(rotor3PositionAdapter);
|
||||
prepareSpinnerAdapter(rotor1View, R.array.rotors_1_5);
|
||||
prepareSpinnerAdapter(rotor2View, R.array.rotors_1_5);
|
||||
prepareSpinnerAdapter(rotor3View, R.array.rotors_1_5);
|
||||
prepareSpinnerAdapter(reflectorView, R.array.reflectors_a_c);
|
||||
prepareSpinnerAdapter(rotor1PositionView, rotorPositionArray);
|
||||
prepareSpinnerAdapter(rotor2PositionView, rotorPositionArray);
|
||||
prepareSpinnerAdapter(rotor3PositionView, rotorPositionArray);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset()
|
||||
public void resetLayout()
|
||||
{
|
||||
rotor1View.setSelection(0); //I
|
||||
rotor2View.setSelection(1); //II
|
||||
rotor3View.setSelection(2); //III
|
||||
reflectorView.setSelection(0); //A
|
||||
rotor1PositionView.setSelection(0); //0
|
||||
rotor2PositionView.setSelection(0); //0
|
||||
rotor3PositionView.setSelection(0); //0
|
||||
this.ringSettings = new int[]{0,0,0};
|
||||
inputView.setText("");
|
||||
outputView.setText("");
|
||||
plugboardView.setText("");
|
||||
enigma.setConfiguration(createConfiguration());
|
||||
enigma.setPlugboard(new Plugboard());
|
||||
enigma = new Enigma_I();
|
||||
setLayoutState(enigma.getState());
|
||||
output.setText("");
|
||||
input.setText("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLayout()
|
||||
public void setLayoutState(EnigmaStateBundle state)
|
||||
{
|
||||
int[] conf = enigma.getConfiguration();
|
||||
rotor1View.setSelection(conf[0]-1);
|
||||
rotor2View.setSelection(conf[1]-1);
|
||||
rotor3View.setSelection(conf[2]-1);
|
||||
reflectorView.setSelection(conf[3]-1);
|
||||
rotor1PositionView.setSelection(conf[4]);
|
||||
rotor2PositionView.setSelection(conf[5]);
|
||||
rotor3PositionView.setSelection(conf[6]);
|
||||
ringSettings[0] = conf[7];
|
||||
ringSettings[1] = conf[8];
|
||||
ringSettings[2] = conf[9];
|
||||
this.rotor1View.setSelection(state.getTypeRotor1());
|
||||
this.rotor2View.setSelection(state.getTypeRotor2());
|
||||
this.rotor3View.setSelection(state.getTypeRotor3());
|
||||
this.reflectorView.setSelection(state.getTypeReflector());
|
||||
this.rotor1PositionView.setSelection(state.getRotationRotor1());
|
||||
this.rotor2PositionView.setSelection(state.getRotationRotor2());
|
||||
this.rotor3PositionView.setSelection(state.getRotationRotor3());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] createConfiguration()
|
||||
public void syncStateFromLayoutToEnigma()
|
||||
{
|
||||
int[] conf = new int[10];
|
||||
//Rotors 1..3
|
||||
conf[0] = rotor1View.getSelectedItemPosition() + 1;
|
||||
conf[1] = rotor2View.getSelectedItemPosition() + 1;
|
||||
conf[2] = rotor3View.getSelectedItemPosition() + 1;
|
||||
//Reflector
|
||||
conf[3] = reflectorView.getSelectedItemPosition() + 1;
|
||||
|
||||
conf[4] = rotor1PositionView.getSelectedItemPosition();
|
||||
conf[5] = rotor2PositionView.getSelectedItemPosition();
|
||||
conf[6] = rotor3PositionView.getSelectedItemPosition();
|
||||
|
||||
conf[7] = ringSettings[0];
|
||||
conf[8] = ringSettings[1];
|
||||
conf[9] = ringSettings[2];
|
||||
|
||||
return conf;
|
||||
EnigmaStateBundle state = getEnigma().getState();
|
||||
state.setTypeRotor1(rotor1View.getSelectedItemPosition());
|
||||
state.setTypeRotor2(rotor2View.getSelectedItemPosition());
|
||||
state.setTypeRotor3(rotor3View.getSelectedItemPosition());
|
||||
state.setTypeReflector(reflectorView.getSelectedItemPosition());
|
||||
state.setRotationRotor1(rotor1PositionView.getSelectedItemPosition());
|
||||
state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition());
|
||||
state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition());
|
||||
getEnigma().setState(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[][] createPlugboardConfiguration() {
|
||||
return Plugboard.parseConfigurationString(plugboardView.getText().toString());
|
||||
public Enigma_I getEnigma()
|
||||
{
|
||||
return this.enigma;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showRingSettingsDialog()
|
||||
{
|
||||
Integer[] ringArray = new Integer[26];
|
||||
for(int i=1; i<=26; i++) {ringArray[i-1] = i;}
|
||||
View ringSettingsView = View.inflate(main, R.layout.dialog_ringsettings_i_m3, null);
|
||||
final Spinner ring1 = (Spinner) ringSettingsView.findViewById(R.id.rotor1ring);
|
||||
ArrayAdapter<Integer> ring1Adapter = new ArrayAdapter<>(main,
|
||||
android.R.layout.simple_spinner_item,ringArray);
|
||||
ring1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
ring1.setAdapter(ring1Adapter);
|
||||
ring1.setSelection(ringSettings[0]);
|
||||
|
||||
final Spinner ring2 = (Spinner) ringSettingsView.findViewById(R.id.rotor2ring);
|
||||
ArrayAdapter<Integer> ring2Adapter = new ArrayAdapter<>(main,
|
||||
android.R.layout.simple_spinner_item,ringArray);
|
||||
ring2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
ring2.setAdapter(ring2Adapter);
|
||||
ring2.setSelection(ringSettings[1]);
|
||||
|
||||
final Spinner ring3 = (Spinner) ringSettingsView.findViewById(R.id.rotor3ring);
|
||||
ArrayAdapter<Integer> ring3Adapter = new ArrayAdapter<>(main,
|
||||
android.R.layout.simple_spinner_item,ringArray);
|
||||
ring3Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
ring3.setAdapter(ring3Adapter);
|
||||
ring3.setSelection(ringSettings[2]);
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(main);
|
||||
builder.setTitle(R.string.title_ringsetting);
|
||||
builder.setView(ringSettingsView)
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(R.string.dialog_positiv, new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int id)
|
||||
{
|
||||
ringSettings[0] = ring1.getSelectedItemPosition();
|
||||
ringSettings[1] = ring2.getSelectedItemPosition();
|
||||
ringSettings[2] = ring3.getSelectedItemPosition();
|
||||
String message = main.getResources().getString(
|
||||
R.string.dialog_ringsettings_success) + " " +
|
||||
(ringSettings[2]+1) + ", " +
|
||||
(ringSettings[1]+1) + ", " +
|
||||
(ringSettings[0]+1) + ".";
|
||||
Toast.makeText(main, message, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.dialog_negativ, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
dialog.cancel();
|
||||
Toast.makeText(main, R.string.dialog_ringsettings_abort,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}).show();
|
||||
new RingSettingsDialogBuilder.RingSettingsDialogBuilderRotRotRot().
|
||||
createRingSettingsDialog(getEnigma().getState());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.layout;
|
||||
|
||||
import android.widget.Spinner;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.R;
|
||||
import de.vanitasvitae.enigmandroid.enigma.Enigma;
|
||||
import de.vanitasvitae.enigmandroid.enigma.EnigmaStateBundle;
|
||||
import de.vanitasvitae.enigmandroid.enigma.Enigma_K;
|
||||
|
||||
/**
|
||||
* LayoutContainer for the Enigma Model K
|
||||
* This class contains the layout and controls the layout elements such as spinners and stuff
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
*/
|
||||
public class LayoutContainer_K extends LayoutContainer
|
||||
{
|
||||
Enigma enigma;
|
||||
|
||||
private Spinner rotor1View;
|
||||
private Spinner rotor2View;
|
||||
private Spinner rotor3View;
|
||||
|
||||
private Spinner rotor1PositionView;
|
||||
private Spinner rotor2PositionView;
|
||||
private Spinner rotor3PositionView;
|
||||
private Spinner reflectorPositionView;
|
||||
|
||||
public LayoutContainer_K()
|
||||
{
|
||||
super();
|
||||
main.setTitle("K - EnigmAndroid");
|
||||
this.resetLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setEnigmaLayout()
|
||||
{
|
||||
MainActivity.ActivitySingleton.getInstance().getActivity().setContentView(R.layout.activity_main_g_k_r_t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enigma getEnigma() {
|
||||
return this.enigma;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assembleLayout() {
|
||||
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_K();
|
||||
setLayoutState(enigma.getState());
|
||||
output.setText("");
|
||||
input.setText("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLayoutState(EnigmaStateBundle state)
|
||||
{
|
||||
this.rotor1View.setSelection(state.getTypeRotor1());
|
||||
this.rotor2View.setSelection(state.getTypeRotor2());
|
||||
this.rotor3View.setSelection(state.getTypeRotor3());
|
||||
this.rotor1PositionView.setSelection(state.getRotationRotor1());
|
||||
this.rotor2PositionView.setSelection(state.getRotationRotor2());
|
||||
this.rotor3PositionView.setSelection(state.getRotationRotor3());
|
||||
this.reflectorPositionView.setSelection(state.getRotationReflector());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syncStateFromLayoutToEnigma()
|
||||
{
|
||||
EnigmaStateBundle state = getEnigma().getState();
|
||||
state.setTypeRotor1(rotor1View.getSelectedItemPosition());
|
||||
state.setTypeRotor2(rotor2View.getSelectedItemPosition());
|
||||
state.setTypeRotor3(rotor3View.getSelectedItemPosition());
|
||||
state.setRotationRotor1(rotor1PositionView.getSelectedItemPosition());
|
||||
state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition());
|
||||
state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition());
|
||||
state.setRotationReflector(reflectorPositionView.getSelectedItemPosition());
|
||||
getEnigma().setState(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showRingSettingsDialog()
|
||||
{
|
||||
new RingSettingsDialogBuilder.RingSettingsDialogBuilderRotRotRotRef().
|
||||
createRingSettingsDialog(getEnigma().getState());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.layout;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.Spinner;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.R;
|
||||
import de.vanitasvitae.enigmandroid.enigma.Enigma;
|
||||
import de.vanitasvitae.enigmandroid.enigma.EnigmaStateBundle;
|
||||
import de.vanitasvitae.enigmandroid.enigma.Enigma_KD;
|
||||
|
||||
/**
|
||||
* LayoutContainer for the Enigma Model K
|
||||
* This class contains the layout and controls the layout elements such as spinners and stuff
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
*/
|
||||
public class LayoutContainer_KD extends LayoutContainer
|
||||
{
|
||||
private Enigma enigma;
|
||||
|
||||
private Spinner rotor1View;
|
||||
private Spinner rotor2View;
|
||||
private Spinner rotor3View;
|
||||
|
||||
private Spinner rotor1PositionView;
|
||||
private Spinner rotor2PositionView;
|
||||
private Spinner rotor3PositionView;
|
||||
private Spinner reflectorPositionView;
|
||||
|
||||
public LayoutContainer_KD()
|
||||
{
|
||||
super();
|
||||
main.setTitle("KD - EnigmAndroid");
|
||||
this.resetLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setEnigmaLayout()
|
||||
{
|
||||
MainActivity.ActivitySingleton.getInstance().getActivity().setContentView(R.layout.activity_main_kd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enigma getEnigma() {
|
||||
return this.enigma;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assembleLayout() {
|
||||
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);
|
||||
Button reflectorWiring = (Button) main.findViewById(R.id.button_reflector);
|
||||
reflectorWiring.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
new PluggableDialogBuilder(getEnigma().getState()).showDialogReflector();
|
||||
}
|
||||
});
|
||||
|
||||
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_KD();
|
||||
setLayoutState(enigma.getState());
|
||||
output.setText("");
|
||||
input.setText("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLayoutState(EnigmaStateBundle state)
|
||||
{
|
||||
this.rotor1View.setSelection(state.getTypeRotor1());
|
||||
this.rotor2View.setSelection(state.getTypeRotor2());
|
||||
this.rotor3View.setSelection(state.getTypeRotor3());
|
||||
this.rotor1PositionView.setSelection(state.getRotationRotor1());
|
||||
this.rotor2PositionView.setSelection(state.getRotationRotor2());
|
||||
this.rotor3PositionView.setSelection(state.getRotationRotor3());
|
||||
this.reflectorPositionView.setSelection(state.getRotationReflector());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syncStateFromLayoutToEnigma()
|
||||
{
|
||||
EnigmaStateBundle state = getEnigma().getState();
|
||||
state.setTypeRotor1(rotor1View.getSelectedItemPosition());
|
||||
state.setTypeRotor2(rotor2View.getSelectedItemPosition());
|
||||
state.setTypeRotor3(rotor3View.getSelectedItemPosition());
|
||||
state.setRotationRotor1(rotor1PositionView.getSelectedItemPosition());
|
||||
state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition());
|
||||
state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition());
|
||||
state.setRotationReflector(reflectorPositionView.getSelectedItemPosition());
|
||||
getEnigma().setState(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showRingSettingsDialog()
|
||||
{
|
||||
new RingSettingsDialogBuilder.RingSettingsDialogBuilderRotRotRotRef().
|
||||
createRingSettingsDialog(getEnigma().getState());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.layout;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.enigma.Enigma_K_Swiss_Standard;
|
||||
|
||||
/**
|
||||
* LayoutContainer for the Enigma Model K
|
||||
* This class contains the layout and controls the layout elements such as spinners and stuff
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
*/
|
||||
public class LayoutContainer_K_Swiss extends LayoutContainer_K
|
||||
{
|
||||
public LayoutContainer_K_Swiss()
|
||||
{
|
||||
super();
|
||||
main.setTitle("KS - EnigmAndroid");
|
||||
this.resetLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetLayout() {
|
||||
enigma = new Enigma_K_Swiss_Standard();
|
||||
setLayoutState(enigma.getState());
|
||||
output.setText("");
|
||||
input.setText("");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.layout;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.enigma.Enigma_K_Swiss_Airforce;
|
||||
|
||||
/**
|
||||
* LayoutContainer for the Enigma Model K
|
||||
* This class contains the layout and controls the layout elements such as spinners and stuff
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
*/
|
||||
public class LayoutContainer_K_Swiss_Airforce extends LayoutContainer_K
|
||||
{
|
||||
public LayoutContainer_K_Swiss_Airforce()
|
||||
{
|
||||
super();
|
||||
main.setTitle("KSA - EnigmAndroid");
|
||||
this.resetLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetLayout() {
|
||||
enigma = new Enigma_K_Swiss_Airforce();
|
||||
setLayoutState(enigma.getState());
|
||||
output.setText("");
|
||||
input.setText("");
|
||||
}
|
||||
}
|
|
@ -1,115 +1,111 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.layout;
|
||||
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.Spinner;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.R;
|
||||
import de.vanitasvitae.enigmandroid.enigma.EnigmaStateBundle;
|
||||
import de.vanitasvitae.enigmandroid.enigma.Enigma_M3;
|
||||
|
||||
/**
|
||||
* Concrete LayoutContainer for the M3 layout.
|
||||
* This class contains the layout and controls the layout elements such as spinners and stuff
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* @author vanitasvitae
|
||||
*/
|
||||
public class LayoutContainer_M3 extends LayoutContainer_I
|
||||
{
|
||||
private Enigma_M3 enigma;
|
||||
|
||||
public LayoutContainer_M3()
|
||||
{
|
||||
super();
|
||||
main.setTitle("M3 - EnigmAndroid");
|
||||
this.enigma = new Enigma_M3();
|
||||
this.resetLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
void initialize()
|
||||
protected void assembleLayout()
|
||||
{
|
||||
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.reflectorView = (Spinner) main.findViewById(R.id.reflector);
|
||||
Button setPlugboardButton = (Button) main.findViewById(R.id.button_plugboard);
|
||||
setPlugboardButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
new PluggableDialogBuilder(getEnigma().getState()).showDialogPlugboard();
|
||||
}
|
||||
});
|
||||
|
||||
Character[] rotorPositionArray = new Character[26];
|
||||
for(int i=0; i<26; i++) {rotorPositionArray[i] = (char) (65+i); /**Fill with A..Z*/}
|
||||
for(int i=0; i<26; i++) {rotorPositionArray[i] = (char) (65+i); /*Fill with A..Z*/}
|
||||
|
||||
ArrayAdapter<CharSequence> rotor1Adapter = ArrayAdapter.createFromResource(main, R.array.rotors_1_8,
|
||||
android.R.layout.simple_spinner_item);
|
||||
rotor1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor1View.setAdapter(rotor1Adapter);
|
||||
ArrayAdapter<CharSequence> rotor2Adapter = ArrayAdapter.createFromResource(main, R.array.rotors_1_8,
|
||||
android.R.layout.simple_spinner_item);
|
||||
rotor2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor2View.setAdapter(rotor2Adapter);
|
||||
ArrayAdapter<CharSequence> rotor3Adapter = ArrayAdapter.createFromResource(main, R.array.rotors_1_8,
|
||||
android.R.layout.simple_spinner_item);
|
||||
rotor3Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor3View.setAdapter(rotor3Adapter);
|
||||
|
||||
ArrayAdapter<CharSequence> reflectorAdapter = ArrayAdapter.createFromResource(main, R.array.reflectors_b_c,
|
||||
android.R.layout.simple_spinner_item);
|
||||
reflectorAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
reflectorView.setAdapter(reflectorAdapter);
|
||||
|
||||
ArrayAdapter<Character> rotor1PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(),
|
||||
android.R.layout.simple_spinner_item,rotorPositionArray);
|
||||
rotor1PositionAdapter.setDropDownViewResource(
|
||||
android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor1PositionView.setAdapter(rotor1PositionAdapter);
|
||||
ArrayAdapter<Character> rotor2PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(),
|
||||
android.R.layout.simple_spinner_item,rotorPositionArray);
|
||||
rotor2PositionAdapter.setDropDownViewResource(
|
||||
android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor2PositionView.setAdapter(rotor2PositionAdapter);
|
||||
ArrayAdapter<Character> rotor3PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(),
|
||||
android.R.layout.simple_spinner_item,rotorPositionArray);
|
||||
rotor3PositionAdapter.setDropDownViewResource(
|
||||
android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor3PositionView.setAdapter(rotor3PositionAdapter);
|
||||
prepareSpinnerAdapter(rotor1View, R.array.rotors_1_8);
|
||||
prepareSpinnerAdapter(rotor2View, R.array.rotors_1_8);
|
||||
prepareSpinnerAdapter(rotor3View, R.array.rotors_1_8);
|
||||
prepareSpinnerAdapter(reflectorView, R.array.reflectors_b_c);
|
||||
prepareSpinnerAdapter(rotor1PositionView, rotorPositionArray);
|
||||
prepareSpinnerAdapter(rotor2PositionView, rotorPositionArray);
|
||||
prepareSpinnerAdapter(rotor3PositionView, rotorPositionArray);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLayout()
|
||||
public void resetLayout()
|
||||
{
|
||||
int[] conf = enigma.getConfiguration();
|
||||
rotor1View.setSelection(conf[0]-1);
|
||||
rotor2View.setSelection(conf[1]-1);
|
||||
rotor3View.setSelection(conf[2]-1);
|
||||
reflectorView.setSelection(conf[3]-2); //B=2 -> 0
|
||||
rotor1PositionView.setSelection(conf[4]);
|
||||
rotor2PositionView.setSelection(conf[5]);
|
||||
rotor3PositionView.setSelection(conf[6]);
|
||||
ringSettings[0] = conf[7];
|
||||
ringSettings[1] = conf[8];
|
||||
ringSettings[2] = conf[9];
|
||||
enigma = new Enigma_M3();
|
||||
setLayoutState(enigma.getState());
|
||||
output.setText("");
|
||||
input.setText("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] createConfiguration()
|
||||
public void setLayoutState(EnigmaStateBundle state)
|
||||
{
|
||||
int[] conf = new int[10];
|
||||
//Rotors 1..3
|
||||
conf[0] = rotor1View.getSelectedItemPosition() + 1;
|
||||
conf[1] = rotor2View.getSelectedItemPosition() + 1;
|
||||
conf[2] = rotor3View.getSelectedItemPosition() + 1;
|
||||
//Reflector
|
||||
conf[3] = reflectorView.getSelectedItemPosition() + 2; //M3 has no B
|
||||
this.rotor1View.setSelection(state.getTypeRotor1());
|
||||
this.rotor2View.setSelection(state.getTypeRotor2());
|
||||
this.rotor3View.setSelection(state.getTypeRotor3());
|
||||
this.reflectorView.setSelection(state.getTypeReflector());
|
||||
this.rotor1PositionView.setSelection(state.getRotationRotor1());
|
||||
this.rotor2PositionView.setSelection(state.getRotationRotor2());
|
||||
this.rotor3PositionView.setSelection(state.getRotationRotor3());
|
||||
}
|
||||
|
||||
conf[4] = rotor1PositionView.getSelectedItemPosition();
|
||||
conf[5] = rotor2PositionView.getSelectedItemPosition();
|
||||
conf[6] = rotor3PositionView.getSelectedItemPosition();
|
||||
@Override
|
||||
public void syncStateFromLayoutToEnigma()
|
||||
{
|
||||
EnigmaStateBundle state = getEnigma().getState();
|
||||
state.setTypeRotor1(rotor1View.getSelectedItemPosition());
|
||||
state.setTypeRotor2(rotor2View.getSelectedItemPosition());
|
||||
state.setTypeRotor3(rotor3View.getSelectedItemPosition());
|
||||
state.setTypeReflector(reflectorView.getSelectedItemPosition());
|
||||
state.setRotationRotor1(rotor1PositionView.getSelectedItemPosition());
|
||||
state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition());
|
||||
state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition());
|
||||
getEnigma().setState(state);
|
||||
}
|
||||
|
||||
conf[7] = ringSettings[0];
|
||||
conf[8] = ringSettings[1];
|
||||
conf[9] = ringSettings[2];
|
||||
|
||||
return conf;
|
||||
@Override
|
||||
public Enigma_M3 getEnigma()
|
||||
{
|
||||
return this.enigma;
|
||||
}
|
||||
}
|
|
@ -1,39 +1,37 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.layout;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Button;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.Toast;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.R;
|
||||
import de.vanitasvitae.enigmandroid.enigma.EnigmaStateBundle;
|
||||
import de.vanitasvitae.enigmandroid.enigma.Enigma_M4;
|
||||
import de.vanitasvitae.enigmandroid.enigma.Plugboard;
|
||||
|
||||
/**
|
||||
* Concrete LayoutContainer for the M4 layout.
|
||||
* This class contains the layout and controls the layout elements such as spinners and stuff
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* @author vanitasvitae
|
||||
*/
|
||||
public class LayoutContainer_M4 extends LayoutContainer
|
||||
{
|
||||
private Enigma_M4 enigma;
|
||||
|
||||
private Spinner rotor1View;
|
||||
private Spinner rotor2View;
|
||||
private Spinner rotor3View;
|
||||
|
@ -44,211 +42,98 @@ public class LayoutContainer_M4 extends LayoutContainer
|
|||
private Spinner rotor3PositionView;
|
||||
private Spinner rotor4PositionView;
|
||||
|
||||
private EditText plugboardView;
|
||||
|
||||
public LayoutContainer_M4()
|
||||
{
|
||||
super();
|
||||
main.setTitle("M4 - EnigmAndroid");
|
||||
this.enigma = new Enigma_M4();
|
||||
this.ringSettings = new int[]{0,0,0,0};
|
||||
this.resetLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setEnigmaLayout()
|
||||
{
|
||||
MainActivity.ActivitySingleton.getInstance().getActivity().setContentView(R.layout.activity_main_m4);
|
||||
}
|
||||
|
||||
|
||||
public Enigma_M4 getEnigma()
|
||||
{
|
||||
return this.enigma;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assembleLayout() {
|
||||
this.rotor1View = (Spinner) main.findViewById(R.id.rotor1);
|
||||
this.rotor2View = (Spinner) main.findViewById(R.id.rotor2);
|
||||
this.rotor3View = (Spinner) main.findViewById(R.id.rotor3);
|
||||
this.rotor4View = (Spinner) main.findViewById(R.id.thin_rotor);
|
||||
this.reflectorView = (Spinner) main.findViewById(R.id.reflector);
|
||||
this.rotor1PositionView = (Spinner) main.findViewById(R.id.rotor1position);
|
||||
this.rotor2PositionView = (Spinner) main.findViewById(R.id.rotor2position);
|
||||
this.rotor3PositionView = (Spinner) main.findViewById(R.id.rotor3position);
|
||||
this.rotor4PositionView = (Spinner) main.findViewById(R.id.thin_rotor_position);
|
||||
this.plugboardView = (EditText) main.findViewById(R.id.plugboard);
|
||||
this.inputView = (EditText) main.findViewById(R.id.input);
|
||||
this.outputView = (EditText) main.findViewById(R.id.output);
|
||||
this.reflectorView = (Spinner) main.findViewById(R.id.reflector);
|
||||
Button setPlugboardButton = (Button) main.findViewById(R.id.button_plugboard);
|
||||
if(setPlugboardButton != null) setPlugboardButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
new PluggableDialogBuilder(getEnigma().getState()).showDialogPlugboard();
|
||||
}
|
||||
});
|
||||
|
||||
initialize();
|
||||
reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
void initialize()
|
||||
{
|
||||
Character[] rotorPositionArray = new Character[26];
|
||||
for(int i=0; i<26; i++) {rotorPositionArray[i] = (char) (65+i); /**Fill with A..Z*/}
|
||||
for(int i=0; i<26; i++) {rotorPositionArray[i] = (char) (65+i); /*Fill with A..Z*/}
|
||||
|
||||
ArrayAdapter<CharSequence> rotor1Adapter = ArrayAdapter.createFromResource(main, R.array.rotors_1_8,
|
||||
android.R.layout.simple_spinner_item);
|
||||
rotor1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor1View.setAdapter(rotor1Adapter);
|
||||
ArrayAdapter<CharSequence> rotor2Adapter = ArrayAdapter.createFromResource(main, R.array.rotors_1_8,
|
||||
android.R.layout.simple_spinner_item);
|
||||
rotor2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor2View.setAdapter(rotor2Adapter);
|
||||
ArrayAdapter<CharSequence> rotor3Adapter = ArrayAdapter.createFromResource(main, R.array.rotors_1_8,
|
||||
android.R.layout.simple_spinner_item);
|
||||
rotor3Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor3View.setAdapter(rotor3Adapter);
|
||||
ArrayAdapter<CharSequence> rotor4Adapter = ArrayAdapter.createFromResource(main, R.array.rotors_beta_gamma,
|
||||
android.R.layout.simple_spinner_item);
|
||||
rotor4Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor4View.setAdapter(rotor4Adapter);
|
||||
|
||||
ArrayAdapter<CharSequence> reflectorAdapter = ArrayAdapter.createFromResource(main, R.array.reflectors_b_c,
|
||||
android.R.layout.simple_spinner_item);
|
||||
reflectorAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
reflectorView.setAdapter(reflectorAdapter);
|
||||
|
||||
ArrayAdapter<Character> rotor1PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(),
|
||||
android.R.layout.simple_spinner_item,rotorPositionArray);
|
||||
rotor1PositionAdapter.setDropDownViewResource(
|
||||
android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor1PositionView.setAdapter(rotor1PositionAdapter);
|
||||
ArrayAdapter<Character> rotor2PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(),
|
||||
android.R.layout.simple_spinner_item,rotorPositionArray);
|
||||
rotor2PositionAdapter.setDropDownViewResource(
|
||||
android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor2PositionView.setAdapter(rotor2PositionAdapter);
|
||||
ArrayAdapter<Character> rotor3PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(),
|
||||
android.R.layout.simple_spinner_item,rotorPositionArray);
|
||||
rotor3PositionAdapter.setDropDownViewResource(
|
||||
android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor3PositionView.setAdapter(rotor3PositionAdapter);
|
||||
ArrayAdapter<Character> rotor4PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(),
|
||||
android.R.layout.simple_spinner_item,rotorPositionArray);
|
||||
rotor4PositionAdapter.setDropDownViewResource(
|
||||
android.R.layout.simple_spinner_dropdown_item);
|
||||
rotor4PositionView.setAdapter(rotor4PositionAdapter);
|
||||
prepareSpinnerAdapter(rotor1View, R.array.rotors_1_8);
|
||||
prepareSpinnerAdapter(rotor2View, R.array.rotors_1_8);
|
||||
prepareSpinnerAdapter(rotor3View, R.array.rotors_1_8);
|
||||
prepareSpinnerAdapter(rotor4View, R.array.rotors_beta_gamma);
|
||||
prepareSpinnerAdapter(reflectorView, R.array.reflectors_b_c);
|
||||
prepareSpinnerAdapter(rotor1PositionView, rotorPositionArray);
|
||||
prepareSpinnerAdapter(rotor2PositionView, rotorPositionArray);
|
||||
prepareSpinnerAdapter(rotor3PositionView, rotorPositionArray);
|
||||
prepareSpinnerAdapter(rotor4PositionView, rotorPositionArray);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset()
|
||||
{
|
||||
rotor1View.setSelection(0); //I
|
||||
rotor2View.setSelection(1); //II
|
||||
rotor3View.setSelection(2); //III
|
||||
rotor4View.setSelection(0); //Beta
|
||||
reflectorView.setSelection(0); //B
|
||||
rotor1PositionView.setSelection(0); //0
|
||||
rotor2PositionView.setSelection(0); //0
|
||||
rotor3PositionView.setSelection(0); //0
|
||||
rotor4PositionView.setSelection(0); //0
|
||||
ringSettings = new int[]{0,0,0,0};
|
||||
inputView.setText("");
|
||||
outputView.setText("");
|
||||
plugboardView.setText("");
|
||||
enigma.setConfiguration(createConfiguration());
|
||||
enigma.setPlugboard(new Plugboard());
|
||||
public void resetLayout() {
|
||||
enigma = new Enigma_M4();
|
||||
setLayoutState(enigma.getState());
|
||||
output.setText("");
|
||||
input.setText("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLayout()
|
||||
{
|
||||
int[] conf = enigma.getConfiguration();
|
||||
rotor1View.setSelection(conf[0]-1);
|
||||
rotor2View.setSelection(conf[1]-1);
|
||||
rotor3View.setSelection(conf[2]-1);
|
||||
rotor4View.setSelection(conf[3]-9);
|
||||
reflectorView.setSelection(conf[4]-4);
|
||||
rotor1PositionView.setSelection(conf[5]);
|
||||
rotor2PositionView.setSelection(conf[6]);
|
||||
rotor3PositionView.setSelection(conf[7]);
|
||||
rotor4PositionView.setSelection(conf[8]);
|
||||
ringSettings[0] = conf[9];
|
||||
ringSettings[1] = conf[10];
|
||||
ringSettings[2] = conf[11];
|
||||
ringSettings[3] = conf[12];
|
||||
public void setLayoutState(EnigmaStateBundle state) {
|
||||
this.rotor1View.setSelection(state.getTypeRotor1());
|
||||
this.rotor2View.setSelection(state.getTypeRotor2());
|
||||
this.rotor3View.setSelection(state.getTypeRotor3());
|
||||
this.rotor4View.setSelection(state.getTypeRotor4());
|
||||
this.reflectorView.setSelection(state.getTypeReflector());
|
||||
this.rotor1PositionView.setSelection(state.getRotationRotor1());
|
||||
this.rotor2PositionView.setSelection(state.getRotationRotor2());
|
||||
this.rotor3PositionView.setSelection(state.getRotationRotor3());
|
||||
this.rotor4PositionView.setSelection(state.getRotationRotor4());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] createConfiguration()
|
||||
{
|
||||
int[] conf = new int[13];
|
||||
//Rotors 1..4
|
||||
conf[0] = rotor1View.getSelectedItemPosition() + 1;
|
||||
conf[1] = rotor2View.getSelectedItemPosition() + 1;
|
||||
conf[2] = rotor3View.getSelectedItemPosition() + 1;
|
||||
conf[3] = rotor4View.getSelectedItemPosition() + 9; //Beta is rotor #9
|
||||
//Reflector
|
||||
conf[4] = reflectorView.getSelectedItemPosition() + 4; //thinB is reflector #4
|
||||
|
||||
conf[5] = rotor1PositionView.getSelectedItemPosition();
|
||||
conf[6] = rotor2PositionView.getSelectedItemPosition();
|
||||
conf[7] = rotor3PositionView.getSelectedItemPosition();
|
||||
conf[8] = rotor4PositionView.getSelectedItemPosition();
|
||||
|
||||
conf[9] = ringSettings[0];
|
||||
conf[10] = ringSettings[1];
|
||||
conf[11] = ringSettings[2];
|
||||
conf[12] = ringSettings[3];
|
||||
|
||||
return conf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[][] createPlugboardConfiguration() {
|
||||
return Plugboard.parseConfigurationString(plugboardView.getText().toString());
|
||||
public void syncStateFromLayoutToEnigma() {
|
||||
EnigmaStateBundle state = getEnigma().getState();
|
||||
state.setTypeRotor1(rotor1View.getSelectedItemPosition());
|
||||
state.setTypeRotor2(rotor2View.getSelectedItemPosition());
|
||||
state.setTypeRotor3(rotor3View.getSelectedItemPosition());
|
||||
state.setTypeRotor4(rotor4View.getSelectedItemPosition());
|
||||
state.setTypeReflector(reflectorView.getSelectedItemPosition());
|
||||
state.setRotationRotor1(rotor1PositionView.getSelectedItemPosition());
|
||||
state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition());
|
||||
state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition());
|
||||
state.setRotationRotor4(rotor4PositionView.getSelectedItemPosition());
|
||||
getEnigma().setState(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showRingSettingsDialog()
|
||||
{
|
||||
Integer[] ringArray = new Integer[26];
|
||||
for(int i=1; i<=26; i++) {ringArray[i-1] = i;}
|
||||
View ringSettingsView = View.inflate(main, R.layout.dialog_ringsettings_m4, null);
|
||||
final Spinner ring1 = (Spinner) ringSettingsView.findViewById(R.id.rotor1ring);
|
||||
ArrayAdapter<Integer> ring1Adapter = new ArrayAdapter<>(main,
|
||||
android.R.layout.simple_spinner_item,ringArray);
|
||||
ring1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
ring1.setAdapter(ring1Adapter);
|
||||
ring1.setSelection(ringSettings[0]);
|
||||
|
||||
final Spinner ring2 = (Spinner) ringSettingsView.findViewById(R.id.rotor2ring);
|
||||
ArrayAdapter<Integer> ring2Adapter = new ArrayAdapter<>(main,
|
||||
android.R.layout.simple_spinner_item,ringArray);
|
||||
ring2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
ring2.setAdapter(ring2Adapter);
|
||||
ring2.setSelection(ringSettings[1]);
|
||||
|
||||
final Spinner ring3 = (Spinner) ringSettingsView.findViewById(R.id.rotor3ring);
|
||||
ArrayAdapter<Integer> ring3Adapter = new ArrayAdapter<>(main,
|
||||
android.R.layout.simple_spinner_item,ringArray);
|
||||
ring3Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
ring3.setAdapter(ring3Adapter);
|
||||
ring3.setSelection(ringSettings[2]);
|
||||
|
||||
final Spinner ring4 = (Spinner) ringSettingsView.findViewById(R.id.rotor4ring);
|
||||
ArrayAdapter<Integer> ring4Adapter = new ArrayAdapter<>(main,
|
||||
android.R.layout.simple_spinner_item, ringArray);
|
||||
ring4Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
ring4.setAdapter(ring4Adapter);
|
||||
ring4.setSelection(ringSettings[3]);
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(main);
|
||||
builder.setTitle(R.string.title_ringsetting);
|
||||
builder.setView(ringSettingsView)
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(R.string.dialog_positiv, new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int id)
|
||||
{
|
||||
ringSettings[0] = ring1.getSelectedItemPosition();
|
||||
ringSettings[1] = ring2.getSelectedItemPosition();
|
||||
ringSettings[2] = ring3.getSelectedItemPosition();
|
||||
ringSettings[3] = ring4.getSelectedItemPosition();
|
||||
String message = main.getResources().getString(
|
||||
R.string.dialog_ringsettings_success) + " " +
|
||||
(ringSettings[3]+1) + ", " +
|
||||
(ringSettings[2]+1) + ", " +
|
||||
(ringSettings[1]+1) + ", " +
|
||||
(ringSettings[0]+1) + ".";
|
||||
Toast.makeText(main, message, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.dialog_negativ, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
dialog.cancel();
|
||||
Toast.makeText(main, R.string.dialog_ringsettings_abort,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}).show();
|
||||
new RingSettingsDialogBuilder.RingSettingsDialogBuilderRotRotRotRot().
|
||||
createRingSettingsDialog(getEnigma().getState());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.layout;
|
||||
|
||||
import android.widget.Spinner;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.R;
|
||||
import de.vanitasvitae.enigmandroid.enigma.Enigma;
|
||||
import de.vanitasvitae.enigmandroid.enigma.EnigmaStateBundle;
|
||||
import de.vanitasvitae.enigmandroid.enigma.Enigma_R;
|
||||
|
||||
/**
|
||||
* LayoutContainer for the Enigma Model R
|
||||
* This class contains the layout and controls the layout elements such as spinners and stuff
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
*/
|
||||
public class LayoutContainer_R extends LayoutContainer
|
||||
{
|
||||
private Enigma_R enigma;
|
||||
|
||||
private Spinner rotor1View;
|
||||
private Spinner rotor2View;
|
||||
private Spinner rotor3View;
|
||||
|
||||
private Spinner rotor1PositionView;
|
||||
private Spinner rotor2PositionView;
|
||||
private Spinner rotor3PositionView;
|
||||
private Spinner reflectorPositionView;
|
||||
|
||||
public LayoutContainer_R()
|
||||
{
|
||||
super();
|
||||
main.setTitle("R - EnigmAndroid");
|
||||
this.resetLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setEnigmaLayout()
|
||||
{
|
||||
MainActivity.ActivitySingleton.getInstance().getActivity().setContentView(R.layout.activity_main_g_k_r_t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enigma getEnigma() {
|
||||
return this.enigma;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assembleLayout() {
|
||||
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_R();
|
||||
setLayoutState(enigma.getState());
|
||||
output.setText("");
|
||||
input.setText("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLayoutState(EnigmaStateBundle state)
|
||||
{
|
||||
this.rotor1View.setSelection(state.getTypeRotor1());
|
||||
this.rotor2View.setSelection(state.getTypeRotor2());
|
||||
this.rotor3View.setSelection(state.getTypeRotor3());
|
||||
this.rotor1PositionView.setSelection(state.getRotationRotor1());
|
||||
this.rotor2PositionView.setSelection(state.getRotationRotor2());
|
||||
this.rotor3PositionView.setSelection(state.getRotationRotor3());
|
||||
this.reflectorPositionView.setSelection(state.getRotationReflector());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syncStateFromLayoutToEnigma()
|
||||
{
|
||||
EnigmaStateBundle state = getEnigma().getState();
|
||||
state.setTypeRotor1(rotor1View.getSelectedItemPosition());
|
||||
state.setTypeRotor2(rotor2View.getSelectedItemPosition());
|
||||
state.setTypeRotor3(rotor3View.getSelectedItemPosition());
|
||||
state.setRotationRotor1(rotor1PositionView.getSelectedItemPosition());
|
||||
state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition());
|
||||
state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition());
|
||||
state.setRotationReflector(reflectorPositionView.getSelectedItemPosition());
|
||||
getEnigma().setState(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showRingSettingsDialog()
|
||||
{
|
||||
new RingSettingsDialogBuilder.RingSettingsDialogBuilderRotRotRotRef().
|
||||
createRingSettingsDialog(getEnigma().getState());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.layout;
|
||||
|
||||
import android.widget.Spinner;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.R;
|
||||
import de.vanitasvitae.enigmandroid.enigma.Enigma;
|
||||
import de.vanitasvitae.enigmandroid.enigma.EnigmaStateBundle;
|
||||
import de.vanitasvitae.enigmandroid.enigma.Enigma_T;
|
||||
|
||||
/**
|
||||
* LayoutContainer for the Enigma Model T
|
||||
* This class contains the layout and controls the layout elements such as spinners and stuff
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
*/
|
||||
public class LayoutContainer_T extends LayoutContainer
|
||||
{
|
||||
private Enigma_T enigma;
|
||||
|
||||
private Spinner rotor1View;
|
||||
private Spinner rotor2View;
|
||||
private Spinner rotor3View;
|
||||
|
||||
private Spinner rotor1PositionView;
|
||||
private Spinner rotor2PositionView;
|
||||
private Spinner rotor3PositionView;
|
||||
private Spinner reflectorPositionView;
|
||||
|
||||
public LayoutContainer_T()
|
||||
{
|
||||
super();
|
||||
main.setTitle("T - EnigmAndroid");
|
||||
this.resetLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doCrypto()
|
||||
{
|
||||
if(inputView.getText().length()!=0)
|
||||
{
|
||||
syncStateFromLayoutToEnigma();
|
||||
String message = inputView.getText().toString();
|
||||
//<Insert funny comment here>
|
||||
boolean egg = false;
|
||||
if(message.hashCode() == -1475861192) egg = true;
|
||||
message = inputPreparer.prepareString(message);
|
||||
input.setText(message);
|
||||
if(egg) output.setText("ENIGMA<TURINGMACHINE");
|
||||
else output.setText(getEnigma().encryptString(message));
|
||||
setLayoutState(getEnigma().getState());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setEnigmaLayout()
|
||||
{
|
||||
MainActivity.ActivitySingleton.getInstance().getActivity().setContentView(
|
||||
R.layout.activity_main_g_k_r_t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enigma getEnigma() {
|
||||
return this.enigma;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assembleLayout() {
|
||||
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_8);
|
||||
prepareSpinnerAdapter(rotor2View, R.array.rotors_1_8);
|
||||
prepareSpinnerAdapter(rotor3View, R.array.rotors_1_8);
|
||||
prepareSpinnerAdapter(rotor1PositionView, rotorPositionArray);
|
||||
prepareSpinnerAdapter(rotor2PositionView, rotorPositionArray);
|
||||
prepareSpinnerAdapter(rotor3PositionView, rotorPositionArray);
|
||||
prepareSpinnerAdapter(reflectorPositionView, rotorPositionArray);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetLayout() {
|
||||
enigma = new Enigma_T();
|
||||
setLayoutState(enigma.getState());
|
||||
output.setText("");
|
||||
input.setText("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLayoutState(EnigmaStateBundle state)
|
||||
{
|
||||
this.rotor1View.setSelection(state.getTypeRotor1());
|
||||
this.rotor2View.setSelection(state.getTypeRotor2());
|
||||
this.rotor3View.setSelection(state.getTypeRotor3());
|
||||
|
||||
this.rotor1PositionView.setSelection(state.getRotationRotor1());
|
||||
this.rotor2PositionView.setSelection(state.getRotationRotor2());
|
||||
this.rotor3PositionView.setSelection(state.getRotationRotor3());
|
||||
this.reflectorPositionView.setSelection(state.getRotationReflector());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syncStateFromLayoutToEnigma()
|
||||
{
|
||||
EnigmaStateBundle state = getEnigma().getState();
|
||||
state.setTypeRotor1(rotor1View.getSelectedItemPosition());
|
||||
state.setTypeRotor2(rotor2View.getSelectedItemPosition());
|
||||
state.setTypeRotor3(rotor3View.getSelectedItemPosition());
|
||||
state.setRotationRotor1(rotor1PositionView.getSelectedItemPosition());
|
||||
state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition());
|
||||
state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition());
|
||||
state.setRotationReflector(reflectorPositionView.getSelectedItemPosition());
|
||||
getEnigma().setState(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showRingSettingsDialog()
|
||||
{
|
||||
new RingSettingsDialogBuilder.RingSettingsDialogBuilderRotRotRotRef().
|
||||
createRingSettingsDialog(getEnigma().getState());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.R;
|
||||
|
||||
/**
|
||||
* Builder for the dialog that is used to obtain a passphrase to generate
|
||||
* a enigma configuration from it.
|
||||
* Alternatively the user can enter the content String from a EnigmAndroid QR-Code here.
|
||||
* That would have the same effect as scanning the QR-Code.
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
*/
|
||||
public class PassphraseDialogBuilder
|
||||
{
|
||||
private final MainActivity main;
|
||||
private final View passphraseDialogView;
|
||||
private final EditText passphrase;
|
||||
private 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) {
|
||||
//Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
//Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
//Count input text and enable positive button if length > 0.
|
||||
//Disable else
|
||||
if(s.length() > 0) positive.setEnabled(true);
|
||||
else positive.setEnabled(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* create and show the dialog
|
||||
*/
|
||||
public void showDialog()
|
||||
{
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(main);
|
||||
builder.setTitle(R.string.hint_configuration);
|
||||
Dialog d = builder.setView(passphraseDialogView)
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(R.string.dialog_positive, new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int id)
|
||||
{
|
||||
String pass = passphrase.getText().toString();
|
||||
if(pass.startsWith(MainActivity.APP_ID+"/"))
|
||||
{
|
||||
main.restoreStateFromCode(pass);
|
||||
Toast.makeText(main, R.string.dialog_passphrase_was_coded_state, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
else
|
||||
{
|
||||
main.applyStateFromSeed(pass);
|
||||
String message = String.format(main.getResources().getString(
|
||||
R.string.dialog_passphrase_set), " \'"+pass+"\'");
|
||||
Toast.makeText(main, message, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.dialog_negative, 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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,432 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.layout;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.res.Resources;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
||||
import de.vanitasvitae.enigmandroid.MainActivity;
|
||||
import de.vanitasvitae.enigmandroid.R;
|
||||
import de.vanitasvitae.enigmandroid.enigma.EnigmaStateBundle;
|
||||
|
||||
/**
|
||||
* Builder for the dialog that is used to plug the plugboard/wire the
|
||||
* rewirable reflector.
|
||||
* Copyright (C) 2015 Paul Schaub
|
||||
*/
|
||||
class PluggableDialogBuilder
|
||||
{
|
||||
private ArrayList<ButtonWrapper> buttons;
|
||||
private View dialogView;
|
||||
private final MainActivity main;
|
||||
private final EnigmaStateBundle state;
|
||||
|
||||
private boolean allowIncompleteConnections;
|
||||
private Button positive;
|
||||
|
||||
private HashSet<Integer> colors;
|
||||
|
||||
private int previouslyPressedButton = -1;
|
||||
|
||||
/**
|
||||
* Constructor that prepares layout and buttons.
|
||||
* @param state EnigmaStateBundle from which dialog gets restored and which gets manipulated
|
||||
*/
|
||||
public PluggableDialogBuilder(EnigmaStateBundle state)
|
||||
{
|
||||
this.state = state;
|
||||
main = (MainActivity) MainActivity.ActivitySingleton.getInstance().getActivity();
|
||||
initializeLayout();
|
||||
setButtonListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show dialog for the plugboard
|
||||
*/
|
||||
public void showDialogPlugboard()
|
||||
{
|
||||
allowIncompleteConnections = true;
|
||||
restoreConfigurationPlugboard();
|
||||
AlertDialog.Builder adb = new AlertDialog.Builder(main);
|
||||
adb.setTitle(R.string.title_plugboard_dialog);
|
||||
Dialog d = adb.setView(dialogView)
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(R.string.dialog_positive, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
int[] plugs = new int[26];
|
||||
for (int i = 0; i < 26; i++) {
|
||||
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();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.dialog_negative, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
dialog.cancel();
|
||||
Toast.makeText(main, R.string.dialog_abort,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}).create();
|
||||
|
||||
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
|
||||
lp.copyFrom(d.getWindow().getAttributes());
|
||||
lp.width = WindowManager.LayoutParams.MATCH_PARENT;
|
||||
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
|
||||
d.show();
|
||||
d.getWindow().setAttributes(lp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the dialog for the reflector. This can only be positively closed when all
|
||||
* connections are made.
|
||||
*/
|
||||
public void showDialogReflector()
|
||||
{
|
||||
allowIncompleteConnections = false;
|
||||
restoreConfigurationReflector();
|
||||
AlertDialog.Builder adb = new AlertDialog.Builder(main);
|
||||
adb.setTitle(R.string.title_reflector_dialog);
|
||||
Dialog d = adb.setView(dialogView)
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(R.string.dialog_positive, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
int[] plugs = new int[26];
|
||||
for (int i = 0; i < 26; i++) {
|
||||
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();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.dialog_negative, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
dialog.cancel();
|
||||
Toast.makeText(main, R.string.dialog_abort,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}).create();
|
||||
|
||||
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
|
||||
lp.copyFrom(d.getWindow().getAttributes());
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize array of buttons, initialize background-color hashset.
|
||||
*/
|
||||
private void initializeLayout()
|
||||
{
|
||||
buttons = new ArrayList<>();
|
||||
dialogView = View.inflate(main, R.layout.dialog_plugs, null);
|
||||
|
||||
buttons.add(new ButtonWrapper((Button) dialogView.findViewById(R.id.A),0));
|
||||
buttons.add(new ButtonWrapper((Button) dialogView.findViewById(R.id.B),1));
|
||||
buttons.add(new ButtonWrapper((Button) dialogView.findViewById(R.id.C),2));
|
||||
buttons.add(new ButtonWrapper((Button) dialogView.findViewById(R.id.D),3));
|
||||
buttons.add(new ButtonWrapper((Button) dialogView.findViewById(R.id.E),4));
|
||||
buttons.add(new ButtonWrapper((Button) dialogView.findViewById(R.id.F),5));
|
||||
buttons.add(new ButtonWrapper((Button) dialogView.findViewById(R.id.G),6));
|
||||
buttons.add(new ButtonWrapper((Button) dialogView.findViewById(R.id.H),7));
|
||||
buttons.add(new ButtonWrapper((Button) dialogView.findViewById(R.id.I),8));
|
||||
buttons.add(new ButtonWrapper((Button) dialogView.findViewById(R.id.J),9));
|
||||
buttons.add(new ButtonWrapper((Button) dialogView.findViewById(R.id.K),10));
|
||||
buttons.add(new ButtonWrapper((Button) dialogView.findViewById(R.id.L),11));
|
||||
buttons.add(new ButtonWrapper((Button) dialogView.findViewById(R.id.M),12));
|
||||
buttons.add(new ButtonWrapper((Button) dialogView.findViewById(R.id.N),13));
|
||||
buttons.add(new ButtonWrapper((Button) dialogView.findViewById(R.id.O),14));
|
||||
buttons.add(new ButtonWrapper((Button) dialogView.findViewById(R.id.P),15));
|
||||
buttons.add(new ButtonWrapper((Button) dialogView.findViewById(R.id.Q),16));
|
||||
buttons.add(new ButtonWrapper((Button) dialogView.findViewById(R.id.R),17));
|
||||
buttons.add(new ButtonWrapper((Button) dialogView.findViewById(R.id.S),18));
|
||||
buttons.add(new ButtonWrapper((Button) dialogView.findViewById(R.id.T),19));
|
||||
buttons.add(new ButtonWrapper((Button) dialogView.findViewById(R.id.U),20));
|
||||
buttons.add(new ButtonWrapper((Button) dialogView.findViewById(R.id.V),21));
|
||||
buttons.add(new ButtonWrapper((Button) dialogView.findViewById(R.id.W),22));
|
||||
buttons.add(new ButtonWrapper((Button) dialogView.findViewById(R.id.X),23));
|
||||
buttons.add(new ButtonWrapper((Button) dialogView.findViewById(R.id.Y),24));
|
||||
buttons.add(new ButtonWrapper((Button) dialogView.findViewById(R.id.Z),25));
|
||||
|
||||
colors = new HashSet<>();
|
||||
colors.add(R.drawable.button_orange);
|
||||
colors.add(R.drawable.button_olive);
|
||||
colors.add(R.drawable.button_blue);
|
||||
colors.add(R.drawable.button_red);
|
||||
colors.add(R.drawable.button_yellow);
|
||||
colors.add(R.drawable.button_purple);
|
||||
colors.add(R.drawable.button_green);
|
||||
colors.add(R.drawable.button_cyan);
|
||||
colors.add(R.drawable.button_berry);
|
||||
colors.add(R.drawable.button_brown);
|
||||
colors.add(R.drawable.button_pink);
|
||||
colors.add(R.drawable.button_elder);
|
||||
colors.add(R.drawable.button_black);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set listeners for all buttons
|
||||
*/
|
||||
private void setButtonListeners()
|
||||
{
|
||||
for(int i=0; i<26; i++)
|
||||
{
|
||||
Button b = buttons.get(i).getButton();
|
||||
final int id = i;
|
||||
b.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
buttonPressed(id);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check, whether all connections are done. If so, return true.
|
||||
* return false otherwise
|
||||
* @return boolean
|
||||
*/
|
||||
private 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* restore the connections according to the plugboard
|
||||
*/
|
||||
private void restoreConfigurationPlugboard()
|
||||
{
|
||||
restoreConfiguration(state.getConfigurationPlugboard());
|
||||
}
|
||||
|
||||
/**
|
||||
* restore the connections according to the reflector
|
||||
*/
|
||||
private void restoreConfigurationReflector()
|
||||
{
|
||||
restoreConfiguration(state.getConfigurationReflector());
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect all the buttons according to c.
|
||||
* @param c array of connections
|
||||
*/
|
||||
private void restoreConfiguration(int[] c)
|
||||
{
|
||||
for(int i=0; i<26; i++)
|
||||
{
|
||||
setPlug(i, c[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect button1 and button2. If two buttons got pressed afterwards and they are not the same
|
||||
* they get connected. If one or both of them was connected beforehand, these connections get
|
||||
* resolved. If both events come from the same button, the buttons connections (if any) get
|
||||
* resolved.
|
||||
* @param button1 first and
|
||||
* @param button2 second button
|
||||
*/
|
||||
private void setPlug(int button1, int button2)
|
||||
{
|
||||
if(button1 == button2)
|
||||
{
|
||||
setButtonFree(buttons.get(button1).getConnectedButton());
|
||||
setButtonFree(button1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ButtonWrapper b1 = buttons.get(button1);
|
||||
ButtonWrapper b2 = buttons.get(button2);
|
||||
|
||||
if (b1.getConnectedButton() != button1) {
|
||||
setButtonFree(b1.getConnectedButton());
|
||||
}
|
||||
if (b2.getConnectedButton() != button2) {
|
||||
setButtonFree(b2.getConnectedButton());
|
||||
}
|
||||
|
||||
b1.setConnectedButton(button2);
|
||||
b2.setConnectedButton(button1);
|
||||
|
||||
int res;
|
||||
Iterator<Integer> it = colors.iterator();
|
||||
res = it.next();
|
||||
if(res == 0) res = it.next();
|
||||
colors.remove(res);
|
||||
|
||||
b1.setResourceID(res);
|
||||
b2.setResourceID(res);
|
||||
}
|
||||
updatePositiveButton();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update state of positive button. Check, if all connections are done and if so, enable positive
|
||||
* button. Otherwise disable it.
|
||||
*/
|
||||
private void updatePositiveButton()
|
||||
{
|
||||
if(!allowIncompleteConnections && positive != null)
|
||||
{
|
||||
if(allConnectionsDone()) positive.setEnabled(true);
|
||||
else positive.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set buttons to not connected. That includes changing background to grey, set connection to
|
||||
* itself.
|
||||
* @param b index of button
|
||||
*/
|
||||
private void setButtonFree(int b)
|
||||
{
|
||||
ButtonWrapper button = buttons.get(b);
|
||||
int res = button.getResourceID();
|
||||
if(res != R.drawable.button_grey)
|
||||
colors.add(button.getResourceID());
|
||||
button.setResourceID(R.drawable.button_grey);
|
||||
button.setConnectedButton(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle button pressed events.
|
||||
* @param button button that got pressed
|
||||
*/
|
||||
private void buttonPressed(int button)
|
||||
{
|
||||
if(previouslyPressedButton != -1)
|
||||
{
|
||||
setPlug(previouslyPressedButton, button);
|
||||
previouslyPressedButton = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
previouslyPressedButton = button;
|
||||
buttons.get(button).setWaiting();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper class for Buttons, that also stores the index of both, the connected button, as well
|
||||
* as the button itself and resourceID of used material.
|
||||
*/
|
||||
private static class ButtonWrapper
|
||||
{
|
||||
private Button button;
|
||||
private int connectedButton;
|
||||
private int resourceID;
|
||||
private int index;
|
||||
|
||||
/**
|
||||
* Create ButtonWrapper
|
||||
* @param button underlying Button
|
||||
* @param index index of the button in the buttons array
|
||||
*/
|
||||
public ButtonWrapper(Button button, int index)
|
||||
{
|
||||
this.button = button;
|
||||
this.index = index;
|
||||
this.connectedButton = index;
|
||||
}
|
||||
|
||||
/**
|
||||
* set the index of the connected button and update buttons text
|
||||
* @param other index
|
||||
*/
|
||||
public void setConnectedButton(int other)
|
||||
{
|
||||
this.connectedButton = other;
|
||||
Resources res = MainActivity.ActivitySingleton.getInstance().getActivity().getResources();
|
||||
this.getButton().setText(String.format(
|
||||
res.getText(R.string.button_plug_title).toString(),
|
||||
""+(char) (index+65),
|
||||
""+(char) (connectedButton+65)));
|
||||
}
|
||||
|
||||
/**
|
||||
* return index of the connected button
|
||||
* @return index of connected button
|
||||
*/
|
||||
public int getConnectedButton()
|
||||
{
|
||||
return this.connectedButton;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate, that this button is waiting for another button to connect to.
|
||||
*/
|
||||
public void setWaiting()
|
||||
{
|
||||
Resources res = MainActivity.ActivitySingleton.getInstance().getActivity().getResources();
|
||||
this.getButton().setText(String.format(
|
||||
res.getText(R.string.button_plug_title).toString(),
|
||||
""+(char) (index+65)," "));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set buttons background and store value in resourceID
|
||||
* @param r resourceID of background material
|
||||
*/
|
||||
public void setResourceID(int r)
|
||||
{
|
||||
button.setBackgroundResource(r);
|
||||
this.resourceID = r;
|
||||
}
|
||||
|
||||
/**
|
||||
* get resourceID of buttons background as store in resourceID
|
||||
* @return resourceID
|
||||
*/
|
||||
public int getResourceID()
|
||||
{
|
||||
return this.resourceID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return stored button object
|
||||
* @return button
|
||||
*/
|
||||
public Button getButton()
|
||||
{
|
||||
return button;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,405 @@
|
|||
/**
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.vanitasvitae.enigmandroid.layout;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
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
|
||||
*/
|
||||
public abstract class RingSettingsDialogBuilder
|
||||
{
|
||||
protected abstract void showDialog(EnigmaStateBundle stateBundle, ArrayAdapter[] adapters, int[] rIDs, Actions actions);
|
||||
public abstract void createRingSettingsDialog(EnigmaStateBundle stateBundle);
|
||||
|
||||
private static ArrayAdapter createAdapter(Integer[] array)
|
||||
{
|
||||
ArrayAdapter adapter = new ArrayAdapter<>(
|
||||
MainActivity.ActivitySingleton.getInstance().getActivity(),
|
||||
android.R.layout.simple_spinner_item, array);
|
||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
return adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ArrayAdapter working over an array of numbers 1 to 26.
|
||||
* @return ArrayAdapter
|
||||
*/
|
||||
private static ArrayAdapter createAdapter1_26()
|
||||
{
|
||||
Integer[] ringArray = new Integer[26];
|
||||
for(int i=1; i<=26; i++) {ringArray[i-1] = i;}
|
||||
return createAdapter(ringArray);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* DialogBuilder for 3 Spinners and ringSettingRotor1-3
|
||||
*/
|
||||
public static class RingSettingsDialogBuilderRotRotRot extends RingSettingsDialogBuilder
|
||||
{
|
||||
public void createRingSettingsDialog(final EnigmaStateBundle state)
|
||||
{
|
||||
this.showDialog(state,
|
||||
new ArrayAdapter[]{
|
||||
createAdapter1_26(),
|
||||
createAdapter1_26(),
|
||||
createAdapter1_26()},
|
||||
new int[]{
|
||||
R.string.hint_rotor1,
|
||||
R.string.hint_rotor2,
|
||||
R.string.hint_rotor3},
|
||||
new Actions3(state) {
|
||||
@Override
|
||||
protected void firstSpinnerItemSelected(int pos) {
|
||||
state.setRingSettingRotor1(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void secondSpinnerItemSelected(int pos) {
|
||||
state.setRingSettingRotor2(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void thirdSpinnerItemSelected(int pos) {
|
||||
state.setRingSettingRotor3(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getFirstValueFromBundle() {
|
||||
return state.getRingSettingRotor1();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSecondValueFromBundle() {
|
||||
return state.getRingSettingRotor2();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getThirdValueFromBundle() {
|
||||
return state.getRingSettingRotor3();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void showDialog(final EnigmaStateBundle stateBundle, ArrayAdapter[] adapters, int[] rIDs, Actions actions)
|
||||
{
|
||||
if(adapters.length != 3 || rIDs.length != 3)
|
||||
{
|
||||
Log.e(MainActivity.APP_ID, "RingSettingsDialogBuilderRotRotRot.showDialog():" +
|
||||
" Length of adapters array or length of rIDs array not equal to 3!");
|
||||
}
|
||||
final Actions3 action = (Actions3) actions;
|
||||
final MainActivity main = (MainActivity) MainActivity.ActivitySingleton.getInstance().getActivity();
|
||||
View ringSettingsView = View.inflate(main, R.layout.dialog_ringsettings_3, null);
|
||||
|
||||
TextView ring1Title = (TextView) ringSettingsView.findViewById(R.id.dialog_text_rotor1);
|
||||
ring1Title.setText(rIDs[0]);
|
||||
TextView ring2Title = (TextView) ringSettingsView.findViewById(R.id.dialog_text_rotor2);
|
||||
ring2Title.setText(rIDs[1]);
|
||||
TextView ring3Title = (TextView) ringSettingsView.findViewById(R.id.dialog_text_rotor3);
|
||||
ring3Title.setText(rIDs[2]);
|
||||
|
||||
final Spinner ring1 = (Spinner) ringSettingsView.findViewById(R.id.rotor1ring);
|
||||
ring1.setAdapter(adapters[0]);
|
||||
ring1.setSelection(action.getFirstValueFromBundle());
|
||||
|
||||
final Spinner ring2 = (Spinner) ringSettingsView.findViewById(R.id.rotor2ring);
|
||||
ring2.setAdapter(adapters[1]);
|
||||
ring2.setSelection(action.getSecondValueFromBundle());
|
||||
|
||||
final Spinner ring3 = (Spinner) ringSettingsView.findViewById(R.id.rotor3ring);
|
||||
ring3.setAdapter(adapters[2]);
|
||||
ring3.setSelection(action.getThirdValueFromBundle());
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(main);
|
||||
builder.setTitle(R.string.title_ring_setting);
|
||||
builder.setView(ringSettingsView)
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(R.string.dialog_positive, new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int id)
|
||||
{
|
||||
action.firstSpinnerItemSelected(ring1.getSelectedItemPosition());
|
||||
action.secondSpinnerItemSelected(ring2.getSelectedItemPosition());
|
||||
action.thirdSpinnerItemSelected(ring3.getSelectedItemPosition());
|
||||
String message = String.format(main.getResources().getString(
|
||||
R.string.dialog_ring_settings_success),
|
||||
(ring1.getSelectedItemPosition()+1) + ", " +
|
||||
(ring2.getSelectedItemPosition()+1) + ", " +
|
||||
(ring3.getSelectedItemPosition()+1));
|
||||
main.onDialogFinished(stateBundle);
|
||||
Toast.makeText(main, message, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.dialog_negative, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
dialog.cancel();
|
||||
Toast.makeText(main, R.string.dialog_abort,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}).show();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DialogBuilder for 4 Spinners and ringSettingRotor1-3, ringSettingReflector
|
||||
*/
|
||||
public static class RingSettingsDialogBuilderRotRotRotRef extends RingSettingsDialogBuilder
|
||||
{
|
||||
@Override
|
||||
public void createRingSettingsDialog(final EnigmaStateBundle state) {
|
||||
this.showDialog(state,
|
||||
new ArrayAdapter[]{
|
||||
createAdapter1_26(),
|
||||
createAdapter1_26(),
|
||||
createAdapter1_26(),
|
||||
createAdapter1_26()},
|
||||
new int[]{
|
||||
R.string.hint_rotor1,
|
||||
R.string.hint_rotor2,
|
||||
R.string.hint_rotor3,
|
||||
R.string.hint_reflector},
|
||||
new Actions4(state) {
|
||||
|
||||
@Override
|
||||
protected void firstSpinnerItemSelected(int pos) {
|
||||
state.setRingSettingRotor1(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void secondSpinnerItemSelected(int pos) {
|
||||
state.setRingSettingRotor2(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void thirdSpinnerItemSelected(int pos) {
|
||||
state.setRingSettingRotor3(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getFirstValueFromBundle() {
|
||||
return state.getRingSettingRotor1();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSecondValueFromBundle() {
|
||||
return state.getRingSettingRotor2();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getThirdValueFromBundle() {
|
||||
return state.getRingSettingRotor3();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fourthSpinnerItemSelected(int pos) {
|
||||
state.setRingSettingReflector(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getFourthValueFromBundle() {
|
||||
return state.getRingSettingReflector();
|
||||
}
|
||||
});
|
||||
}
|
||||
@Override
|
||||
protected void showDialog(final EnigmaStateBundle stateBundle, ArrayAdapter[] adapters, int[] rIDs, Actions actions) {
|
||||
if(adapters.length != 4 || rIDs.length != 4)
|
||||
{
|
||||
Log.d(MainActivity.APP_ID, "RingSettingsDialogBuilderRotRotRotRef.showDialog():" +
|
||||
"Length of adapters array or length of rIDs array not equal to 4!");
|
||||
}
|
||||
final Actions4 action = (Actions4) actions;
|
||||
final MainActivity main = (MainActivity) MainActivity.ActivitySingleton.getInstance().getActivity();
|
||||
View ringSettingsView = View.inflate(main, R.layout.dialog_ringsettings_4, null);
|
||||
|
||||
TextView ring1Title = (TextView) ringSettingsView.findViewById(R.id.dialog_text_rotor1);
|
||||
ring1Title.setText(rIDs[0]);
|
||||
TextView ring2Title = (TextView) ringSettingsView.findViewById(R.id.dialog_text_rotor2);
|
||||
ring2Title.setText(rIDs[1]);
|
||||
TextView ring3Title = (TextView) ringSettingsView.findViewById(R.id.dialog_text_rotor3);
|
||||
ring3Title.setText(rIDs[2]);
|
||||
TextView ring4Title = (TextView) ringSettingsView.findViewById(R.id.dialog_text_rotor4);
|
||||
ring4Title.setText(rIDs[3]);
|
||||
|
||||
final Spinner ring1 = (Spinner) ringSettingsView.findViewById(R.id.rotor1ring);
|
||||
ring1.setAdapter(adapters[0]);
|
||||
ring1.setSelection(action.getFirstValueFromBundle());
|
||||
|
||||
final Spinner ring2 = (Spinner) ringSettingsView.findViewById(R.id.rotor2ring);
|
||||
ring2.setAdapter(adapters[1]);
|
||||
ring2.setSelection(action.getSecondValueFromBundle());
|
||||
|
||||
final Spinner ring3 = (Spinner) ringSettingsView.findViewById(R.id.rotor3ring);
|
||||
ring3.setAdapter(adapters[2]);
|
||||
ring3.setSelection(action.getThirdValueFromBundle());
|
||||
|
||||
final Spinner ring4 = (Spinner) ringSettingsView.findViewById(R.id.rotor4ring);
|
||||
ring4.setAdapter(adapters[3]);
|
||||
ring4.setSelection(action.getFourthValueFromBundle());
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(main);
|
||||
builder.setTitle(R.string.title_ring_setting);
|
||||
builder.setView(ringSettingsView)
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(R.string.dialog_positive, new DialogInterface.OnClickListener()
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int id)
|
||||
{
|
||||
action.firstSpinnerItemSelected(ring1.getSelectedItemPosition());
|
||||
action.secondSpinnerItemSelected(ring2.getSelectedItemPosition());
|
||||
action.thirdSpinnerItemSelected(ring3.getSelectedItemPosition());
|
||||
action.fourthSpinnerItemSelected(ring4.getSelectedItemPosition());
|
||||
String message = String.format(main.getResources().getString(
|
||||
R.string.dialog_ring_settings_success),
|
||||
(ring1.getSelectedItemPosition()+1) + ", " +
|
||||
(ring2.getSelectedItemPosition()+1) + ", " +
|
||||
(ring3.getSelectedItemPosition()+1) + ", " +
|
||||
(ring4.getSelectedItemPosition()+1));
|
||||
main.onDialogFinished(stateBundle);
|
||||
Toast.makeText(main, message, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.dialog_negative, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
dialog.cancel();
|
||||
Toast.makeText(main, R.string.dialog_abort,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}).show();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DialogBuilder for 4 Spinners and ringSettingRotor1-4
|
||||
*/
|
||||
public static class RingSettingsDialogBuilderRotRotRotRot extends RingSettingsDialogBuilderRotRotRotRef
|
||||
{
|
||||
@Override
|
||||
public void createRingSettingsDialog(final EnigmaStateBundle state) {
|
||||
this.showDialog(state,
|
||||
new ArrayAdapter[]{
|
||||
createAdapter1_26(),
|
||||
createAdapter1_26(),
|
||||
createAdapter1_26(),
|
||||
createAdapter1_26()},
|
||||
new int[]{
|
||||
R.string.hint_rotor1,
|
||||
R.string.hint_rotor2,
|
||||
R.string.hint_rotor3,
|
||||
R.string.hint_thin_rotor},
|
||||
new Actions4(state) {
|
||||
|
||||
@Override
|
||||
protected void firstSpinnerItemSelected(int pos) {
|
||||
state.setRingSettingRotor1(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void secondSpinnerItemSelected(int pos) {
|
||||
state.setRingSettingRotor2(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void thirdSpinnerItemSelected(int pos) {
|
||||
state.setRingSettingRotor3(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getFirstValueFromBundle() {
|
||||
return state.getRingSettingRotor1();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSecondValueFromBundle() {
|
||||
return state.getRingSettingRotor2();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getThirdValueFromBundle() {
|
||||
return state.getRingSettingRotor3();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fourthSpinnerItemSelected(int pos) {
|
||||
state.setRingSettingRotor4(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getFourthValueFromBundle() {
|
||||
return state.getRingSettingRotor4();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract class that defines how Spinners correspond to the EnigmaStateBundle
|
||||
*/
|
||||
public static abstract class Actions
|
||||
{
|
||||
final EnigmaStateBundle stateBundle;
|
||||
public Actions(EnigmaStateBundle bundle)
|
||||
{
|
||||
this.stateBundle = bundle;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract class that defines, how the 3 Spinners correspond to 3 values in the
|
||||
* EnigmaStateBundle
|
||||
*/
|
||||
public static abstract class Actions3 extends Actions
|
||||
{
|
||||
public Actions3(EnigmaStateBundle bundle)
|
||||
{
|
||||
super(bundle);
|
||||
}
|
||||
protected abstract void firstSpinnerItemSelected(int pos);
|
||||
protected abstract void secondSpinnerItemSelected(int pos);
|
||||
protected abstract void thirdSpinnerItemSelected(int pos);
|
||||
protected abstract int getFirstValueFromBundle();
|
||||
protected abstract int getSecondValueFromBundle();
|
||||
protected abstract int getThirdValueFromBundle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extension of Actions3 which forces implementing classes to implement methods for the fourth
|
||||
* Spinner.
|
||||
*/
|
||||
public static abstract class Actions4 extends Actions3
|
||||
{
|
||||
public Actions4(EnigmaStateBundle bundle)
|
||||
{
|
||||
super(bundle);
|
||||
}
|
||||
protected abstract void fourthSpinnerItemSelected(int pos);
|
||||
protected abstract int getFourthValueFromBundle();
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 9.8 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 23 KiB |
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content">
|
||||
<item android:state_pressed="true" >
|
||||
<shape>
|
||||
<solid
|
||||
android:color="#ea138f" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#222222" />
|
||||
<corners
|
||||
android:radius="4dp" />
|
||||
<padding
|
||||
android:left="10dp"
|
||||
android:top="10dp"
|
||||
android:right="10dp"
|
||||
android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<gradient
|
||||
android:startColor="#810e41"
|
||||
android:endColor="#930e52"
|
||||
android:angle="270" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#52082e" />
|
||||
<corners
|
||||
android:radius="4dp" />
|
||||
<padding
|
||||
android:left="10dp"
|
||||
android:top="10dp"
|
||||
android:right="10dp"
|
||||
android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content">
|
||||
<item android:state_pressed="true" >
|
||||
<shape>
|
||||
<solid
|
||||
android:color="#444552" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#222222" />
|
||||
<corners
|
||||
android:radius="4dp" />
|
||||
<padding
|
||||
android:left="10dp"
|
||||
android:top="10dp"
|
||||
android:right="10dp"
|
||||
android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<gradient
|
||||
android:startColor="#23262e"
|
||||
android:endColor="#24252e"
|
||||
android:angle="270" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#181719" />
|
||||
<corners
|
||||
android:radius="4dp" />
|
||||
<padding
|
||||
android:left="10dp"
|
||||
android:top="10dp"
|
||||
android:right="10dp"
|
||||
android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content">
|
||||
<item android:state_pressed="true" >
|
||||
<shape>
|
||||
<solid
|
||||
android:color="#b94b52e4" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#222222" />
|
||||
<corners
|
||||
android:radius="4dp" />
|
||||
<padding
|
||||
android:left="10dp"
|
||||
android:top="10dp"
|
||||
android:right="10dp"
|
||||
android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<gradient
|
||||
android:startColor="#b94b52e4"
|
||||
android:endColor="#a74e55ff"
|
||||
android:angle="270" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#1e2153" />
|
||||
<corners
|
||||
android:radius="4dp" />
|
||||
<padding
|
||||
android:left="10dp"
|
||||
android:top="10dp"
|
||||
android:right="10dp"
|
||||
android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content">
|
||||
<item android:state_pressed="true" >
|
||||
<shape>
|
||||
<solid
|
||||
android:color="#de9307" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#222222" />
|
||||
<corners
|
||||
android:radius="4dp" />
|
||||
<padding
|
||||
android:left="10dp"
|
||||
android:top="10dp"
|
||||
android:right="10dp"
|
||||
android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<gradient
|
||||
android:startColor="#864f07"
|
||||
android:endColor="#9c6007"
|
||||
android:angle="270" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#462606" />
|
||||
<corners
|
||||
android:radius="4dp" />
|
||||
<padding
|
||||
android:left="10dp"
|
||||
android:top="10dp"
|
||||
android:right="10dp"
|
||||
android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content">
|
||||
<item android:state_pressed="true" >
|
||||
<shape>
|
||||
<solid
|
||||
android:color="#15dbdc" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#222222" />
|
||||
<corners
|
||||
android:radius="4dp" />
|
||||
<padding
|
||||
android:left="10dp"
|
||||
android:top="10dp"
|
||||
android:right="10dp"
|
||||
android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<gradient
|
||||
android:startColor="#139e9f"
|
||||
android:endColor="#13aeaf"
|
||||
android:angle="270" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#115c5d" />
|
||||
<corners
|
||||
android:radius="4dp" />
|
||||
<padding
|
||||
android:left="10dp"
|
||||
android:top="10dp"
|
||||
android:right="10dp"
|
||||
android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content">
|
||||
<item android:state_pressed="true" >
|
||||
<shape>
|
||||
<solid
|
||||
android:color="#c895ad" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#222222" />
|
||||
<corners
|
||||
android:radius="4dp" />
|
||||
<padding
|
||||
android:left="10dp"
|
||||
android:top="10dp"
|
||||
android:right="10dp"
|
||||
android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<gradient
|
||||
android:startColor="#815f6b"
|
||||
android:endColor="#8e6a77"
|
||||
android:angle="270" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#53353f" />
|
||||
<corners
|
||||
android:radius="4dp" />
|
||||
<padding
|
||||
android:left="10dp"
|
||||
android:top="10dp"
|
||||
android:right="10dp"
|
||||
android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content">
|
||||
<item android:state_pressed="true" >
|
||||
<shape>
|
||||
<solid
|
||||
android:color="#6aff46" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#222222" />
|
||||
<corners
|
||||
android:radius="4dp" />
|
||||
<padding
|
||||
android:left="10dp"
|
||||
android:top="10dp"
|
||||
android:right="10dp"
|
||||
android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<gradient
|
||||
android:startColor="#54bb32"
|
||||
android:endColor="#56cc33"
|
||||
android:angle="270" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#3b7727" />
|
||||
<corners
|
||||
android:radius="4dp" />
|
||||
<padding
|
||||
android:left="10dp"
|
||||
android:top="10dp"
|
||||
android:right="10dp"
|
||||
android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content">
|
||||
<item android:state_pressed="true" >
|
||||
<shape>
|
||||
<solid
|
||||
android:color="#666670" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#222222" />
|
||||
<corners
|
||||
android:radius="4dp" />
|
||||
<padding
|
||||
android:left="10dp"
|
||||
android:top="10dp"
|
||||
android:right="10dp"
|
||||
android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<gradient
|
||||
android:startColor="#3f4046"
|
||||
android:endColor="#3c3d43"
|
||||
android:angle="270" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#181719" />
|
||||
<corners
|
||||
android:radius="4dp" />
|
||||
<padding
|
||||
android:left="10dp"
|
||||
android:top="10dp"
|
||||
android:right="10dp"
|
||||
android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content">
|
||||
<item android:state_pressed="true" >
|
||||
<shape>
|
||||
<solid
|
||||
android:color="#a4e82b" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#222222" />
|
||||
<corners
|
||||
android:radius="4dp" />
|
||||
<padding
|
||||
android:left="10dp"
|
||||
android:top="10dp"
|
||||
android:right="10dp"
|
||||
android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<gradient
|
||||
android:startColor="#4f7d1d"
|
||||
android:endColor="#5f8e1e"
|
||||
android:angle="270" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#365013" />
|
||||
<corners
|
||||
android:radius="4dp" />
|
||||
<padding
|
||||
android:left="10dp"
|
||||
android:top="10dp"
|
||||
android:right="10dp"
|
||||
android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
0
app/src/main/res/drawable/button.xml → app/src/main/res/drawable/button_orange.xml
Executable file → Normal file
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content">
|
||||
<item android:state_pressed="true" >
|
||||
<shape>
|
||||
<solid
|
||||
android:color="#95ff168e" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#222222" />
|
||||
<corners
|
||||
android:radius="4dp" />
|
||||
<padding
|
||||
android:left="10dp"
|
||||
android:top="10dp"
|
||||
android:right="10dp"
|
||||
android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<gradient
|
||||
android:startColor="#d1156d"
|
||||
android:endColor="#e5157f"
|
||||
android:angle="270" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#8c0e49" />
|
||||
<corners
|
||||
android:radius="4dp" />
|
||||
<padding
|
||||
android:left="10dp"
|
||||
android:top="10dp"
|
||||
android:right="10dp"
|
||||
android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content">
|
||||
<item android:state_pressed="true" >
|
||||
<shape>
|
||||
<solid
|
||||
android:color="#cf54ff" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#222222" />
|
||||
<corners
|
||||
android:radius="4dp" />
|
||||
<padding
|
||||
android:left="10dp"
|
||||
android:top="10dp"
|
||||
android:right="10dp"
|
||||
android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<gradient
|
||||
android:startColor="#9944c2"
|
||||
android:endColor="#de9944c2"
|
||||
android:angle="270" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#703290" />
|
||||
<corners
|
||||
android:radius="4dp" />
|
||||
<padding
|
||||
android:left="10dp"
|
||||
android:top="10dp"
|
||||
android:right="10dp"
|
||||
android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content">
|
||||
<item android:state_pressed="true" >
|
||||
<shape>
|
||||
<solid
|
||||
android:color="#ff4f52" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#222222" />
|
||||
<corners
|
||||
android:radius="4dp" />
|
||||
<padding
|
||||
android:left="10dp"
|
||||
android:top="10dp"
|
||||
android:right="10dp"
|
||||
android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<gradient
|
||||
android:startColor="#d9ef241e"
|
||||
android:endColor="#bdef3f3f"
|
||||
android:angle="270" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#5a1717" />
|
||||
<corners
|
||||
android:radius="4dp" />
|
||||
<padding
|
||||
android:left="10dp"
|
||||
android:top="10dp"
|
||||
android:right="10dp"
|
||||
android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content">
|
||||
<item android:state_pressed="true" >
|
||||
<shape>
|
||||
<solid
|
||||
android:color="#cbfffc0f" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#222222" />
|
||||
<corners
|
||||
android:radius="4dp" />
|
||||
<padding
|
||||
android:left="10dp"
|
||||
android:top="10dp"
|
||||
android:right="10dp"
|
||||
android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<gradient
|
||||
android:startColor="#b7b40e"
|
||||
android:endColor="#d2cf0e"
|
||||
android:angle="270" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#5c5903" />
|
||||
<corners
|
||||
android:radius="4dp" />
|
||||
<padding
|
||||
android:left="10dp"
|
||||
android:top="10dp"
|
||||
android:right="10dp"
|
||||
android:bottom="10dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 82 KiB |
After Width: | Height: | Size: 42 KiB |
|
@ -0,0 +1,123 @@
|
|||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:id="@+id/lin_lay_names_1">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_reflector_position"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor3_position"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor2_position"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor1_position"/>
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:id="@+id/lin_lay_1"
|
||||
android:layout_below="@+id/lin_lay_names_1">
|
||||
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/reflector_position">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor3position">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor2position">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor1position">
|
||||
</Spinner>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/lin_lay_1"
|
||||
android:layout_above="@+id/buttons_lay"
|
||||
android:id="@+id/text_layer">
|
||||
<EditText
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".50"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/input"
|
||||
android:inputType="textNoSuggestions|textMultiLine"
|
||||
android:hint="@string/hint_enigma_type_here" />
|
||||
|
||||
<EditText
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".50"
|
||||
android:layout_height="match_parent"
|
||||
android:inputType="none"
|
||||
android:textIsSelectable="true"
|
||||
android:id="@+id/output"
|
||||
android:hint="@string/hint_enigma_code"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/buttons_lay"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="50"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/button_reflector"
|
||||
android:text="@string/hint_enigma_reflector_wiring"
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle"/>
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="50"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/button_crypt"
|
||||
android:onClick="doCrypto"
|
||||
android:text="@string/button_crypt"
|
||||
android:background="@drawable/button_orange"
|
||||
tools:ignore="ButtonStyle"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
|
@ -0,0 +1,144 @@
|
|||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:id="@+id/lin_lay_names_1">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor3"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor2"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor1"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_reflector_position"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor3_position"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor2_position"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor1_position"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:id="@+id/lin_lay_1"
|
||||
android:layout_below="@+id/lin_lay_names_1">
|
||||
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor3">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor2">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor1">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/reflector_position">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor3position">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor2position">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor1position">
|
||||
</Spinner>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/lin_lay_1"
|
||||
android:layout_above="@+id/buttons_lay"
|
||||
android:id="@+id/text_layer">
|
||||
<EditText
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".50"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/input"
|
||||
android:inputType="textNoSuggestions|textMultiLine"
|
||||
android:hint="@string/hint_enigma_type_here" />
|
||||
|
||||
<EditText
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".50"
|
||||
android:layout_height="match_parent"
|
||||
android:inputType="none"
|
||||
android:textIsSelectable="true"
|
||||
android:id="@+id/output"
|
||||
android:hint="@string/hint_enigma_code"/>
|
||||
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/buttons_lay"
|
||||
android:layout_alignParentBottom="true">
|
||||
<Button
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/button_crypt"
|
||||
android:onClick="doCrypto"
|
||||
android:text="@string/button_crypt"
|
||||
android:background="@drawable/button_orange"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
|
@ -119,41 +119,13 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Plugboard and button-->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/buttons_lay"
|
||||
android:layout_below="@+id/lin_lay_1"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<EditText
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="75"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/plugboard"
|
||||
android:hint="@string/hint_enigma_plugboard">
|
||||
|
||||
</EditText>
|
||||
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="25"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/button_crypt"
|
||||
android:onClick="doCrypto"
|
||||
android:text="@string/button_crypt"
|
||||
android:background="@drawable/button"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Textboxes for input and output -->
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/buttons_lay"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_below="@+id/lin_lay_1"
|
||||
android:layout_above="@id/buttons_lay"
|
||||
android:id="@+id/text_layer">
|
||||
|
||||
<EditText
|
||||
|
@ -174,4 +146,34 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/buttons_lay"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="50"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="bottom"
|
||||
android:text="@string/title_plugboard_dialog"
|
||||
android:background="@drawable/button_grey"
|
||||
android:id="@+id/button_plugboard"
|
||||
tools:ignore="ButtonStyle"/>
|
||||
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="50"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="bottom"
|
||||
android:id="@+id/button_crypt"
|
||||
android:onClick="doCrypto"
|
||||
android:text="@string/button_crypt"
|
||||
android:background="@drawable/button_orange"
|
||||
tools:ignore="ButtonStyle"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
|
|
@ -144,41 +144,13 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Plugboard and button-->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/buttons_lay"
|
||||
android:layout_below="@+id/lin_lay_1"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<EditText
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="75"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/plugboard"
|
||||
android:hint="@string/hint_enigma_plugboard">
|
||||
|
||||
</EditText>
|
||||
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="25"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/button_crypt"
|
||||
android:onClick="doCrypto"
|
||||
android:text="@string/button_crypt"
|
||||
android:background="@drawable/button"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Textboxes for input and output -->
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/buttons_lay"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_below="@+id/lin_lay_1"
|
||||
android:layout_above="@id/buttons_lay"
|
||||
android:id="@+id/text_layer">
|
||||
|
||||
<EditText
|
||||
|
@ -198,5 +170,32 @@
|
|||
android:hint="@string/hint_enigma_code"/>
|
||||
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/buttons_lay"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="50"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/button_plugboard"
|
||||
android:text="@string/title_plugboard_dialog"
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle"/>
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="50"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/button_crypt"
|
||||
android:onClick="doCrypto"
|
||||
android:text="@string/button_crypt"
|
||||
android:background="@drawable/button_orange"
|
||||
tools:ignore="ButtonStyle"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</RelativeLayout>
|
||||
|
|
|
@ -0,0 +1,254 @@
|
|||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:id="@+id/first_row">
|
||||
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/Q"
|
||||
android:text="Q: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/W"
|
||||
android:text="W: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/E"
|
||||
android:text="E: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/R"
|
||||
android:text="R: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/T"
|
||||
android:text="T: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/Z"
|
||||
android:text="Z: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/U"
|
||||
android:text="U: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/I"
|
||||
android:text="I: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/O"
|
||||
android:text="O: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_below="@id/first_row"
|
||||
android:id="@+id/second_row">
|
||||
|
||||
<android.support.v4.widget.Space
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/A"
|
||||
android:text="A: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/S"
|
||||
android:text="S: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/D"
|
||||
android:text="D: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/F"
|
||||
android:text="F: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/G"
|
||||
android:text="G: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/H"
|
||||
android:text="H: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/J"
|
||||
android:text="J: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/K"
|
||||
android:text="K: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="HardcodedText" />
|
||||
<android.support.v4.widget.Space
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_below="@id/second_row"
|
||||
android:id="@+id/third_row">
|
||||
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/P"
|
||||
android:text="P: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/Y"
|
||||
android:text="Y: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/X"
|
||||
android:text="X: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/C"
|
||||
android:text="C: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/V"
|
||||
android:text="V: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/B"
|
||||
android:text="B: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/N"
|
||||
android:text="N: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/M"
|
||||
android:text="M: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/L"
|
||||
android:text="L: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
|
@ -0,0 +1,88 @@
|
|||
<ScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:id="@+id/ringstellung_layout_hint">
|
||||
|
||||
<!-- About Enigma. -->
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@android:style/TextAppearance.Medium"
|
||||
android:text="@string/title_about_dialog"
|
||||
android:id="@+id/title_section_app_description_text"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@android:style/TextAppearance.Holo.Small"
|
||||
android:text="@string/description_text"
|
||||
android:id="@+id/about_app_description"/>
|
||||
|
||||
<!-- About Version -->
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@android:style/TextAppearance.Holo.Medium"
|
||||
android:text="@string/action_version"
|
||||
android:id="@+id/title_section_version"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@android:style/TextAppearance.Holo.Small"
|
||||
android:id="@+id/about_version_section"/>
|
||||
|
||||
<!-- About How To -->
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@android:style/TextAppearance.Holo.Medium"
|
||||
android:text="@string/title_section_how_to_use"
|
||||
android:id="@+id/title_section_how_to_use"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@android:style/TextAppearance.Holo.Small"
|
||||
android:text="@string/section_how_to_use"
|
||||
android:id="@+id/section_how_to_use"/>
|
||||
|
||||
<!-- About Developer -->
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@android:style/TextAppearance.Holo.Medium"
|
||||
android:text="@string/title_section_developer"
|
||||
android:id="@+id/title_section_developer_text"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@android:style/TextAppearance.Holo.Small"
|
||||
android:text="@string/section_developer"
|
||||
android:id="@+id/about_developer_section"/>
|
||||
|
||||
<!-- About Disclaimer -->
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@android:style/TextAppearance.Holo.Medium"
|
||||
android:text="@string/title_section_disclaimer"
|
||||
android:id="@+id/title_section_disclaimer_text"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@android:style/TextAppearance.Holo.Small"
|
||||
android:text="@string/section_disclaimer"
|
||||
android:id="@+id/about_disclaimer_section"/>
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
|
@ -0,0 +1,123 @@
|
|||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:id="@+id/lin_lay_names_2">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_reflector_position"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor3_position"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor2_position"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor1_position"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:id="@+id/lin_lay_2"
|
||||
android:layout_below="@+id/lin_lay_names_2">
|
||||
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/reflector_position">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor3position">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor2position">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor1position">
|
||||
</Spinner>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/lin_lay_2"
|
||||
android:layout_above="@+id/buttons_lay"
|
||||
android:id="@+id/text_layer">
|
||||
<EditText
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".50"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/input"
|
||||
android:inputType="textNoSuggestions|textMultiLine"
|
||||
android:hint="@string/hint_enigma_type_here" />
|
||||
|
||||
<EditText
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".50"
|
||||
android:layout_height="match_parent"
|
||||
android:inputType="none"
|
||||
android:textIsSelectable="true"
|
||||
android:id="@+id/output"
|
||||
android:hint="@string/hint_enigma_code"/>
|
||||
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/buttons_lay"
|
||||
android:layout_alignParentBottom="true">
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="50"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/button_reflector"
|
||||
android:text="@string/hint_enigma_reflector_wiring"
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle"/>
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="50"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/button_crypt"
|
||||
android:onClick="doCrypto"
|
||||
android:text="@string/button_crypt"
|
||||
android:background="@drawable/button_orange"
|
||||
tools:ignore="ButtonStyle"/>
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
|
@ -0,0 +1,162 @@
|
|||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:id="@+id/lin_lay_names_1">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor3"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor2"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor1"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:id="@+id/lin_lay_1"
|
||||
android:layout_below="@+id/lin_lay_names_1">
|
||||
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor3">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor2">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor1">
|
||||
</Spinner>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_below="@+id/lin_lay_1"
|
||||
android:id="@+id/lin_lay_names_2">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_reflector_position"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor3_position"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor2_position"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor1_position"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:id="@+id/lin_lay_2"
|
||||
android:layout_below="@+id/lin_lay_names_2">
|
||||
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/reflector_position">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor3position">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor2position">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor1position">
|
||||
</Spinner>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/lin_lay_2"
|
||||
android:layout_above="@+id/buttons_lay"
|
||||
android:id="@+id/text_layer">
|
||||
<EditText
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".50"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/input"
|
||||
android:inputType="textNoSuggestions|textMultiLine"
|
||||
android:hint="@string/hint_enigma_type_here" />
|
||||
|
||||
<EditText
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".50"
|
||||
android:layout_height="match_parent"
|
||||
android:inputType="none"
|
||||
android:textIsSelectable="true"
|
||||
android:id="@+id/output"
|
||||
android:hint="@string/hint_enigma_code"/>
|
||||
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/buttons_lay"
|
||||
android:layout_alignParentBottom="true">
|
||||
<Button
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/button_crypt"
|
||||
android:onClick="doCrypto"
|
||||
android:text="@string/button_crypt"
|
||||
android:background="@drawable/button_orange"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
|
@ -78,7 +78,7 @@
|
|||
android:layout_below="@+id/lin_lay_1"
|
||||
android:id="@+id/lin_lay_names_2">
|
||||
|
||||
<Space
|
||||
<android.support.v4.widget.Space
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".125"
|
||||
android:layout_height="wrap_content" />
|
||||
|
@ -99,7 +99,7 @@
|
|||
android:layout_weight=".25"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor1_position"/>
|
||||
<Space
|
||||
<android.support.v4.widget.Space
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".125"
|
||||
android:layout_height="wrap_content" />
|
||||
|
@ -112,7 +112,7 @@
|
|||
android:id="@+id/lin_lay_2"
|
||||
android:layout_below="@+id/lin_lay_names_2">
|
||||
|
||||
<Space
|
||||
<android.support.v4.widget.Space
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".125"
|
||||
android:layout_height="wrap_content" />
|
||||
|
@ -134,24 +134,16 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor1position">
|
||||
</Spinner>
|
||||
<Space
|
||||
<android.support.v4.widget.Space
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".125"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
|
||||
<EditText
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="30pt"
|
||||
android:id="@+id/plugboard"
|
||||
android:inputType="textNoSuggestions"
|
||||
android:hint="@string/hint_enigma_plugboard"
|
||||
android:layout_below="@+id/lin_lay_2"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/plugboard"
|
||||
android:layout_below="@+id/lin_lay_2"
|
||||
android:layout_above="@+id/buttons_lay"
|
||||
android:id="@+id/text_layer">
|
||||
<EditText
|
||||
|
@ -178,13 +170,22 @@
|
|||
android:id="@+id/buttons_lay"
|
||||
android:layout_alignParentBottom="true">
|
||||
<Button
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="50"
|
||||
android:text="@string/title_plugboard_dialog"
|
||||
android:id="@+id/button_plugboard"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle"/>
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="50"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/button_crypt"
|
||||
android:onClick="doCrypto"
|
||||
android:text="@string/button_crypt"
|
||||
android:background="@drawable/button"
|
||||
/>
|
||||
android:background="@drawable/button_orange"
|
||||
tools:ignore="ButtonStyle"/>
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:id="@+id/lin_lay_names_1">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor3"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor2"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor1"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:id="@+id/lin_lay_1"
|
||||
android:layout_below="@+id/lin_lay_names_1">
|
||||
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor3">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor2">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor1">
|
||||
</Spinner>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_below="@+id/lin_lay_1"
|
||||
android:id="@+id/lin_lay_names_2">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_reflector_position"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor3_position"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor2_position"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hint_rotor1_position"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:id="@+id/lin_lay_2"
|
||||
android:layout_below="@+id/lin_lay_names_2">
|
||||
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/reflector_position">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor3position">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor2position">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor1position">
|
||||
</Spinner>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/lin_lay_2"
|
||||
android:layout_above="@+id/buttons_lay"
|
||||
android:id="@+id/text_layer">
|
||||
<EditText
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".50"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/input"
|
||||
android:inputType="textNoSuggestions|textMultiLine"
|
||||
android:hint="@string/hint_enigma_type_here" />
|
||||
|
||||
<EditText
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".50"
|
||||
android:layout_height="match_parent"
|
||||
android:inputType="none"
|
||||
android:textIsSelectable="true"
|
||||
android:id="@+id/output"
|
||||
android:hint="@string/hint_enigma_code"/>
|
||||
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/buttons_lay"
|
||||
android:layout_alignParentBottom="true">
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="50"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/button_reflector"
|
||||
android:text="@string/hint_enigma_reflector_wiring"
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle"/>
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="50"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/button_crypt"
|
||||
android:onClick="doCrypto"
|
||||
android:text="@string/button_crypt"
|
||||
android:background="@drawable/button_orange"
|
||||
tools:ignore="ButtonStyle"/>
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
|
@ -146,18 +146,10 @@
|
|||
</Spinner>
|
||||
</LinearLayout>
|
||||
|
||||
<EditText
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="30pt"
|
||||
android:id="@+id/plugboard"
|
||||
android:inputType="textNoSuggestions"
|
||||
android:hint="@string/hint_enigma_plugboard"
|
||||
android:layout_below="@+id/lin_lay_2"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/plugboard"
|
||||
android:layout_below="@+id/lin_lay_2"
|
||||
android:layout_above="@+id/buttons_lay"
|
||||
android:id="@+id/text_layer">
|
||||
<EditText
|
||||
|
@ -184,13 +176,23 @@
|
|||
android:id="@+id/buttons_lay"
|
||||
android:layout_alignParentBottom="true">
|
||||
<Button
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="50"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/button_plugboard"
|
||||
android:text="@string/title_plugboard_dialog"
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle"
|
||||
/>
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="50"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/button_crypt"
|
||||
android:onClick="doCrypto"
|
||||
android:text="@string/button_crypt"
|
||||
android:background="@drawable/button"
|
||||
/>
|
||||
android:background="@drawable/button_orange"
|
||||
tools:ignore="ButtonStyle"/>
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
<RelativeLayout
|
||||
<ScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp">
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -18,14 +14,14 @@
|
|||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@android:style/TextAppearance.Holo.Medium"
|
||||
android:textAppearance="@android:style/TextAppearance.Medium"
|
||||
android:text="@string/title_about_dialog"
|
||||
android:id="@+id/title_section_app_description_text"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@android:style/TextAppearance.Holo.Small"
|
||||
android:textAppearance="@android:style/TextAppearance.Small"
|
||||
android:text="@string/description_text"
|
||||
android:id="@+id/about_app_description"/>
|
||||
|
||||
|
@ -33,29 +29,28 @@
|
|||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@android:style/TextAppearance.Holo.Medium"
|
||||
android:textAppearance="@android:style/TextAppearance.Medium"
|
||||
android:text="@string/action_version"
|
||||
android:id="@+id/title_section_version"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@android:style/TextAppearance.Holo.Small"
|
||||
android:text="@string/version"
|
||||
android:textAppearance="@android:style/TextAppearance.Small"
|
||||
android:id="@+id/about_version_section"/>
|
||||
|
||||
<!-- About How To -->
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@android:style/TextAppearance.Holo.Medium"
|
||||
android:textAppearance="@android:style/TextAppearance.Medium"
|
||||
android:text="@string/title_section_how_to_use"
|
||||
android:id="@+id/title_section_how_to_use"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@android:style/TextAppearance.Holo.Small"
|
||||
android:textAppearance="@android:style/TextAppearance.Small"
|
||||
android:text="@string/section_how_to_use"
|
||||
android:id="@+id/section_how_to_use"/>
|
||||
|
||||
|
@ -63,14 +58,14 @@
|
|||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@android:style/TextAppearance.Holo.Medium"
|
||||
android:textAppearance="@android:style/TextAppearance.Medium"
|
||||
android:text="@string/title_section_developer"
|
||||
android:id="@+id/title_section_developer_text"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@android:style/TextAppearance.Holo.Small"
|
||||
android:textAppearance="@android:style/TextAppearance.Small"
|
||||
android:text="@string/section_developer"
|
||||
android:id="@+id/about_developer_section"/>
|
||||
|
||||
|
@ -78,18 +73,16 @@
|
|||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@android:style/TextAppearance.Holo.Medium"
|
||||
android:textAppearance="@android:style/TextAppearance.Medium"
|
||||
android:text="@string/title_section_disclaimer"
|
||||
android:id="@+id/title_section_disclaimer_text"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@android:style/TextAppearance.Holo.Small"
|
||||
android:textAppearance="@android:style/TextAppearance.Small"
|
||||
android:text="@string/section_disclaimer"
|
||||
android:id="@+id/about_disclaimer_section"/>
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
||||
</RelativeLayout>
|
||||
</ScrollView>
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp">
|
||||
<EditText
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/hint_configuration"
|
||||
android:id="@+id/passphrase"/>
|
||||
</LinearLayout>
|
|
@ -0,0 +1,298 @@
|
|||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:id="@+id/first_row">
|
||||
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/Q"
|
||||
android:text="Q: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/W"
|
||||
android:text="W: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/E"
|
||||
android:text="E: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/R"
|
||||
android:text="R: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/T"
|
||||
android:text="T: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_below="@id/first_row"
|
||||
android:id="@+id/second_row">
|
||||
|
||||
<android.support.v4.widget.Space
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/Z"
|
||||
android:text="Z: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/U"
|
||||
android:text="U: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/I"
|
||||
android:text="I: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/O"
|
||||
android:text="O: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="HardcodedText" />
|
||||
<android.support.v4.widget.Space
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_below="@id/second_row"
|
||||
android:id="@+id/third_row">
|
||||
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/A"
|
||||
android:text="A: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/S"
|
||||
android:text="S: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/D"
|
||||
android:text="D: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/F"
|
||||
android:text="F: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/G"
|
||||
android:text="G: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_below="@id/third_row"
|
||||
android:id="@+id/fourth_row">
|
||||
|
||||
<android.support.v4.widget.Space
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/H"
|
||||
android:text="H: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/J"
|
||||
android:text="J: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/K"
|
||||
android:text="K: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/P"
|
||||
android:text="P: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="HardcodedText" />
|
||||
<android.support.v4.widget.Space
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_below="@id/fourth_row"
|
||||
android:id="@+id/fifth_row">
|
||||
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/Y"
|
||||
android:text="Y: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/X"
|
||||
android:text="X: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/C"
|
||||
android:text="C: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/V"
|
||||
android:text="V: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/B"
|
||||
android:text="B: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="ButtonStyle,HardcodedText" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_below="@id/fifth_row"
|
||||
android:id="@+id/sixth_row">
|
||||
|
||||
<android.support.v4.widget.Space
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="2"
|
||||
android:layout_height="wrap_content" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/N"
|
||||
android:text="N: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/M"
|
||||
android:text="M: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="HardcodedText" />
|
||||
<Button
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:id="@+id/L"
|
||||
android:text="L: "
|
||||
android:background="@drawable/button_grey"
|
||||
tools:ignore="HardcodedText" />
|
||||
<android.support.v4.widget.Space
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="2"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
12
app/src/main/res/layout/dialog_ringsettings_i_m3.xml → app/src/main/res/layout/dialog_ringsettings_3.xml
Executable file → Normal file
|
@ -13,17 +13,17 @@
|
|||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="33"
|
||||
android:text="@string/hint_rotor3"
|
||||
android:id="@+id/dialog_text_rotor3"
|
||||
android:layout_height="wrap_content"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="33"
|
||||
android:text="@string/hint_rotor2"
|
||||
android:id="@+id/dialog_text_rotor2"
|
||||
android:layout_height="wrap_content"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="33"
|
||||
android:text="@string/hint_rotor1"
|
||||
android:id="@+id/dialog_text_rotor1"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
@ -37,19 +37,19 @@
|
|||
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".33"
|
||||
android:layout_weight="33"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor3ring">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".33"
|
||||
android:layout_weight="33"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor2ring">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight=".33"
|
||||
android:layout_weight="33"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor1ring">
|
||||
</Spinner>
|
35
app/src/main/res/layout/dialog_ringsettings_m4.xml → app/src/main/res/layout/dialog_ringsettings_4.xml
Executable file → Normal file
|
@ -8,60 +8,63 @@
|
|||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/ringsettings_layout_hint">
|
||||
android:id="@+id/ringstellung_layout_hint">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="25"
|
||||
android:text="@string/hint_thin_rotor"
|
||||
android:layout_weight="33"
|
||||
android:id="@+id/dialog_text_rotor4"
|
||||
android:layout_height="wrap_content"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="25"
|
||||
android:text="@string/hint_rotor3"
|
||||
android:layout_weight="33"
|
||||
android:id="@+id/dialog_text_rotor3"
|
||||
android:layout_height="wrap_content"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="25"
|
||||
android:text="@string/hint_rotor2"
|
||||
android:layout_weight="33"
|
||||
android:id="@+id/dialog_text_rotor2"
|
||||
android:layout_height="wrap_content"/>
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="25"
|
||||
android:text="@string/hint_rotor1"
|
||||
android:layout_weight="33"
|
||||
android:id="@+id/dialog_text_rotor1"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/ringsettings_layout_hint"
|
||||
android:id="@+id/ringsettings_layout">
|
||||
android:layout_below="@id/ringstellung_layout_hint"
|
||||
android:id="@+id/ringstellung_layout">
|
||||
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="25"
|
||||
android:layout_weight="33"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor4ring">
|
||||
</Spinner>
|
||||
</Spinner>
|
||||
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="25"
|
||||
android:layout_weight="33"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor3ring">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="25"
|
||||
android:layout_weight="33"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor2ring">
|
||||
</Spinner>
|
||||
<Spinner
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="25"
|
||||
android:layout_weight="33"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/rotor1ring">
|
||||
</Spinner>
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/dialog_two_options_lay">
|
||||
<Button
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/dialog_two_options_1"/>
|
||||
|
||||
<Button
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/dialog_two_options_2"/>
|
||||
|
||||
</LinearLayout>
|
|
@ -0,0 +1,23 @@
|
|||
<ScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:paddingStart="5dp"
|
||||
android:paddingEnd="5dp">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@android:style/TextAppearance.Medium"
|
||||
android:id="@+id/dialog_whats_new_header"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@android:style/TextAppearance.Small"
|
||||
android:id="@+id/dialog_whats_new_details"/>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
|
@ -1,26 +1,55 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:context=".MainActivity" >
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:context=".MainActivity"
|
||||
tools:ignore="UnusedAttribute">
|
||||
|
||||
<item android:id="@+id/action_reset"
|
||||
<!-- RESET -->
|
||||
<item
|
||||
android:id="@+id/action_reset"
|
||||
android:orderInCategory="96"
|
||||
android:showAsAction="ifRoom"
|
||||
android:title="@string/action_reset" />
|
||||
<item android:id="@+id/action_send"
|
||||
android:title="@string/action_reset"/>
|
||||
<!-- SEND -->
|
||||
<item
|
||||
android:id="@+id/action_send_message"
|
||||
android:icon="@drawable/ic_send_white_48dp"
|
||||
android:orderInCategory="97"
|
||||
android:showAsAction="always"
|
||||
android:title="@string/action_send"
|
||||
android:icon="@drawable/ic_send_white_48dp"/>
|
||||
<item android:id="@+id/action_choose_ringstellung"
|
||||
android:title="@string/action_choose_ringsettings"
|
||||
android:title="@string/action_send"/>
|
||||
<!-- RINGSETTING -->
|
||||
<item
|
||||
android:id="@+id/action_choose_ringsetting"
|
||||
android:orderInCategory="98"
|
||||
android:showAsAction="never" />
|
||||
<item android:id="@+id/action_settings"
|
||||
android:title="@string/action_settings"
|
||||
android:orderInCategory="99"
|
||||
android:showAsAction="never" />
|
||||
<item android:id="@+id/action_about"
|
||||
android:title="@string/title_action_about"
|
||||
android:orderInCategory="100"
|
||||
android:showAsAction="never" />
|
||||
android:showAsAction="ifRoom"
|
||||
android:title="@string/action_choose_ring_settings"/>
|
||||
<!-- SHARE CONFIGURATION -->
|
||||
<item
|
||||
android:id="@+id/action_share_configuration"
|
||||
android:orderInCategory="99"
|
||||
android:showAsAction="ifRoom"
|
||||
android:title="@string/action_share_configuration"/>
|
||||
<!-- RESTORE CONFIGURATION FROM QR OR ENTER SEED-->
|
||||
<item
|
||||
android:id="@+id/action_restore_configuration"
|
||||
android:orderInCategory="100"
|
||||
android:showAsAction="ifRoom"
|
||||
android:title="@string/action_restore_configuration"/>
|
||||
<!-- RANDOM -->
|
||||
<item
|
||||
android:id="@+id/action_random_configuration"
|
||||
android:orderInCategory="101"
|
||||
android:showAsAction="ifRoom"
|
||||
android:title="@string/action_random"/>
|
||||
<!-- SETTINGS -->
|
||||
<item
|
||||
android:id="@+id/action_settings"
|
||||
android:orderInCategory="102"
|
||||
android:showAsAction="ifRoom"
|
||||
android:title="@string/action_settings"/>
|
||||
<!-- ABOUT -->
|
||||
<item
|
||||
android:id="@+id/action_about"
|
||||
android:orderInCategory="103"
|
||||
android:showAsAction="ifRoom"
|
||||
android:title="@string/title_action_about"/>
|
||||
</menu>
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
#!/bin/sh
|
||||
# Converts the Inkscape icon file ic_launcher_web.svg to the launcher web & app png files.
|
||||
|
||||
PROJECT="/home/vanitas/Programmierung/androidstudio/EnigmAndroid/app"
|
||||
MAIN="${PROJECT}/src/main/"
|
||||
RES="${MAIN}res/"
|
||||
DRAWABLE="${RES}drawable"
|
||||
INPUT="${RES}icon.svg"
|
||||
|
||||
inkscape --shell <<COMMANDS
|
||||
--export-png "${RES}ic_launcher-web.png" -w 512 "${INPUT}"
|
||||
--export-png "${DRAWABLE}-mdpi/ic_launcher.png" -w 48 "${INPUT}"
|
||||
--export-png "${DRAWABLE}-hdpi/ic_launcher.png" -w 72 "${INPUT}"
|
||||
--export-png "${DRAWABLE}-xhdpi/ic_launcher.png" -w 96 "${INPUT}"
|
||||
--export-png "${DRAWABLE}-xxhdpi/ic_launcher.png" -w 144 "${INPUT}"
|
||||
--export-png "${DRAWABLE}-xxxhdpi/ic_launcher.png" -w 192 "${INPUT}"
|
||||
quit
|
||||
COMMANDS
|
|
@ -8,7 +8,8 @@
|
|||
<string name="description_text">EnigmAndroid ist die Implementation einer Simulation der Enigma Maschine.
|
||||
Die Enigma Maschine ist eine in den 1920er Jahren entwickelte Verschlüsselungsmaschine,
|
||||
die unter anderem im zweiten Weltkrieg von der deutschen Wehrmacht eingesetzt wurde,
|
||||
um geheime Nachrichten zu verschlüsseln. Dabei wird jeder einzelne Buchstabe elektronisch
|
||||
um geheime Nachrichten zu verschlüsseln. Es gab mehrere verschiedene Enigmamodelle.
|
||||
Zur Verschlüsselung wird jeder einzelne Buchstabe elektronisch
|
||||
durch eine Reihe von rotierbaren Walzen geleitet, sodass nach jedem Buchstaben ein anderes
|
||||
Verschlüsselungsalphabet genutzt wird (Polyalphabetische Substitution).
|
||||
Die Walzen konnte man aus einem Set von 5 Walzen wählen. Zusätzlich gab es ein Steckbrett, an dem
|
||||
|
@ -16,12 +17,18 @@
|
|||
</string>
|
||||
|
||||
<string name="title_section_how_to_use">Bedienungsanleitung</string>
|
||||
<string name="section_how_to_use">Um einen Text mit EnigmAndroid zu ver- oder entschlüsseln, tippen Sie den Klar- oder Geheimtext in das Feld \"Hier tippen\".
|
||||
Wählen Sie anschließend eine Umkehrwalze, sowie Walzen für die Plätze 1 bis 3 aus. Legen Sie außerdem die Startpositionen der Walzen fest.
|
||||
Zuletzt können Sie noch einige Steckerpaare auf dem Steckbrett festlegen. Tippen Sie dazu die gewünschten Paare mit Komma getrennt in das entsprechende Textfeld (zb. \"ab,cd\").
|
||||
Beachten Sie, dass Sie einen Stecker nicht doppelt nutzen dürfen.
|
||||
Optional können Sie auch noch die Ringstellung definieren. Öffnen Sie dazu das Optionsmenü und wählen Sie den Punkt \"Ringstellung\".
|
||||
Haben Sie alle Einstellungen getätigt klicken Sie auf den Button \"Ver-Entschlüsseln\".</string>
|
||||
<string name="section_how_to_use">Um einen Text mit EnigmAndroid zu ver- oder entschlüsseln, wählen Sie zunächst das entsprechende Maschinenmodell aus.
|
||||
Sie finden eine Liste, aus der Sie wählen können in den Einstellungen. Tippen Sie dann den Klar- oder Geheimtext in das Feld \"Hier tippen\".
|
||||
Wählen Sie anschließend je nach gewähltem Modell eine Umkehrwalze, sowie weitere Walzen aus. Legen Sie außerdem die Startpositionen der Walzen fest.
|
||||
Zuletzt können Sie ggf. noch einige Steckerpaare auf dem Steckbrett festlegen, oder die Verkabelung der Umkehrwalze ändern. Tippen Sie dazu den
|
||||
jeweiligen Button an und verbinden Sie die gewünschten Steckerpaare, indem Sie im sich öffnenden Dialog nacheinander jeweils zwei
|
||||
Stecker berühren. Falls sie eine Verbindung trennen möchten, klicken Sie einen der betroffenen Stecker doppelt an.
|
||||
Optional können Sie außerdem auch noch die Ringstellung definieren. Öffnen Sie dazu das Optionsmenü und wählen Sie den Punkt \"Ringstellung\".
|
||||
Haben Sie alle Einstellungen getätigt klicken Sie auf den Button \"Ver-Entschlüsseln\".
|
||||
Um die gewählte Konfiguration der Enigma Maschine per QR-Code zu teilen, wählen Sie den Eintrag \"Teile Konfiguration per QR-Code\" aus dem Optionsmenü.
|
||||
Um eine per QR-Code geteilte Konfiguration zu scannen, wählen Sie stattdessen den Eintrag \"Lese Konfiguration aus QR-Code\".
|
||||
Außerdem können Sie eine Konfiguration aus einem Schlüsselwort generieren, oder wiederherstellen, indem Sie dein Eintrag \"Konfiguration aus Schlüsselwort\"
|
||||
wählen und im erscheinenden Dialog entweder ein beliebiges Wort oder den Inhalt eines QR-Codes (\"EnigmAndroid/…\" eingeben.</string>
|
||||
|
||||
<string name="title_section_developer">Entwickler</string>
|
||||
<string name="section_developer">EnigmAndroid wird entwickelt von: \nPaul Schaub</string>
|
||||
|
|
|
@ -4,14 +4,15 @@
|
|||
<string name="app_name">EnigmAndroid</string>
|
||||
<string name="action_version">Version</string>
|
||||
<string name="action_reset">Zurücksetzen</string>
|
||||
<string name="action_random">Zufällige Konfiguration</string>
|
||||
<string name="action_restore_configuration">Konfiguration wiederherstellen</string>
|
||||
<string name="action_share_configuration">Konfiguration teilen</string>
|
||||
<string name="action_settings">Einstellungen</string>
|
||||
<string name="action_choose_ringsettings">Ringstellung</string>
|
||||
<string name="action_choose_ring_settings">Ringstellung</string>
|
||||
<string name="action_send">Senden</string>
|
||||
<string name="send_to">Senden an…</string>
|
||||
<string name="message_choose_ringsettings">Wähle die Ringstellungen für die Walzen:</string>
|
||||
<string name="hint_enigma_type_here">Hier Tippen</string>
|
||||
<string name="hint_enigma_code">Enigma-Code</string>
|
||||
<string name="hint_enigma_plugboard">Steckerbrett (AZ,BE…)</string>
|
||||
<string name="hint_rotor1">Walze 1</string>
|
||||
<string name="hint_rotor2">Walze 2</string>
|
||||
<string name="hint_rotor3">Walze 3</string>
|
||||
|
@ -20,17 +21,34 @@
|
|||
<string name="hint_rotor1_position">Position\nWalze 1</string>
|
||||
<string name="hint_rotor2_position">Position\nWalze 2</string>
|
||||
<string name="hint_rotor3_position">Position\nWalze 3</string>
|
||||
<string name="hint_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_configuration">Schlüsselwort/Konfiguration</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="dialog_positiv">OK</string>
|
||||
<string name="dialog_negativ">Abbrechen</string>
|
||||
<string name="dialog_ringsettings_success">Setze Ringe auf</string>
|
||||
<string name="dialog_ringsettings_abort">Keine Änderungen</string>
|
||||
<string name="message_reset">Enigma zurückgesetzt</string>
|
||||
<string name="error_no_valid_qr">Fehler: Kein korrekter EnigmAndroid QR-Code!</string>
|
||||
<string name="title_ring_setting">Ringstellungen</string>
|
||||
|
||||
<string name="title_plugboard_dialog">Steckbrett-\nVerbindungen</string>
|
||||
<string name="title_reflector_dialog">Verkabelung Umkehrwalze</string>
|
||||
|
||||
<string name="dialog_positive">OK</string>
|
||||
<string name="dialog_negative">Abbrechen</string>
|
||||
<string name="dialog_title_restore_configuration">Konfiguration wiederherstellen…</string>
|
||||
<string name="dialog_restore_code">…aus Text/Schlüsselwort</string>
|
||||
<string name="dialog_restore_qr">…aus QR-code</string>
|
||||
<string name="dialog_title_share_configuration">Konfiguration teilen…</string>
|
||||
<string name="dialog_share_qr">…per QR-code</string>
|
||||
<string name="dialog_share_code">…als kodierten Text</string>
|
||||
<string name="dialog_ring_settings_success">Setze Ringe auf %1$s.</string>
|
||||
<string name="dialog_reflector_set">Umkehrwalze verkabelt.</string>
|
||||
<string name="dialog_plugboard_set">Steckbrettverbindungen gesetzt.</string>
|
||||
<string name="dialog_passphrase_set">Konfiguration aus Schlüsselwort %1$s generiert.</string>
|
||||
<string name="dialog_passphrase_was_coded_state">Konfiguration aus Kodierung wiederhergestellt.</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>
|
||||
<string name="message_clipboard">In Zwischenablage kopiert</string>
|
||||
|
||||
</resources>
|
||||
|
|