Jump to content
  • entries
    63
  • comments
    51
  • views
    20,368

The Software Enigma Machine blog Pt. 3: The Plug board

Mira Yurizaki

841 views

Part 3 in the making of the Software Enigma Machine. This time, talking about the plug board.

 

The Outline

A recap on the outline.

  • Part 1
    • What is the Enigma Machine?
    • Why did I choose to implement the Enigma machine?
    • Before Programming Begins:
      • Understanding the theory of the Enigma Machine
      • Finding a programming environment
  • Part 2
    • Programming the features
    • Rotors
    • Rotor housing
  • Part 3
    • Plug Board
  • Part 4
    • GUI

If you'd like to look at the source code, it's uploaded on GitHub.

 

The Plug Board

At first I thought I could reuse the rotor code, but there was a snag with this: the user can change the mapping at will.  And not only that, but the mapping needs to be reflective. That is if inputting A results in outputting G, then inputting G results in outputting A. So the first data structure I thought of that could store this mapping is a dictionary, where the keys and values are string types. The dictionary would be initialized to take in the list of letters or characters and just have them map to themselves.

public PlugBoard(int Seed, List<string> CharList)
{
  mapping = new Dictionary<string, string>();
  rng = new Random(Seed);

  foreach (string entry in CharList)
    mapping.Add(entry, entry);
}

The RNG seed is needed for the shuffle function, which I'll talk about later.

 

At first I thought the remapping would be easy:

public void ChangeWiring(string Input, string NewOutput)
{
  mapping[Input] = NewOutput;
  mapping[NewOutput] = Input;
}

But this presents a problem. Say for instance we have this mapping:
 

A => G
B => S
G => A
S => B

 

I want to map A to B. But taking that code as is, would actually result in this mapping.

 

A => B
B => A
G => A
S => B

Oops. I didn't account for the fact that A and B still had something connected to it. So after stewing on this for a while, maybe thinking of some clever swap trick, I decided on this: don't assume the user wanted to remap the other side of Input and NewOutput. That is, those letters should be "disconnected" first. In this case, G and S should be disconnected and mapped themselves, then we can map A and B together. So the code becomes this:

public void ChangeWiring(string Input, string NewOutput)
{
  string oldOutput = mapping[Input];
  mapping[oldOutput] = oldOutput;

  oldOutput = mapping[NewOutput];
  mapping[oldOutput] = oldOutput;

  mapping[Input] = NewOutput;
  mapping[NewOutput] = Input;
}

Another feature I wanted is to have the app shuffle the wiring since:

  1. The user may not want to manually input what combinations they want on the plugboard
  2. It allows the app to automatically rewire the board in the event of encoding a text string, rather than having the user key in all of the text.

The first instinct way of doing this would be to randomly generate two numbers of which indexes to change the wiring. Except... this is a dictionary where the key is a string. So I can't use an integer. And since I can't assume what the list of keys looks like, I can't use this integer to generate a character. However, you can iterate through the keys using the foreach loop. So I combined the two ideas so to speak:

  • Generate a random number that's between 0 and the number of entries in the dictionary.
  • Use a foreach loop to iterate through the letters.
  • A counter counts up for each iteration.
  • When the counter equals the random number, use the letter picked from the iteration and break the foreach loop.

Do this twice, and the first and second letters to be wired together are picked. It looks hokey, but it works:

public void ShuffleWiring()
{
  int entries = mapping.Count;
  Dictionary<string, string>.KeyCollection keys = mapping.Keys;

  for(int i = 0; i < entries; i++)
  {
    int randEntry = rng.Next(entries + 1);
    int counter = 0;
    string firstLetter = "";
    string secondLetter = "";

    foreach (string randomKey in keys)
    {
      firstLetter = randomKey;
      counter++;
      if (counter == randEntry)                        
        break;

    }

    randEntry = (rng.Next() % entries);
    counter = 0;

    foreach (string randomKey in keys)
    {
      secondLetter = randomKey;
      counter++;
      if (counter == randEntry)
        break;

    }

    ChangeWiring(firstLetter, secondLetter);
  }
}

The only other plug board behavior needed is to get the mapped letter. However, since the valid inputs of the board are arbitrary, this method makes sure the input is a key in the dictionary. If it is, then it returns the remapped letter. Otherwise it returns the input as-is.

public string GetRewiredLetter(string Input)
{
  Input = Input.ToUpper();
  if (mapping.ContainsKey(Input))
    return mapping[Input];
  return Input;
}

> On to Part 4

0 Comments

There are no comments to display.

×