The purpose of this lab is to practice good OOP practices. You will work with a partner, using Git to share work as you did for Lab 2. Of particular note: you will work separately on some componenets, but when your partner is responsible for developing one part of the program, you are in charge of developing tests for that part of the program.

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:

  1. The alphabet for messages is all capital letters, plus # for spaces.
  2. In order to encrypt/decrypt properly, sender and receiver have to agree a) and ordered list of three numbers taken from {1,2,3,4,5}, no duplicates allowed (in Enigma this corresponds to the choice of "rotors"), and a string of three symbols from the alphabet (in Enigma this corresponds to the initial alignment of the three rotors).
Here are several sample runs of the program:
~/$ java Comms 1 2 3 "###" encrypt
~/$ java Comms 1 2 3 "USN" encrypt
~/$ java Comms 1 2 3 "USN" decrypt

In the end, you should be able to decrypt the following message using the settings 1 2 3 "###":


Substitution ciphers that encode a message by substituting one character for another go back at least as far as Julius Caesar, who used a rotating character scheme to encode military orders. This simple type of encryption is extremely vulnerable to statistical attacks, however. In World War II, the Nazi military employed an encryption scheme that addressed this weakness of simple substitution ciphers. This scheme, implemented by typewriter-sized devices known as Enigma machines, was believed by the Nazis to be unbreakable. This belief was grounded in the fact that by the time the huge amount of computational work necessary to break the code was completed, the message itself would be irrelevant.

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.

Setup another Git repository

On the account of the person who's computer you've been working at:
  1. In a separate terminal window from the work you've already done, give the following commands:
    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"
  2. In the same directory as the previous step, give the command:
    This 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/share04
    Save that! That's what you need to do to "checkout" or "clone" a copy of the repository.
  3. Each partner should go to whatever directory they've created for this lab (e.g. "lab04") give your version of the command:
    git clone ssh://mich302csd17u.academy.usna.edu/home/mids/m17xxxx/share04
    if 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!

Overview of your solution

You will define a class 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:

The Comms class

The Comms class should take input from the command line arguments and from standard in as described above. If there are too few arguments or an argument is wrong (e.g. "XYk"), an error message should be printed along with the usage message. Same thing if the string to encrypt/decrypt has symbols outside the 27 allowed. So, for example:
~/$ 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!):
... 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:
A 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
inner  rotar: #GNUAHOVBIPWCJQXDKRYELSZFMT with # on top
middle rotar: #EJOTYCHMRWAFKPUZDINSXBGLQV with # on top
inner  rotar: #BDFHJLNPRTVXZACEGIKMOQSUWY with # on top
string to encrypt: BEAT#ARMY

The Rotor class

I strongly recommend that you represent the rotor as an array of 27 characters — where the element at index 0 is the topmost element, and moving to the right in the array represents moving clockwise around the rotor — and a single character, which stores the symbol that was initially topmost. Your Rotor should be able to do the following things:
  1. Be constructed, using as input a String defining the rotor and a char defining the symbol on the rotor that should be uppermost initially. Note: in the constructor, you can call other methods, like the method to rotate!
  2. Rotate one click clockwise. This should involve an alteration of the array of characters.
  3. Return, given a character, the index in the array at which that character appears.
  4. Return, given an index, the character at that index.

The Enigma class

This I'm leaving very much up to you. Certainly, I expect it to be set up with three rotors and three rotor starting symbols, and I expect you'll have encrypt and decrypt methods for encrypting and decrypting strings. Beyond that, do what you need to do!


This lab originally written by Prof. David Reed, Creighton University