Class: RotorMachine::Plugboard

Inherits:
Object
  • Object
show all
Defined in:
lib/rotor_machine/plugboard.rb

Overview

Plugboard implementaion for the RotorMachine Enigma simulation.

The Plugboard was an enhancement to the original Enigma machine to add an additional layer of transposition into the signal path. Signals passed through the plugboard as they were leaving the keyboard and, to maintain the symmetry of the Enigma’s encryption, before being displayed on the lightboard.

The properties of the Plugboard which are relevant to how the encryption works are:

  • Each letter may only be connected to one other letter.

  • Connections are reciprocal. Connecting A to B also implies a connection from B to A.

  • A letter cannot be connected to itself.

Instance Method Summary collapse

Constructor Details

#initializePlugboard

Create a new, empty Plugboard object.

By default, no letters are connected in the plugboard, and all input characters are passed through unchanged.



25
26
27
# File 'lib/rotor_machine/plugboard.rb', line 25

def initialize
  @connections = {}
end

Instance Method Details

#connect(from, to) ⇒ Object

Connect a pair of letters on the RotorMachine::Plugboard.

The designations of “from” and “to” are rather arbitrary, since the connection is reciprocal.

An ArgumentError will be raised if either from or to are already connected, or if you try to connect a letter to itself.

Parameters:

  • from (String)

    A single-character string designating the start of the connection.

  • to (String)

    A single-character string designating the end of the connection.

Raises:

  • (ArgumentError)


42
43
44
45
46
47
48
49
50
51
# File 'lib/rotor_machine/plugboard.rb', line 42

def connect(from, to)
  from.upcase!
  to.upcase!
  raise ArgumentError, "#{from} is already connected" if (connected?(from))
  raise ArgumentError, "#{to} is already connected" if (connected?(to))
  raise ArgumentError, "#{from} cannot be connected to itself" if (to == from)

  @connections[from] = to
  @connections[to] = from
end

#connected?(letter) ⇒ Boolean

Test if a particular letter is connected on the RotorMachine::Plugboard.

Parameters:

  • letter (String)

    The letter to test.

Returns:

  • (Boolean)

    True if the letter is connected, nil otherwise.



90
91
92
# File 'lib/rotor_machine/plugboard.rb', line 90

def connected?(letter)
  @connections.keys.include?(letter.upcase)
end

#disconnect(letter) ⇒ Object

Disconnect a plugboard mapping for a letter.

Because the RotorMachine::Plugboard mappings are reciprocal (they were represented by a physical wire on the actual machine), this also removes the reciprocal mapping.

An ArgumentError is raised if the specified letter is not connected.

Parameters:

  • letter (String)

    The letter to disconnect. You may specify the letter at either end of the mapping.



64
65
66
67
68
69
70
71
72
# File 'lib/rotor_machine/plugboard.rb', line 64

def disconnect(letter)
  letter.upcase!
  if (connected?(letter))
    other_end = @connections.delete(letter)
    @connections.delete(other_end)
  else
    raise ArgumentError, "#{letter} is not connected"
  end
end

#to_sString

Produce a human-readable representation of the #RotorMachine::Plugboard‘s state.

Returns:

  • (String)

    A description of the current state.



98
99
100
# File 'lib/rotor_machine/plugboard.rb', line 98

def to_s
  "a RotorMachine::Plugboard with connections: #{@connections.to_s}"
end

#transpose(the_string) ⇒ String

Feed a string of characters through the RotorMachine::Plugboard and return the mapped characters. Characters which are not mapped are passed through unchanged (but the parameter string is upcased before processing.

Parameters:

  • the_string (String)

    The string being enciphered.

Returns:

  • (String)

    The enciphered text.



81
82
83
# File 'lib/rotor_machine/plugboard.rb', line 81

def transpose(the_string)
  the_string.chars.collect { |c| @connections[c.upcase] || c.upcase }.join("")
end