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 Attribute Summary collapse

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.


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

def initialize
  @connections = {}
end

Instance Attribute Details

#connectionsObject (readonly)

Returns the value of attribute connections


19
20
21
# File 'lib/rotor_machine/plugboard.rb', line 19

def connections
  @connections
end

Instance Method Details

#==(another_plugboard) ⇒ Object


101
102
103
# File 'lib/rotor_machine/plugboard.rb', line 101

def ==(another_plugboard)
  @connections == another_plugboard.connections
end

#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)

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

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

  @connections[from.upcase] = to.upcase
  @connections[to.upcase] = from.upcase
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.


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

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.


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

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.


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

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.


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

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