Copyright | (c) 2014-2019 Roy Levien |
---|---|
License | BSD3 |
Maintainer | royl@aldaron.com |
Stability | provisional |
Portability | POSIX |
Safe Haskell | Safe |
Language | Haskell2010 |
Crypto.Enigma.Display
Description
A module for rich display of the state of and encoding performed by Enigma machines defined in Crypto.Enigma.
Synopsis
- data DisplayOpts
- displayOpts :: DisplayOpts
- format :: DisplayOpts -> Format
- showencoding :: DisplayOpts -> Bool
- markerspec :: DisplayOpts -> MarkerSpec
- showsteps :: DisplayOpts -> Bool
- steps :: DisplayOpts -> DisplaySteps
- type Format = String
- type MarkerSpec = String
- type DisplaySteps = Int
- displayEnigmaConfig :: EnigmaConfig -> Char -> DisplayOpts -> String
- displayEnigmaOperation :: EnigmaConfig -> Message -> DisplayOpts -> String
- listEnigmaOperation :: EnigmaConfig -> Message -> DisplayOpts -> [String]
- displayEnigmaEncoding :: EnigmaConfig -> Message -> String
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 (seewindows
), and thePosition
s of the rotors (seepositions
).Any valid letter being encoded (see
showencoding
) by the configuration is indicated as input, and the encoding of the letter is marked (seemarkerspec
).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 (seestageMappingList
), along with an indication of the stage (rotor number,"P"
for plugboard, or"R"
for reflector), window letter (seewindows
),Position
(seepositions
) andName
, 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 (seemarkerspec
).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 (seeName
), to'Z'
, which is then - encoded by the first rotor (
'1'
), a"II"
rotor in the07
position (and'Q'
at the window), to'C'
, which is then - encoded by the second rotor (
'2'
), a"VIII"
rotor in the24
position (and'A'
at the window), to'Y'
, which is then - encoded by the third rotor (
'3'
), a"V"
rotor in the16
position (and'F'
at the window), to'S'
, which is then - encoded by the fourth rotor (
'4'
), a"γ"
rotor in the10
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 byconfigEnigma
andconfigEnigmaExcept
, 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 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 #
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 format
s
>>>
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