crypto-enigma-0.1.1.2: An Enigma machine simulator with display.

Copyright(c) 2014-2019 Roy Levien
LicenseBSD3
Maintainerroyl@aldaron.com
Stabilityprovisional
PortabilityPOSIX
Safe HaskellSafe
LanguageHaskell2010

Crypto.Enigma.Display

Contents

Description

A module for rich display of the state of and encoding performed by Enigma machines defined in Crypto.Enigma.

Synopsis

Display options

data DisplayOpts Source #

Options for displayEnigmaConfig, displayEnigmaOperation, and listEnigmaOperation, created using displayOpts. All fields are coerced to valid values by display functions.

displayOpts :: DisplayOpts Source #

Default DisplayOpts equivalent to DisplayOpts{format="single",showencoding=False,markerspec="bars",...}. See individual options below for defaults values. This is the sole method for providing and setting options for display functions. E.g. to supply specify a format of "windows" which shows encoding (see showencoding) provide

displayOpts{format="windows",showencoding=True}

as the DisplayOpts argument to a display finction.

format :: DisplayOpts -> Format Source #

A Format specifying the format used to display EnigmaConfig machine configuration(s) that should be one of "single", "internal", "windows", "config", and "encoding":

"single"
A summary of the Enigma machine configuration as its encoding (see Mapping), the letters at the windows (see windows), and the Positions of the rotors (see positions).

Any valid letter being encoded (see showencoding) by the configuration is indicated as input, and the encoding of the letter is marked (see markerspec).

For example,

K > CMAWFEKLNVG̲̅HBIUYTXZQOJDRPS  LFAQ  10 16 24 07

shows the process of encoding of the letter 'K' to 'G'.

"internal"
An expaned schematic of the configuration showing the encoding (see Mapping) performed by each stage (see stageMappingList), along with an indication of the stage (rotor number, "P" for plugboard, or "R" for reflector), window letter (see windows), Position (see positions) and Name, followed by the encoding for the machine as a whole, and preceded by a (trivial, no-op) keyboard "encoding" for reference.

Any valid letter being encoded (see showencoding) by the configuration is indicated as input, and its encoding at each stage is marked (see markerspec).

For example,

K > ABCDEFGHIJK̲̅LMNOPQRSTUVWXYZ
  P YBCDFEGHIJZ̲̅PONMLQRSTXVWUAK         UX.MO.KZ.AY.EF.PL
  1 LORVFBQNGWKATHJSZPIYUDXEMC̲̅  Q  07  II
  2 BJY̲̅INTKWOARFEMVSGCUDPHZQLX  A  24  VIII
  3 ILHXUBZQPNVGKMCRTEJFADOYS̲̅W  F  16  V
  4 YDSKZPTNCHGQOMXAUWJ̲̅FBRELVI  L  10  γ
  R ENKQAUYWJI̲̅COPBLMDXZVFTHRGS         b
  4 PUIBWTKJZ̲̅SDXNHMFLVCGQYROAE         γ
  3 UFOVRTLCASMBNJWIHPYQEKZDXG̲̅         V
  2 JARTMLQ̲̅VDBGYNEIUXKPFSOHZCW         VIII
  1 LFZVXEINSOKAYHBRG̲̅CPMUDJWTQ         II
  P YBCDFEG̲̅HIJZPONMLQRSTXVWUAK         UX.MO.KZ.AY.EF.PL
G < CMAWFEKLNVG̲̅HBIUYTXZQOJDRPS

shows the "internals" of the same proccess as avove using the same machine configuration: the encoding of the letter 'K' to 'G':

  • 'K' is entered at the keyboard, which is then
  • encoded by the plugboard ('P'), which includes "KZ" in its specification (see Name), to 'Z', which is then
  • encoded by the first rotor ('1'), a "II" rotor in the 07 position (and 'Q' at the window), to 'C', which is then
  • encoded by the second rotor ('2'), a "VIII" rotor in the 24 position (and 'A' at the window), to 'Y', which is then
  • encoded by the third rotor ('3'), a "V" rotor in the 16 position (and 'F' at the window), to 'S', which is then
  • encoded by the fourth rotor ('4'), a "γ" rotor in the 10 position (and 'L' at the window), to 'J', which is then
  • encoded by the reflector rotor ('U'), a "b" reflector, to 'I', which reverses the signal sending it back through the rotors, where it is then
  • encoded in reverse by the fourth rotor ('4'), to 'Z', which is then
  • encoded in reverse by the third rotor ('3'), to 'G', which is then
  • encoded in reverse by the second rotor ('2'), to 'Q', which is then
  • encoded in reverse by the first rotor ('1'), to 'G', which is then
  • left unchanged by the plugboard ('P'), and finally
  • displayed as 'G'

Note that (as follows from Mapping) the position of the marked letter at each stage is the alphabetic position of the marked letter at the previous stage.

This can be represented schematically (with input arriving and output exiting on the left) as

"windows"
The letters at the window (see windows):
LFAQ
"config"
The specification of the configuration (see configEnigmaExcept) in the same format used by configEnigma and configEnigmaExcept, as a single string:
b-γ-V-VIII-II LFAQ UX.MO.KZ.AY.EF.PL 03.17.04.11
"encoding"
The encoding of any valid letter being encoded (see showencoding):
K > G

Note the "windows" and config" effectively display the same format as windows and show, and are most useful in conjunction with other options (e.g. showencoding and showsteps, respectively) and for showing operation with displayEnigmaOperation.

See displayEnigmaConfig for further examples.

Display functions are forgiving about the supplied format and will accept a range of reasonable substitutes (e.g., "detailed" or "schematic" for "internal"), and will treat unrecognized formats as the default, "single".

showencoding :: DisplayOpts -> Bool Source #

A Bool indicating whether to show encoding if not normally shown for the specified format.

If a valid letter is being encoded (one is either provided as an argument to displayEnigmaConfig, or there is a message provided as an argument to displayEnigmaOperation with a letter at the displayed step) the letter and its encoding are indicated.

This setting applies only to "windows" and "config". For example, where "windows" normally shows just

LFAQ

setting showencoding to True produces

LFAQ  K > G

markerspec :: DisplayOpts -> MarkerSpec Source #

