Skip to content

Instantly share code, notes, and snippets.

@felipec
Last active August 29, 2015 14:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save felipec/82e78cfe7d6f20d5fa10 to your computer and use it in GitHub Desktop.
Save felipec/82e78cfe7d6f20d5fa10 to your computer and use it in GitHub Desktop.
Enigma machine in Ruby
#!/usr/bin/env ruby
CHARS = ('A'..'Z')
=begin
def stringify(array)
array.map(&:join).join(' ')
end
def build_reflector(max)
n = CHARS.to_a.shuffle.first(max).each_slice(2).to_a
n += n.map(&:reverse)
end
def build_rotor
CHARS.zip(CHARS.to_a.shuffle)
end
puts "reflector: " + stringify(build_reflector(26))
puts "rotor_1: " + stringify(build_rotor)
puts "rotor_2: " + stringify(build_rotor)
puts "rotor_3: " + stringify(build_rotor)
puts "plugboard: " + stringify(build_reflector(20))
puts "config: " + CHARS.to_a.shuffle.first(3).join
puts "start: " + CHARS.to_a.shuffle.first(3).join
=end
REFLECTOR = "WL ZM BC KP XO HR VY FI NE US JT GA QD LW MZ CB PK OX RH YV IF EN SU TJ AG DQ"
ROTOR_1 = "AK BB CJ DY EU FX GP HF IO JS KV LH MN NA OZ PE QR RW ST TI UC VM WD XG YQ ZL"
ROTOR_2 = "AI BY CT DU EF FE GC HN IM JH KQ LZ MB NK OJ PV QO RA SG TD US VW WP XR YL ZX"
ROTOR_3 = "AZ BN CU DD ET FO GX HR IQ JG KB LF MM NL OH PI QY RC SP TW UK VE WS XA YJ ZV"
plugboard = "SD HY GM EB UO LJ WZ QT AC FR"
config = "BFR"
start = "OIZ"
def config_rotor(rotor, key, value)
keys, values = rotor.split(' ').map(&:chars).transpose
keys.rotate!(keys.index(value))
values.rotate!(values.index(key))
Hash[keys.zip(values)]
end
def config_plugboard(config)
plugboard = config.split(' ').map(&:chars).to_h
plugboard.merge!(plugboard.invert)
plugboard.default_proc = proc { |hash, key| key }
plugboard
end
$reflector = REFLECTOR.split(' ').map(&:chars).to_h
$rotor_1 = config_rotor(ROTOR_1, config[0], start[0])
$rotor_2 = config_rotor(ROTOR_2, config[1], start[1])
$rotor_3 = config_rotor(ROTOR_3, config[2], start[2])
$plugboard = config_plugboard(plugboard)
def input(string)
rotor_1, rotor_2, rotor_3 = $rotor_1.dup, $rotor_2.dup, $rotor_3.dup
string.chars.each_with_index.map do |char, index|
rotor_1 = rotate_rotor rotor_1
rotor_2 = rotate_rotor rotor_2 if index % 25 == 0
rotor_3 = rotate_rotor rotor_3 if index % 25 * 25 == 0
char = $plugboard[char]
char = rotor_1[char]
char = rotor_2[char]
char = rotor_3[char]
char = $reflector[char]
char = rotor_3.invert[char]
char = rotor_2.invert[char]
char = rotor_1.invert[char]
$plugboard[char]
end.join
end
def rotate_rotor(rotor)
Hash[rotor.map { |k,v| [k == CHARS.last ? CHARS.first : k.next, v] }]
end
plain_text = 'HITLER'
puts "Encrypted '#{plain_text}' to '#{encrypted = input(plain_text)}'"
puts "Decrypted '#{encrypted}' to '#{decrypted = input(encrypted)}'"
puts 'Success!' if plain_text == decrypted
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment