Note
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.
Overview¶
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 (seemapping
); and, - the progressive (
stage_mapping_list
) and overall (enigma_mapping_list
andenigma_mapping
) encoding performed by the machine as a whole.
- the cryptographic effects of each component’s fixed
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 = Mapping(u'EKMFLGDQVZNTOWYHXUSPAIBRCJ')
>>> mpg.encode_string(u'ABCYZJ')
u'EKMCJZ'
>>> mpg.encode_string(u'ABCDEFGHIJKLMNOPQRSTUVWXYZ') == mpg
True
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
u'EKMF...'
For reference, two functions are provided to perform a mappings substitution cypher, though these will rarely be used directly:
-
Mapping.
encode_string
(string)[source]¶ Encode a string using the mapping.
Parameters: string (str) – A string to encode using the Mapping
.Returns: - A string consisting of each of the characters replaced with the corresponding
- character in the
Mapping
.
Return type: str Examples
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') u'EKBMDABCF' >>> ''.join(component(u'AE.BK.CM.FD').wiring.encode_char(c) for c in u'ABKCFEKMD') u'EKBMDABCF'
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) True
-
Mapping.
encode_char
(ch)[source]¶ 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 Example
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') u'E' >>> wng.encode_char(u'K') u'B' >>> wng.encode_char(u'Q') 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 pbd.name, u'ABCDEFGHIJKLMNOPQRSTUVWXYZ')) True >>> all(pbd.wiring.encode_char(c) != c for c in filter(lambda c: c in pbd.name, u'ABCDEFGHIJKLMNOPQRSTUVWXYZ')) True