Class: RotorMachine::Reflector
- Inherits:
-
Object
- Object
- RotorMachine::Reflector
- Defined in:
- lib/rotor_machine/reflector.rb
Overview
Implementation of the Reflector rotor.
A Reflector behaves similarly to a Rotor, except that the Reflector did not rotate. Its purpose is to reflect the signal path back through the rotor stack in the opposite direction, thereby ensuring that the encryption algorithm is symmetric.
The module defines constants for the standard German Enigma reflectors, but you can create a reflector with any string of 26 alphabetic characters. However, you may not repeat a given letter more than once in your string, or else the symmetry of the encipherment algorithm will be broken.
Constant Summary collapse
- REFLECTOR_A =
The letter mapping for the German “A” reflector.
"EJMZALYXVBWFCRQUONTSPIKHGD".freeze
- REFLECTOR_B =
The letter mapping for the German “B” reflector.
"YRUHQSLDPXNGOKMIEBFZCWVJAT".freeze
- REFLECTOR_C =
The letter mapping for the German “C” reflector.
"FVPJIAOYEDRZXWGCTKUQSBNMHL".freeze
- REFLECTOR_B_THIN =
The letter mapping for the German “B Thin” reflector.
"ENKQAUYWJICOPBLMDXZVFTHRGS".freeze
- REFLECTOR_C_THIN =
The letter mapping for the German “C Thin” reflector.
"RDOBJNTKVEHMLFCWZAXGYIPSUQ".freeze
- REFLECTOR_ETW =
The letter mapping for the German “ETW” reflector.
"ABCDEFGHIJKLMNOPQRSTUVWXYZ".freeze
- ALPHABET =
A letter mapping for a passthrough reflector; also used by the RSpec tests
"ABCDEFGHIJKLMNOPQRSTUVWXYZ".freeze
Instance Attribute Summary collapse
-
#position ⇒ Object
Allow querying the numeric position (ie, the initial position) of the reflector.
Instance Method Summary collapse
-
#==(another_reflector) ⇒ Boolean
Compare this Reflector to another one.
-
#current_letter ⇒ String
Get the current letter position of the rotor.
-
#initialize(selected_reflector, start_position = 0) ⇒ Reflector
constructor
Initialize a new Reflector.
-
#letters ⇒ String
Return the sequence of letters on the reflector.
-
#reflect(input) ⇒ String
Feed a sequence of characters through the reflector, and return the results.
-
#reflector_kind_name ⇒ Symbol
Return the reflector kind.
-
#to_s ⇒ String
Return a human-readable representation of the Reflector.
Constructor Details
#initialize(selected_reflector, start_position = 0) ⇒ Reflector
Initialize a new RotorMachine::Reflector.
60 61 62 63 64 65 66 |
# File 'lib/rotor_machine/reflector.rb', line 60 def initialize(selected_reflector, start_position = 0) raise ArgumentError, "Initialization string contains duplicate letters" unless selected_reflector.is_uniq? @letters = selected_reflector.chars.freeze @alphabet = ALPHABET.chars.freeze @position = start_position end |
Instance Attribute Details
#position ⇒ Object
Allow querying the numeric position (ie, the initial position) of the reflector.
20 21 22 |
# File 'lib/rotor_machine/reflector.rb', line 20 def position @position end |
Instance Method Details
#==(another_reflector) ⇒ Boolean
Compare this RotorMachine::Reflector to another one.
Returns True if the configuration of the supplied RotorMachine::Reflector matches this one, false otherwise.
to this one.
154 155 156 157 |
# File 'lib/rotor_machine/reflector.rb', line 154 def ==(another_reflector) self.letters == another_reflector.letters && self.position == another_reflector.position end |
#current_letter ⇒ String
Get the current letter position of the rotor.
133 134 135 |
# File 'lib/rotor_machine/reflector.rb', line 133 def current_letter @letters[self.position] end |
#letters ⇒ String
Return the sequence of letters on the reflector.
125 126 127 |
# File 'lib/rotor_machine/reflector.rb', line 125 def letters @letters.join("") end |
#reflect(input) ⇒ String
Feed a sequence of characters through the reflector, and return the results.
Any characters which are not present on the reflector will be passed through unchanged.
99 100 101 102 103 104 105 106 |
# File 'lib/rotor_machine/reflector.rb', line 99 def reflect(input) input.upcase.chars.each.collect { |c| if @alphabet.include?(c) then @letters[(@alphabet.index(c) + @position) % @alphabet.length] else c end }.join("") end |
#reflector_kind_name ⇒ Symbol
Return the reflector kind.
If the RotorMachine::Reflector is initialized with one of the provided rotor type constants (such as REFLECTOR_A), the name of the reflector will be returned as a symbol. If not, the symbol ‘:CUSTOM` will be returned..
116 117 118 119 |
# File 'lib/rotor_machine/reflector.rb', line 116 def reflector_kind_name self.class.constants.each { |r| return r if (@letters.join("") == self.class.const_get(r)) } return :CUSTOM end |
#to_s ⇒ String
Return a human-readable representation of the RotorMachine::Reflector
141 142 143 |
# File 'lib/rotor_machine/reflector.rb', line 141 def to_s "a RotorMachine::Reflector of type '#{self.reflector_kind_name.to_s}'" end |