This documentation is in draft form. Reports of any errors or suggestions for improvement are welcomed and should be submitted as new issues.

Cypher - crypto_enigma.cypher

This is a supporting module that implements the simple substitution cypher employed by the Enigma machine to encode messages. It will not generally be used directly.


Mapping A substitution cypher mapping.
encode_string Encode a string using the mapping.
encode_char Encode a single character using the mapping.

Substitution cypher mappings

All encoding functionality is built upon a single class:

class crypto_enigma.cypher.Mapping[source]

Bases: unicode

A substitution cypher mapping.

The Enigma machine, and the components from which it is constructed, use mappings to perform a simple substitution encoding. Mappings describe

  • the cryptographic effects of each component’s fixed wiring;
  • the encoding they perform individually in a machine based on their rotational positions and the direction in which a signal passes through them (see mapping); and,
  • the progressive (stage_mapping_list) and overall (enigma_mapping_list and enigma_mapping) encoding performed by the machine as a whole.

Mapping encoding

Mappings are expressed as a string of letters indicating the mapped-to letter for the letter at that position in the alphabet — i.e., as a permutation of the alphabet. For example, the mapping EKMFLGDQVZNTOWYHXUSPAIBRCJ encodes A to E, B to K, C to M, …, Y to C, and Z to J:

>>> mpg.encode_string(u'ABCYZJ')
>>> mpg.encode_string(u'ABCDEFGHIJKLMNOPQRSTUVWXYZ') == mpg

Note that there is no way to directly create Mapping for use by an EnigmaMachine or Component. The closest one can get is to configure a plugboard with component:

>>> component(u'AE.BK.CM.FD').wiring 

For reference, two functions are provided to perform a mappings substitution cypher, though these will rarely be used directly:


Encode a string using the mapping.

Parameters:string (str) – A string to encode using the Mapping.
A string consisting of each of the characters replaced with the corresponding
character in the Mapping.
Return type:str


This just the collected results of applying encode_char to each letter of the string:

>>> component(u'AE.BK.CM.FD').wiring.encode_string(u'ABKCFEKMD')
>>> ''.join(component(u'AE.BK.CM.FD').wiring.encode_char(c) for c in u'ABKCFEKMD')

Note that, critically, the mapping used by an Enigma machine changes before each character is encoded so that:

>>> cfg.enigma_mapping().encode_string(str) != cfg.enigma_encoding(str)

Encode a single character using the mapping.

Parameters:ch (char) – A character to encode using the Mapping.
Returns:The character, replaced with the corresponding characters in the Mapping.
Return type:chr


In the context of this package, this is most useful in low level analysis of the encoding process:

>>> wng = component(u'AE.BK.CM.FD').wiring
>>> wng.encode_char(u'A')
>>> wng.encode_char(u'K')
>>> wng.encode_char(u'Q')

For example, it can be used to confirm that only letters connected in a plugboard are unaltered by the encoding it performs:

>>> pbd = component(u'AE.BK.CM.FD')
>>> all(pbd.wiring.encode_char(c) == c for c in filter(lambda c: c not in,  u'ABCDEFGHIJKLMNOPQRSTUVWXYZ'))
>>> all(pbd.wiring.encode_char(c) != c for c in filter(lambda c: c in,  u'ABCDEFGHIJKLMNOPQRSTUVWXYZ'))