ciphers.enigma_machine2

Video explanation: https://youtu.be/QwQVMqfoB2E
Also check out Numberphile’s and Computerphile’s videos on this topic

This module contains function enigma which emulates the famous Enigma machine from WWII.

Module includes:

  • enigma function

  • showcase of function usage

  • 9 randomly generated rotors

  • reflector (aka static rotor)

  • original alphabet

Created by TrapinchO

Attributes

RotorPositionT

RotorSelectionT

abc

message

reflector

rotor1

rotor2

rotor3

rotor4

rotor5

rotor6

rotor7

rotor8

rotor9

Functions

_plugboard(→ dict[str, str])

https://en.wikipedia.org/wiki/Enigma_machine#Plugboard

_validator(→ tuple[RotorPositionT, RotorSelectionT, ...)

Checks if the values can be used for the enigma function

enigma(, plugb)

The only difference with real-world enigma is that I allowed string input.

Module Contents

ciphers.enigma_machine2._plugboard(pbstring: str) dict[str, str]

https://en.wikipedia.org/wiki/Enigma_machine#Plugboard

>>> _plugboard('PICTURES')
{'P': 'I', 'I': 'P', 'C': 'T', 'T': 'C', 'U': 'R', 'R': 'U', 'E': 'S', 'S': 'E'}
>>> _plugboard('POLAND')
{'P': 'O', 'O': 'P', 'L': 'A', 'A': 'L', 'N': 'D', 'D': 'N'}

In the code, pb stands for plugboard

Pairs can be separated by spaces

Parameters:

pbstring – string containing plugboard setting for the Enigma machine

Returns:

dictionary containing converted pairs

ciphers.enigma_machine2._validator(rotpos: RotorPositionT, rotsel: RotorSelectionT, pb: str) tuple[RotorPositionT, RotorSelectionT, dict[str, str]]

Checks if the values can be used for the enigma function

>>> _validator((1,1,1), (rotor1, rotor2, rotor3), 'POLAND')
((1, 1, 1), ('EGZWVONAHDCLFQMSIPJBYUKXTR', 'FOBHMDKEXQNRAULPGSJVTYICZW', 'ZJXESIUQLHAVRMDOYGTNFWPBKC'), {'P': 'O', 'O': 'P', 'L': 'A', 'A': 'L', 'N': 'D', 'D': 'N'})
Parameters:
  • rotpos – rotor_positon

  • rotsel – rotor_selection

  • pb – plugb -> validated and transformed

Returns:

(rotpos, rotsel, pb)

ciphers.enigma_machine2.enigma(text: str, rotor_position: RotorPositionT, rotor_selection: RotorSelectionT = (rotor1, rotor2, rotor3), plugb: str = '') str

The only difference with real-world enigma is that I allowed string input. All characters are converted to uppercase. (non-letter symbol are ignored)

How it works:
(for every letter in the message)
  • Input letter goes into the plugboard. If it is connected to another one, switch it.

  • Letter goes through 3 rotors. Each rotor can be represented as 2 sets of symbol, where one is shuffled. Each symbol from the first set has corresponding symbol in the second set and vice versa.

    example:

    | ABCDEFGHIJKLMNOPQRSTUVWXYZ | e.g. F=D and D=F
    | VKLEPDBGRNWTFCJOHQAMUZYIXS |
    
  • Symbol then goes through reflector (static rotor). There it is switched with paired symbol. The reflector can be represented as 2 sets, each with half of the alphanet. There are usually 10 pairs of letters.

    Example:

    | ABCDEFGHIJKLM | e.g. E is paired to X
    | ZYXWVUTSRQPON | so when E goes in X goes out and vice versa
    
  • Letter then goes through the rotors again

  • If the letter is connected to plugboard, it is switched.

  • Return the letter

>>> enigma('Hello World!', (1, 2, 1), plugb='pictures')
'KORYH JUHHI!'
>>> enigma('KORYH, juhhi!', (1, 2, 1), plugb='pictures')
'HELLO, WORLD!'
>>> enigma('hello world!', (1, 1, 1), plugb='pictures')
'FPNCZ QWOBU!'
>>> enigma('FPNCZ QWOBU', (1, 1, 1), plugb='pictures')
'HELLO WORLD'
Parameters:
  • text – input message

  • rotor_position – tuple with 3 values in range 1.. 26

  • rotor_selection – tuple with 3 rotors

  • plugb – string containing plugboard configuration (default '')

Returns:

en/decrypted string

ciphers.enigma_machine2.RotorPositionT
ciphers.enigma_machine2.RotorSelectionT
ciphers.enigma_machine2.abc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
ciphers.enigma_machine2.message = 'This is my Python script that emulates the Enigma machine from WWII.'
ciphers.enigma_machine2.reflector
ciphers.enigma_machine2.rotor1 = 'EGZWVONAHDCLFQMSIPJBYUKXTR'
ciphers.enigma_machine2.rotor2 = 'FOBHMDKEXQNRAULPGSJVTYICZW'
ciphers.enigma_machine2.rotor3 = 'ZJXESIUQLHAVRMDOYGTNFWPBKC'
ciphers.enigma_machine2.rotor4 = 'RMDJXFUWGISLHVTCQNKYPBEZOA'
ciphers.enigma_machine2.rotor5 = 'SGLCPQWZHKXAREONTFBVIYJUDM'
ciphers.enigma_machine2.rotor6 = 'HVSICLTYKQUBXDWAJZOMFGPREN'
ciphers.enigma_machine2.rotor7 = 'RZWQHFMVDBKICJLNTUXAGYPSOE'
ciphers.enigma_machine2.rotor8 = 'LFKIJODBEGAMQPXVUHYSTCZRWN'
ciphers.enigma_machine2.rotor9 = 'KOAEGVDHXPQZMLFTYWJNBRCIUS'