You will write a program that encrypts and decrypts messages simulating a simplified version of the Enigma machine used by the Germans in WWII. The machine will be described in detail later, but here are a two key points:
~/$ java Comms 1 2 3 "###" encrypt BEAT#ARMY AFUGNRCD# ~/$ java Comms 1 2 3 "USN" encrypt BEAT#ARMY PUIVBFRSO ~/$ java Comms 1 2 3 "USN" decrypt PUIVBFRSO BEAT#ARMYIn the end, you should be able to decrypt the following message using the settings 1 2 3 "###":
XXMMJ#UBHRWSHYSSTGWIGMMMAKTFSWZD#PU#CZIQADCDQY#NHN#SJVJTKZVVHOZBABLYMWBWWLNGAWWXEBWNXQQBQQRNMJGYXRYBKISBBFHGOO
Polish mathematicians, followed by researchers at Bletchley Park, England (led by Alan Turing), built machines known as bombe (from the Polish "bomba kryptologiczna," or "cryptologic bomb") to run through the computation and allow for timely decryption of Nazi messages. This is hailed as one of the turning points of the war, and the first great success of computer science.
Out Simple Model of the Enigma
Enigma machines used interchangeable rotors that could be placed in
different orientations to obtain different substitution patterns. More
significantly, the rotors rotated after each character was encoded, changing
the substitution pattern and making the code very difficult to break. The
behavior of the rotating rotors can be modeled, in a simplified form, by a
device consisting of labeled, concentric rings. For example, the model below
has three rings labeled with the letters of the alphabet and '#' (representing
a space).
To encrypt a character using this model, find the character on the inner rotor (i.e., the inside ring) and note the character aligned with it on the outer rotor (i.e., the outside ring), then find that character on the middle rotor (i.e., the middle ring) and output the one aligned with it on the outer rotor. After a character is encrypted, turn the inner rotor clockwise one step. Whenever the inner rotor returns to its original orientation, the middle rotor turns once in lock-step, just like the odometer in a car.
For example, in this configuration the character 'A' would be encrypted as 'N', since 'A' on the inner rotor is aligned with 'H' on the outer rotor, and 'H' on the middle rotor is aligned with 'N' on the outer rotor. After performing this encryption, the inner rotor is rotated clockwise, so the letter 'A' would next be encrypted as 'D'.
Note that decrypting a message requires following the same steps, only in reverse (i.e., find the character on the outer rotor, note the character aligned with it on the middle rotor, find that character on the outer rotor, then output the character aligned with it on the inner rotor).
Real Enigma Machine
A standard enigma machines used three rotors. Special units had extra for added
complexity. You can see the rotors in the picture on the right.
A special codebook told the operators which rotors to use and how to orient them
to begin each message. The code changed at the same time every night.
The job of Bletchley Park was largely to figure out which three rotors were in use
that day. Once they did that, they could decode all German military traffic for the day.
The channel would 'go dark' again at midnight when the codes changed again.
Prior to encoding or decoding a message, the operator would put the three rotors in and set them to the problem starting position. To encode, they would type the plaintext message on the keyboard and read the output from the 'lampboard'. The lampboard is a set of letters in qwerty layout that light up. So pressing the 'A' in the example above would cause the letter 'N' to light up on the lampboard. Decoding was done in a similar manner.
The plugboard was an additional feature that added complexity to the encoding algorithm. It allowed the machine to swap two letters before encoding. This made decrypting an Enigma transmission by hand much more difficult, and required the use of machines to encode or decode.
cd ~ ← cd to your home directory mkdir share04 ← create new directory "share02" cd share04 ← cd to the new directory ~wcbrown/bin/cher m17xxxx m17xxxx ← use the alpha codes of the two partners. This makes the directory "shared"
~wcbrown/bin/git-initThis will create a git repository that you both can share. Note the output line that looks like
checkout the repo with: git clone ssh://mich302csd17u.academy.usna.edu/home/mids/m17xxxx/share04Save that! That's what you need to do to "checkout" or "clone" a copy of the repository.
git clone ssh://mich302csd17u.academy.usna.edu/home/mids/m17xxxx/share04if you do an
ls, you should see the
directory share04
has suddenly appeared. In it, you should find a README file.
Cd into the share04 directory. This is where
you will be working from now on!
Rotor to simulate the
workings of a single rotor, the class Enigma to
simulate the workings of an Enigma machine, and a
class Comms to manage the interface with the user.
Your work will proceed in four phases:
public class Rotor, and a list of public
method prototypes followed by { }.
Sync your repositories!
rotars: 3 1 5, init: "XYZ").
However, you'll have to do error handling,so that missing
command-line inputs or input text with characters outside the
allowed alphabet are caught and error messages are printed.
Along with this, you will be writing code to exhaustively test
the Rotor class based on the interface you've agreed upon.
This code should be in the static main of a class RotorTest.
When you sync your work and use your code to test Rotor class,
running this test code and passing those tests should mean you
are *really* confident that the Rotor class works right!
The other partner will work on implementing the Rotor class
based on the interface you've agreed upon. Along with this,
you'll put together (in the README file) a list of calls to
the Comms class that should test all the error
conditions the Comms class code is supposed to catch. For
example, "java Comms" should result in a usage
message. If when you get your code back together, the Comms
class passes all these test, you should be *really*
confident that the program works!
Work on the tests first, then commit and sync with your partner, then work on your implementations. Although you're working on separate things at separate terminals, you can still talk and help each other.
~/$ java Comms
usage: java Comms <inner#> <middle#> <outer#> "init" (encrypt|decrypt)
e.g. java Comms 4 2 3 "X#Y" encrypt
The rotors 1-5 are (this should be hardcoded into Comms as Strings!):
1. #GNUAHOVBIPWCJQXDKRYELSZFMT 2. #EJOTYCHMRWAFKPUZDINSXBGLQV 3. #BDFHJLNPRTVXZACEGIKMOQSUWY 4. #NWDKHGXZVRIFJBLMAOPSCYUTQE 5. #TGOWHLIFMCSZYRVXQABUPEJKND... which you are to interpret circularly, so that the last character loops around to the first. If you imagine that the first positition indicates the top spot on the rotor, then:
#GNUAHOVBIPWCJQXDKRYELSZFMT rotated one click clockwise is T#GNUAHOVBIPWCJQXDKRYELSZFMA correct call to the program Comms should provide all the information needed to setup enigma for that encryption/decryption session on the command-line, and the actual string to encrypt/decrypt should be readin from standard in.
,-- inner rotor initially positioned so X is on top
|,-- middle rotor initially positioned so # is on top
|| ,-- outer rotor initially positioned so Y is on top
|| /
java Comms 4 2 3 "X#Y" encrypt
| | |
| | `-- outer rotor is rotor 3
| `-- middle rotor is rotor 2
`-- inner rotor is rotor 4
Given this, the session pictured in the diagram above would
correspond to running the program like this:
java Comms 1 2 3 "###" encrypt.
Before you actually implement Enigma, have the Comms program just
print out all the relevent information it will ultimately use to
create and call Enigma. Like this:
~/$ java Comms 1 2 3 "###" encrypt BEAT#ARMY inner rotar: #GNUAHOVBIPWCJQXDKRYELSZFMT with # on top middle rotar: #EJOTYCHMRWAFKPUZDINSXBGLQV with # on top inner rotar: #BDFHJLNPRTVXZACEGIKMOQSUWY with # on top string to encrypt: BEAT#ARMY