Plugboard = Hash[*('A'..'Z').to_a.sample(20)] Plugboard.merge!(Plugboard.invert) Plugboard.default_proc = proc { |_, key| key } def build_a_rotor Hash[('A'..'Z').zip(('A'..'Z').to_a.shuffle)] end ROTOR_1, ROTOR_2, ROTOR_3 = build_a_rotor, build_a_rotor, build_a_rotor Reflector = Hash[*('A'..'Z').to_a.shuffle] Reflector.merge!(Reflector.invert) 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 == 'Z' ? 'A' : k.next, v] }] end plain_text = 'IHAVETAKENMOREOUTOFALCOHOLTHANALCOHOLHASTAKENOUTOFME' puts "Encrypted '#{plain_text}' to '#{encrypted = input(plain_text)}'" puts "Decrypted '#{encrypted}' to '#{decrypted = input(encrypted)}'" puts 'Success!' if plain_text == decrypted