A MarkerSpec that should be either a pair or characters (e.g. "[]") or a specification of a color (e.g, "red") or style ("bars") to use to highlight the encoded character in formats that show encoding. For example the default markerspec of "bars" highlights the encoding (in, e.g., the "single" format with a bar above and below the encoding

K > CMAWFEKLNVG̲̅HBIUYTXZQOJDRPS  LFAQ  10 16 24 07

and supplying a markerspec of "[]" instead highlights the encoding of the letter by placing a "[" to the left and a "]" to the right of the encoding

K > CMAWFEKLNV[G]HBIUYTXZQOJDRPS  LFAQ  10 16 24 07

Invalid or unrecognized highlight specifications are treated as the "bars".

showsteps :: DisplayOpts -> Bool Source #

A Bool indicating whether to show step numbers, defaults to False.

Only relevant for operation display functions. See displayEnigmaOperation for examples.

steps :: DisplayOpts -> DisplaySteps Source #

An Int indicating the number of steps to display, which defaults to the length of a message if one is being displayed, and to 1 otherwise. Values less than 1 are treated as the default.

Only relevant for operation display functions. See displayEnigmaOperation for examples.

type Format = String Source #

A (synonym for) String, indicating that this option will be coerced to a valid valid format when used by display functions.

type MarkerSpec = String Source #

A (synonym for) String, indicating that this option will be coerced to a valid valid markerspec when used by display functions.

type DisplaySteps = Int Source #

A (synonym for) Int, indicating that this option will be coerced to a valid valid steps value when used by display functions.

Configuration display

displayEnigmaConfig :: EnigmaConfig -> Char -> DisplayOpts -> String Source #

A String representation of an EnigmaConfig using the specified DisplayOpts.

If an uppercase letter is provided, indicate that as input show its encoding(s), as determined by the the format and showencoding and, where for the format, markerspec. Other characters will be ignored.

For example, the illustrations given in the discussion of the format option above can be created using (in order)

>>> let cfg = step $ configEnigma "b-γ-V-VIII-II" "LFAP" "UX.MO.KZ.AY.EF.PL" "03.17.04.11"
>>> putStrLn $ displayEnigmaConfig cfg 'K' displayOpts{format="single"}
K > CMAWFEKLNVG̲̅HBIUYTXZQOJDRPS  LFAQ  10 16 24 07
>>> putStrLn $ displayEnigmaConfig cfg 'K' displayOpts{format="internal"}
K > ABCDEFGHIJK̲̅LMNOPQRSTUVWXYZ
  P YBCDFEGHIJZ̲̅PONMLQRSTXVWUAK         UX.MO.KZ.AY.EF.PL
  1 LORVFBQNGWKATHJSZPIYUDXEMC̲̅  Q  07  II
  2 BJY̲̅INTKWOARFEMVSGCUDPHZQLX  A  24  VIII
  3 ILHXUBZQPNVGKMCRTEJFADOYS̲̅W  F  16  V
  4 YDSKZPTNCHGQOMXAUWJ̲̅FBRELVI  L  10  γ
  R ENKQAUYWJI̲̅COPBLMDXZVFTHRGS         b
  4 PUIBWTKJZ̲̅SDXNHMFLVCGQYROAE         γ
  3 UFOVRTLCASMBNJWIHPYQEKZDXG̲̅         V
  2 JARTMLQ̲̅VDBGYNEIUXKPFSOHZCW         VIII
  1 LFZVXEINSOKAYHBRG̲̅CPMUDJWTQ         II
  P YBCDFEG̲̅HIJZPONMLQRSTXVWUAK         UX.MO.KZ.AY.EF.PL
G < CMAWFEKLNVG̲̅HBIUYTXZQOJDRPS
>>> putStrLn $ displayEnigmaConfig cfg 'K' displayOpts{format="windows"}
LFAQ
>>> putStrLn $ displayEnigmaConfig cfg 'K' displayOpts{format="config"}
b-γ-V-VIII-II LFAQ UX.MO.KZ.AY.EF.PL 03.17.04.11
>>> putStrLn $ displayEnigmaConfig cfg 'K' displayOpts{format="encoding"}
K > G

and other options can be freely combined (or omitted), for example

>>> putStrLn $ displayEnigmaConfig cfg 'K' displayOpts{format="single",markerspec="()"}
K > CMAWFEKLNV(G)HBIUYTXZQOJDRPS  LFAQ  10 16 24 07
>>> putStrLn $ displayEnigmaConfig cfg 'K' displayOpts{format="config",showencoding=True}
b-γ-V-VIII-II LFAQ UX.MO.KZ.AY.EF.PL 03.17.04.11  K > G
>>> putStrLn $ displayEnigmaConfig cfg 'K' displayOpts
K > CMAWFEKLNVG̲̅HBIUYTXZQOJDRPS  LFAQ  10 16 24 07

Operation display

displayEnigmaOperation :: EnigmaConfig -> Message -> DisplayOpts -> String Source #

A String representation of an Enigma machine's internal configuration (see displayEnigmaConfig for details) and for each subsequent configuration as it processes each letter of a Message, subject to the provided DisplayOpts.

In addition to the options that apply to the representation of each individual configuration, DisplayOpts for this function include options for specifying whether to run for a specific number of steps and whether to include a step number in the representations.

For example, these options applied to the default "single" format

>>> let cfg = configEnigma "b-γ-V-VIII-II" "LFAP" "UX.MO.KZ.AY.EF.PL" "03.17.04.11"
>>> putStr $ displayEnigmaOperation cfg "KRIEG" displayOpts
    OHNKJYSBTEDMLCARWPGIXZQUFV  LFAP  10 16 24 06
K > CMAWFEKLNVG̲̅HBIUYTXZQOJDRPS  LFAQ  10 16 24 07
R > HXETCUMASQNZGKRYJO̲̅IDFWVBPL  LFAR  10 16 24 08
I > FGRJUABYW̲̅DZSXVQTOCLPENIMHK  LFAS  10 16 24 09
E > SJWYN̲̅UZPQBVXRETHIMAOFKCLDG  LFAT  10 16 24 10
G > EOKPAQW̲̅JLHCISTBDFVMNXRGUZY  LFAU  10 16 24 11
>>> putStr $ displayEnigmaOperation cfg "KRIEG" displayOpts{showsteps=True}
000      OHNKJYSBTEDMLCARWPGIXZQUFV  LFAP  10 16 24 06
001  K > CMAWFEKLNVG̲̅HBIUYTXZQOJDRPS  LFAQ  10 16 24 07
002  R > HXETCUMASQNZGKRYJO̲̅IDFWVBPL  LFAR  10 16 24 08
003  I > FGRJUABYW̲̅DZSXVQTOCLPENIMHK  LFAS  10 16 24 09
004  E > SJWYN̲̅UZPQBVXRETHIMAOFKCLDG  LFAT  10 16 24 10
005  G > EOKPAQW̲̅JLHCISTBDFVMNXRGUZY  LFAU  10 16 24 11
>>> putStr $ displayEnigmaOperation cfg "KRIEG" displayOpts{showsteps=False,steps=2}
    OHNKJYSBTEDMLCARWPGIXZQUFV  LFAP  10 16 24 06
K > CMAWFEKLNVG̲̅HBIUYTXZQOJDRPS  LFAQ  10 16 24 07
R > HXETCUMASQNZGKRYJO̲̅IDFWVBPL  LFAR  10 16 24 08
>>> putStr $ displayEnigmaOperation cfg "KRIEG" displayOpts{showsteps=False,steps=10}
    OHNKJYSBTEDMLCARWPGIXZQUFV  LFAP  10 16 24 06
K > CMAWFEKLNVG̲̅HBIUYTXZQOJDRPS  LFAQ  10 16 24 07
R > HXETCUMASQNZGKRYJO̲̅IDFWVBPL  LFAR  10 16 24 08
I > FGRJUABYW̲̅DZSXVQTOCLPENIMHK  LFAS  10 16 24 09
E > SJWYN̲̅UZPQBVXRETHIMAOFKCLDG  LFAT  10 16 24 10
G > EOKPAQW̲̅JLHCISTBDFVMNXRGUZY  LFAU  10 16 24 11
    IKOEDUXWAMBPJYCLSZQVFTHGNR  LFAV  10 16 24 12
    RSWOUZNXTQLKPGDMJABIEYCHVF  LFAW  10 16 24 13
    CUAMOTILGNWHDJERSPQFBZKYXV  LFAX  10 16 24 14
    HXPVYZKAOTGSRWICUMLJQDNBEF  LFAY  10 16 24 15
    QSXTPJNRUFMVKGZEAHBDILYCWO  LFAZ  10 16 24 16

to the "internal" format

>>> putStr $ displayEnigmaOperation cfg "KRIEG" displayOpts{format="internal",showsteps=False,steps=2}
    ABCDEFGHIJKLMNOPQRSTUVWXYZ
  P YBCDFEGHIJZPONMLQRSTXVWUAK         UX.MO.KZ.AY.EF.PL
  1 DMPSWGCROHXLBUIKTAQJZVEYFN  P  06  II
  2 BJYINTKWOARFEMVSGCUDPHZQLX  A  24  VIII
  3 ILHXUBZQPNVGKMCRTEJFADOYSW  F  16  V
  4 YDSKZPTNCHGQOMXAUWJFBRELVI  L  10  γ
  R ENKQAUYWJICOPBLMDXZVFTHRGS         b
  4 PUIBWTKJZSDXNHMFLVCGQYROAE         γ
  3 UFOVRTLCASMBNJWIHPYQEKZDXG         V
  2 JARTMLQVDBGYNEIUXKPFSOHZCW         VIII
  1 RMGAWYFJOTPLBZICSHDQNVEKXU         II
  P YBCDFEGHIJZPONMLQRSTXVWUAK         UX.MO.KZ.AY.EF.PL
    OHNKJYSBTEDMLCARWPGIXZQUFV

K > ABCDEFGHIJK̲̅LMNOPQRSTUVWXYZ
  P YBCDFEGHIJZ̲̅PONMLQRSTXVWUAK         UX.MO.KZ.AY.EF.PL
  1 LORVFBQNGWKATHJSZPIYUDXEMC̲̅  Q  07  II
  2 BJY̲̅INTKWOARFEMVSGCUDPHZQLX  A  24  VIII
  3 ILHXUBZQPNVGKMCRTEJFADOYS̲̅W  F  16  V
  4 YDSKZPTNCHGQOMXAUWJ̲̅FBRELVI  L  10  γ
  R ENKQAUYWJI̲̅COPBLMDXZVFTHRGS         b
  4 PUIBWTKJZ̲̅SDXNHMFLVCGQYROAE         γ
  3 UFOVRTLCASMBNJWIHPYQEKZDXG̲̅         V
  2 JARTMLQ̲̅VDBGYNEIUXKPFSOHZCW         VIII
  1 LFZVXEINSOKAYHBRG̲̅CPMUDJWTQ         II
  P YBCDFEG̲̅HIJZPONMLQRSTXVWUAK         UX.MO.KZ.AY.EF.PL
G < CMAWFEKLNVG̲̅HBIUYTXZQOJDRPS

R > ABCDEFGHIJKLMNOPQR̲̅STUVWXYZ
  P YBCDFEGHIJZPONMLQR̲̅STXVWUAK         UX.MO.KZ.AY.EF.PL
  1 NQUEAPMFVJZSGIRYOH̲̅XTCWDLBK  R  08  II
  2 BJYINTKW̲̅OARFEMVSGCUDPHZQLX  A  24  VIII
  3 ILHXUBZQPNVGKMCRTEJFADO̲̅YSW  F  16  V
  4 YDSKZPTNCHGQOMX̲̅AUWJFBRELVI  L  10  γ
  R ENKQAUYWJICOPBLMDXZVFTHR̲̅GS         b
  4 PUIBWTKJZSDXNHMFLV̲̅CGQYROAE         γ
  3 UFOVRTLCASMBNJWIHPYQEK̲̅ZDXG         V
  2 JARTMLQVDBG̲̅YNEIUXKPFSOHZCW         VIII
  1 EYUWDHM̲̅RNJZXGAQFBOLTCIVSPK         II
  P YBCDFEGHIJZPO̲̅NMLQRSTXVWUAK         UX.MO.KZ.AY.EF.PL
O < HXETCUMASQNZGKRYJO̲̅IDFWVBPL

and to some of the other formats

>>> putStr $ displayEnigmaOperation cfg "KRIEG" displayOpts{showencoding=True,format="windows",showsteps=True,steps=8}
000  LFAP
001  LFAQ  K > G
002  LFAR  R > O
003  LFAS  I > W
004  LFAT  E > N
005  LFAU  G > W
006  LFAV
007  LFAW
008  LFAX
>>> putStr $ displayEnigmaOperation cfg "KRIEG" displayOpts{format="config",showsteps=True,steps=8,showencoding=True}
000  b-γ-V-VIII-II LFAP UX.MO.KZ.AY.EF.PL 03.17.04.11
001  b-γ-V-VIII-II LFAQ UX.MO.KZ.AY.EF.PL 03.17.04.11  K > G
002  b-γ-V-VIII-II LFAR UX.MO.KZ.AY.EF.PL 03.17.04.11  R > O
003  b-γ-V-VIII-II LFAS UX.MO.KZ.AY.EF.PL 03.17.04.11  I > W
004  b-γ-V-VIII-II LFAT UX.MO.KZ.AY.EF.PL 03.17.04.11  E > N
005  b-γ-V-VIII-II LFAU UX.MO.KZ.AY.EF.PL 03.17.04.11  G > W
006  b-γ-V-VIII-II LFAV UX.MO.KZ.AY.EF.PL 03.17.04.11
007  b-γ-V-VIII-II LFAW UX.MO.KZ.AY.EF.PL 03.17.04.11
008  b-γ-V-VIII-II LFAX UX.MO.KZ.AY.EF.PL 03.17.04.11
>>> putStr $ displayEnigmaOperation cfg "KRIEG" displayOpts{format="encoding",showsteps=True,showencoding=False}
000
001  K > G
002  R > O
003  I > W
004  E > N
005  G > W

Note that first step of each of these displays represents the initial configuration of the machine, but does not perform any encoding (as explained in step).

Also also that the second block of the "internal" display example is the same as one illustrated for the "internal" format, where it is explained in detail.

listEnigmaOperation :: EnigmaConfig -> Message -> DisplayOpts -> [String] Source #

A list representation of the operation of an enigma machine, equivalent to

lines $ displayEnigmaOperation

Encoding display

displayEnigmaEncoding :: EnigmaConfig -> Message -> String Source #

Show the conventionally formatted encoding of a Message by an (initial) Enigma machine configuration.

>>> let cfg = configEnigma "c-β-V-VI-VIII" "CDTJ" "AE.BF.CM.DQ.HU.JN.LX.PR.SZ.VW" "05.16.05.12"
>>> putStr $ displayEnigmaEncoding cfg "FOLGENDES IST SOFORT BEKANNTZUGEBEN"
RBBF PMHP HGCZ XTDY GAHG UFXG EWKB LKGJ