packages feed

crypto-enigma 0.1.1.1 → 0.1.1.2

raw patch · 8 files changed

+82/−115 lines, 8 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

CHANGELOG.md view
@@ -8,16 +8,13 @@ * [closed milestones]; and * [issues]. -### (0.0.3.?)+### [0.1.1.2] -* ([First stable release].)-* (Unicode checking for messages and letters.)-* (Force characters into map range or catch indexing errors in encoding.)-* (Further workflow changes: stack integration, Stackage, etc.)+Latest [release version], including fixes to documentation and CLI display bugs.  ### [0.1.1.1] -Latest [release version], including breaking API changes:+[Breaking API changes](https://github.com/orome/crypto-enigma-hs/compare/ef97f8ac..62d0ff59):  * Change to [handling errors with `Either`](http://hackage.haskell.org/package/mtl-2.2.2/docs/Control-Monad-Except.html#g:3)   ([rather than](https://stackoverflow.com/a/53456278/656912) `Except`, eliminating the dependency on `mtl`).@@ -151,6 +148,7 @@ [development version]: https://github.com/orome/crypto-enigma-hs/tree/develop [new CLI]: https://github.com/orome/crypto-enigma-hs/tree/new/cli +[0.1.1.2]: https://github.com/orome/crypto-enigma-hs/releases/tag/0.1.1.2 [0.1.1.1]: https://github.com/orome/crypto-enigma-hs/releases/tag/0.1.1.1 [0.0.3.1]: https://github.com/orome/crypto-enigma-hs/releases/tag/0.0.3.1 [0.0.2.14]: https://github.com/orome/crypto-enigma-hs/releases/tag/0.0.2.14
Crypto/Enigma.hs view
@@ -1,12 +1,11 @@ {-# OPTIONS_HADDOCK show-extensions #-}---{-# OPTIONS_GHC -fno-ignore-asserts #-} --REV: Use to keep asserts for valid 'Message'? <<< {-| Module      : Crypto.Enigma Description : Enigma machine simulator-Copyright   : (c) 2014-2018 Roy Levien+Copyright   : (c) 2014-2019 Roy Levien License     : BSD3 Maintainer  : royl@aldaron.com-Stability   : experimental+Stability   : provisional Portability : POSIX  An Enigma machine simulator with rudimentary display, currently limited to the I, M3, and M4 models.@@ -335,25 +334,29 @@ -- REV: Add checks for historical combinations of machine elements? configEnigma' :: String -> String -> String -> String -> Either EnigmaError EnigmaConfig configEnigma' rots winds plug rngs = do-        unless (and $ (==(length components')) <$> [length winds', length rngs']) (throwError BadNumbers)-        unless (rngs == (filter (`elem` "0123456789.") rngs)) (throwError (BadRings rngs))-        unless (and $ [(>=1),(<=26)] <*> rngs') (throwError (BadRings rngs))-        unless (and $ (`elem` letters) <$> winds') (throwError (BadWindows winds))+        unless (and $ (==(length components')) <$> [length winds', length rngs'])+                (Left $ BadNumbers)+        unless (rngs == (filter (`elem` "0123456789.") rngs))+                (Left $ BadRings rngs)+        unless (and $ [(>=1),(<=26)] <*> rngs')+                (Left $ BadRings rngs)+        unless (and $ (`elem` letters) <$> winds')+                (Left $ BadWindows winds)         unless (plug `elem` ["~",""," "] ||                        ((and $ (==2).length <$> splitOn "." plug) &&                         (and $ (`elem` letters) <$> filter (/='.') plug) &&-                        ((\s -> s == nub s) $ filter (/='.') plug))-               ) (throwError (BadPlugs plug))+                        ((\s -> s == nub s) $ filter (/='.') plug)))+                (Left $ BadPlugs plug)         unless (and $ (`M.member` comps_) <$> tail components')-                (throwError (BadComponents rots $ unwords $ filter (`notElem` (rotors ++ reflectors)) (init (tail components'))                                                 ))+                (Left $ BadComponents rots $ unwords $ filter (`notElem` (rotors ++ reflectors)) (init $ tail components'))         -- REV: Disallow no-op "keyboard" as component; disallow rotors as reflectors and vice versa <<< --         unless (and $ (`M.member` (rots_ `M.union` refs_)) <$> tail components')---                 (throwError (BadComponents rots $ unwords $ filter (`notElem` (rotors ++ reflectors)) (init (tail components'))                                                 ))+--                 (Left $ BadComponents rots $ unwords $ filter (`notElem` (rotors ++ reflectors)) (init $ tail components')) --         unless (and $ (`M.member` rots_) <$> init (tail components'))---                 (throwError (BadRotors rots $ unwords $ filter (`notElem` rotors) (init (tail components'))))+--                 (Left $ BadRotors rots $ unwords $ filter (`notElem` rotors) (init $ tail components')) --         unless ((last $ components') `M.member` refs_)---                 (throwError (BadReflector rots (last $ components')))-        return EnigmaConfig {+--                 (Left $ BadReflector rots (last $ components'))+        Right EnigmaConfig {                 components = components',                 positions = zipWith (\w r -> (mod (numA0 w - r + 1) 26) + 1) winds' rngs',                 rings = rngs'@@ -365,10 +368,6 @@         winds' = "A" ++ reverse winds ++ "A"         components' = reverse $ splitOn "-" $ rots ++ "-" ++ plug -        -- REV: Legacy placeholders from Except to Either change <<<-        throwError = Left       --fail.show would lose error type-        return = Right- -- Errors for use in configEnigma' data EnigmaError = BadNumbers                  | BadRings String@@ -396,7 +395,7 @@ arguments but errors with an informative message and a stack trace:  >>> configEnigma "c-β-V-III-II" "LQVI" "AM.EU.ZiL" "16.01.21.11"-*** Exception: Bad plugboard : AM.EU.ZiL+*** Exception: Bad plugboard: AM.EU.ZiL CallStack (from HasCallStack):   error, called at crypto-enigma/Crypto/Enigma.hs:317:21 in main:Crypto.Enigma @@ -406,9 +405,7 @@ *** Exception: Prelude.read: no parse -} configEnigma :: String -> String -> String -> String -> EnigmaConfig-configEnigma rots winds plug rngs = case configEnigma' rots winds plug rngs of-        Right cfg  -> cfg-        Left err -> error (show err)+configEnigma rots winds plug rngs = either (error.show) id (configEnigma' rots winds plug rngs)  {-| Read the elements of a conventional specification (see 'configEnigma') as a single string.
Crypto/Enigma/Display.hs view
@@ -2,10 +2,10 @@ {-| Module      : Crypto.Enigma.Display Description : Display of Enigma machine state and encoding-Copyright   : (c) 2014-2018 Roy Levien+Copyright   : (c) 2014-2019 Roy Levien License     : BSD3 Maintainer  : royl@aldaron.com-Stability   : experimental+Stability   : provisional Portability : POSIX  A module for rich display of the state of and encoding performed by Enigma machines defined in "Crypto.Enigma".@@ -42,10 +42,8 @@ import Crypto.Enigma.Utils import Crypto.Enigma --- REV: Final newline in show... functions is a bit inconsistent  - -- Machine display ===========================================================  @@ -189,7 +187,8 @@                 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 #showEnigmaConfigInternalFIG#+                This can be represented schematically (with input arriving and output exiting on the left)+                as #showEnigmaConfigInternalFIG#                  <<figs/configinternal.jpg>> @@ -291,21 +290,21 @@ -- Internal function used by all display functions to coerce all display options to valid values. validOpts_ :: DisplayOpts -> DisplayOpts validOpts_ opts = DisplayOpts {-                        format = case fmt of-                                  f | elem f fmts_ -> f-                                    | otherwise -> fmtsSingle_!!0,-                        showencoding = se,-                        markerspec = ms,-                        markerfunction_ = markerFunc_ ms,-                        showsteps = ss,-                        steps = if ns > 0 then ns else allSteps_-                        }-                        where-                                fmt = (format opts)-                                se = (showencoding opts)-                                ms = (markerspec opts)-                                ss = (showsteps opts)-                                ns = (steps opts)+        format = case fmt of+                  f | elem f fmts_ -> f+                    | otherwise -> fmtsSingle_!!0,+        showencoding = se,+        markerspec = ms,+        markerfunction_ = markerFunc_ ms,+        showsteps = ss,+        steps = if ns > 0 then ns else allSteps_+        }+        where+                fmt = (format opts)+                se = (showencoding opts)+                ms = (markerspec opts)+                ss = (showsteps opts)+                ns = (steps opts)   -- Configuration display -----------------------------------------------------@@ -399,15 +398,22 @@                             ps' = unwords $ (printf "%02d") <$> ps          showEnigmaConfigInternal_ =-                unlines $ [fmt (if ech == ' ' then "" else ech:" >") (markedMapping (head charLocs) letters (markerfunction_ opts)) ' ' 0 ""] +++                unlines $ [fmt (if ech == ' ' then "" else ech:" >")+                               (markedMapping (head charLocs) letters (markerfunction_ opts))+                               ' ' 0 ""+                          ] ++                           (zipWith5 fmt (init <> reverse $ ["P"] ++ (show <$> (tail.init $ stages ec)) ++ ["R"])-                                        (zipWith3 markedMapping (tail.init $ charLocs) (stageMappingList ec) (cycle [markerfunction_ opts]))+                                        (zipWith3 markedMapping+                                                        (tail.init $ charLocs)+                                                        (stageMappingList ec)+                                                        (cycle [markerfunction_ opts]))                                         (" " ++ (reverse $ windows ec) ++ replicate (length $ positions ec) ' ')                                         ([0] ++ ((tail.init $ positions ec)) ++ replicate (length $ positions ec) 0 )                                         (components ec ++ (tail $ reverse $ components ec))                           ) ++                           [fmt (if ech == ' ' then "" else (encode (enigmaMapping ec) ech):" <")-                               (markedMapping (last charLocs) (enigmaMapping ec) (markerfunction_ opts)) ' ' 0 ""]+                               (markedMapping (last charLocs) (enigmaMapping ec) (markerfunction_ opts))+                               ' ' 0 ""]                 where                     charLocs = zipWith (locCar ech)                                    ([letters] ++ stageMappingList ec ++ [enigmaMapping ec])@@ -559,18 +565,19 @@ -- starting configuration and for each character of the message, using the provided configuration display function. -- Note that while 'displayEnigmaOperation' indicate a 'Message' argument, it is this function that applies 'message'. listEnigmaOperation :: EnigmaConfig -> Message -> DisplayOpts -> [String]-listEnigmaOperation ec str optsin = zipWith3 (\n sec scr -> (fmtN  (showsteps opts) n) ++ (displayEnigmaConfig sec scr opts))-                                                      [0..(if (steps opts) < 0 then max (length msg) 1 else (steps opts))]-                                                      (iterate step ec)-                                                      (' ':msg ++ [' ',' '..])-                                                where-                                                    -- Ensure valid arguments-                                                    msg = message str-                                                    opts = validOpts_ optsin+listEnigmaOperation ec str optsin = zipWith3+                (\n sec scr -> (fmtN  (showsteps opts) n) ++ (displayEnigmaConfig sec scr opts))+                [0..(if (steps opts) < 0 then max (length msg) 1 else (steps opts))]+                (iterate step ec)+                (' ':msg ++ [' ',' '..])+        where+        -- Ensure valid arguments+                msg = message str+                opts = validOpts_ optsin -                                                    --fmtN :: Bool -> Int -> String-                                                    fmtN True n = (printf "%04d  " n) ++ (if elem (format opts) fmtsInternal_ then "\n" else "")-                                                    fmtN False _ = ""+                --fmtN :: Bool -> Int -> String+                fmtN True n = (printf "%04d  " n) ++ (if elem (format opts) fmtsInternal_ then "\n" else "")+                fmtN False _ = ""   -- Encoding display ==========================================================
LICENSE view
@@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2014-2018, Roy Levien+Copyright (c) 2014-2019, Roy Levien All rights reserved.  Redistribution and use in source and binary forms, with or without
README.md view
@@ -30,9 +30,9 @@  Show [configuration details]: -    >>> let cfg = configEnigma "b-γ-V-VIII-II" "LFAP" "UX.MO.KZ.AY.EF.PL" "03.17.04.11"-    >>> putStr $ showEnigmaConfigInternal cfg 'K'-    K > ABCDEFGHIJK̲̅LMNOPQRSTUVWXYZ+    >>> let cfg = configEnigma "b-γ-V-VIII-II" "LFAQ" "UX.MO.KZ.AY.EF.PL" "03.17.04.11"+    >>> putStr $ 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@@ -45,11 +45,10 @@       1 LFZVXEINSOKAYHBRG̲̅CPMUDJWTQ         II       P YBCDFEG̲̅HIJZPONMLQRSTXVWUAK         UX.MO.KZ.AY.EF.PL     G < CMAWFEKLNVG̲̅HBIUYTXZQOJDRPS- Simulate [machine operation]:      >>> let cfg = configEnigma "b-γ-V-VIII-II" "LFAP" "UX.MO.KZ.AY.EF.PL" "03.17.04.11"-    >>> putStr $ showEnigmaOperation cfg "KRIEG"+    >>> 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@@ -142,10 +141,14 @@ list of [open issues]. Some recent activity includes:  * [changes since](https://github.com/orome/crypto-enigma-hs/compare/hackage...develop#files_bucket) the latest Hackage-  release version; and+  release version; * the [addition of a command line interface](https://github.com/orome/crypto-enigma-hs/issues/13)   which incorporates [extensive changes](https://github.com/orome/crypto-enigma-hs/compare/1d303d3d...eb249974)-  [including](https://github.com/orome/crypto-enigma-hs/blob/develop/CHANGELOG.md#0031) refactoring of display functions.+  [including](https://github.com/orome/crypto-enigma-hs/blob/develop/CHANGELOG.md#0031) refactoring of display+  functions; and+* [breaking API changes](https://github.com/orome/crypto-enigma-hs/blob/develop/CHANGELOG.md#0111)+  [including](https://github.com/orome/crypto-enigma-hs/compare/ef97f8ac..62d0ff59) removal of deprecated display+  functions and change to handling of errors with `Either`.  [Python version]: https://pypi.python.org/pypi/crypto-enigma [documentation]: https://hackage.haskell.org/package/crypto-enigma
cli/enigma.hs view
@@ -134,14 +134,11 @@     configEnigmaFromString :: String -> EnigmaConfig     configEnigmaFromString i = if ((length $ words i) /= 4)                           then cliError ("Enigma machine configuration has the format 'rotors windows plugboard rings'")-                          else case configEnigma' c w s r of-                                    Right cfg  -> cfg-                                    Left err -> cliError (show err)-                                where [c, w, s, r] = words i+                          else either (cliError.show) id (configEnigma' c w s r) where [c, w, s, r] = words i      printConfig s True c = printConfig s False c >>                                 replicateM_ ((length $ lines c) + (if (length $ lines c) > 1 then 1 else 0))-                                            (clearLine >> cursorUpLine 1)+                                            (cursorUpLine 1 >> clearLine)     printConfig s False c = putStrLn c >>                                 (threadDelay (s * stepInterval_)) @@ -195,8 +192,8 @@  speedOptHelp = unlines [         "Pause between display of each step for SPEED*" ++ show ((fromIntegral stepInterval_) / 1000000) ++ "s;",-         "1 is the minimum speed with --overwrite; defaults to 0" ,-         "otherwise"]+         "1 is the minimum and default speed with --overwrite; ",+         "defaults to 0 otherwise"]  overwriteOptHelp = unlines [         "Overwrite each step after a pause (may result in" ,
crypto-enigma.cabal view
@@ -3,7 +3,7 @@ -- PVP summary:         +-+------- breaking API changes --                      | | +----- non-breaking API additions --                      | | | +--- code changes with no API change-version:                0.1.1.1+version:                0.1.1.2 synopsis:               An Enigma machine simulator with display.  description:            The crypto-enigma package is an Enigma machine simulator                         with rich display and machine state details.@@ -28,7 +28,7 @@ license-file:           LICENSE author:                 Roy Levien maintainer:             royl@aldaron.com-copyright:              (c) 2014-2018 Roy Levien+copyright:              (c) 2014-2019 Roy Levien category:               Cryptography, Education build-type:             Simple extra-source-files:     CHANGELOG.md@@ -45,7 +45,7 @@         type:           git         location:       git://github.com/orome/crypto-enigma-hs.git         branch:         hackage-        tag:            0.1.1.1+        tag:            0.1.1.2  library     -- default-extensions: Safe
test/Test.hs view
@@ -67,37 +67,16 @@         scfg         (lines $ displayEnigmaConfig cfg ch displayOpts{format="internal",markerspec=hl}) --- testShowConfig :: EnigmaConfig -> Char -> String -> Test--- testShowConfig cfg ch scfg = TestCase $ assertEqual ("Incorrect config display for " ++ show cfg)---         scfg---         (showEnigmaConfig cfg ch)---- testShowConfigIntenral :: EnigmaConfig -> Char -> [String] -> Test--- testShowConfigIntenral cfg ch scfg = TestCase $ assertEqual ("Incorrect internal config display for " ++ show cfg)---         scfg---         (lines $ showEnigmaConfigInternal cfg ch)- testDisplayOperation :: EnigmaConfig -> String -> String -> [String] -> Test testDisplayOperation cfg msg hl scfg = TestCase $ assertEqual ("Incorrect operation internal display for " ++ show cfg)         scfg         (lines $ displayEnigmaOperation cfg msg displayOpts{format="single",markerspec=hl}) ---- testShowOperation :: EnigmaConfig -> String -> [String] -> Test--- testShowOperation cfg msg sop = TestCase $ assertEqual ("Incorrect operation display for " ++ show cfg)---         sop---         (lines $ showEnigmaOperation cfg msg)- testDisplayOperationInternal :: EnigmaConfig -> String -> String -> [String] -> Test testDisplayOperationInternal cfg msg hl scfg = TestCase $ assertEqual ("Incorrect operation internal display for " ++ show cfg)         scfg         (lines $ displayEnigmaOperation cfg msg displayOpts{format="internal",markerspec=hl}) --- testShowOperationInternal :: EnigmaConfig -> String -> [String] -> Test--- testShowOperationInternal cfg msg sop = TestCase $ assertEqual ("Incorrect operation internal display for " ++ show cfg)---         sop---         (lines $ showEnigmaOperationInternal cfg msg)- testDisplayEncoding :: EnigmaConfig -> String -> [String] -> Test testDisplayEncoding cfg msg senc = TestCase $ assertEqual ("Incorrect encoding display for " ++ show cfg)         senc@@ -163,33 +142,19 @@                         "E > HEMVB\818\773GFAKZIWCQSXNTORYDLPUJ  XYZ  16 01 08",                 testDisplayConfig (configEnigma "A-I-II-III" "ABC" "OI.XC.QA.PL.FG.ER.TY" "02.07.25") ' ' "single" False "bars"                          "    YPLOUWXRMQTCIZDBJHVKESFGAN  ABC  26 22 05",---                 testShowConfig (configEnigma "C-III-II-I" "XYZ" "MJ.NH.RF.PL.ZS.DC" "09.25.19") 'E'---                         "E > HEMVB\818\773GFAKZIWCQSXNTORYDLPUJ  XYZ  16 01 08",---                 testShowConfig (configEnigma "A-I-II-III" "ABC" "OI.XC.QA.PL.FG.ER.TY" "02.07.25") ' '---                         "    YPLOUWXRMQTCIZDBJHVKESFGAN  ABC  26 22 05",                  testDisplayConfigInternal (configEnigma "b-γ-V-VIII-II" "LFAQ" "UX.MO.KZ.AY.EF.PL" "03.17.04.11") 'K' "bars"                         ["K > ABCDEFGHIJK\818\773LMNOPQRSTUVWXYZ         ","  P YBCDFEGHIJZ\818\773PONMLQRSTXVWUAK         UX.MO.KZ.AY.EF.PL","  1 LORVFBQNGWKATHJSZPIYUDXEMC\818\773  Q  07  II","  2 BJY\818\773INTKWOARFEMVSGCUDPHZQLX  A  24  VIII","  3 ILHXUBZQPNVGKMCRTEJFADOYS\818\773W  F  16  V","  4 YDSKZPTNCHGQOMXAUWJ\818\773FBRELVI  L  10  \947","  R ENKQAUYWJI\818\773COPBLMDXZVFTHRGS         b","  4 PUIBWTKJZ\818\773SDXNHMFLVCGQYROAE         \947","  3 UFOVRTLCASMBNJWIHPYQEKZDXG\818\773         V","  2 JARTMLQ\818\773VDBGYNEIUXKPFSOHZCW         VIII","  1 LFZVXEINSOKAYHBRG\818\773CPMUDJWTQ         II","  P YBCDFEG\818\773HIJZPONMLQRSTXVWUAK         UX.MO.KZ.AY.EF.PL","G < CMAWFEKLNVG\818\773HBIUYTXZQOJDRPS         "],                 testDisplayConfigInternal (configEnigma "A-I-II-III" "LZR" "OI.XC.QA.PL.FG.ER.TY" "09.02.16") ' ' "bars"                          ["    ABCDEFGHIJKLMNOPQRSTUVWXYZ         ","  P QBXDRGFHOJKPMNILAESYUVWCTZ         OI.XC.QA.PL.FG.ER.TY","  1 DFHJANPRVTXLWCGUEYIKSQOMZB  R  03  III","  2 QGCLFMUKTWZDNJYVOESIBPRAHX  Z  25  II","  3 CIDANSWKQLTVEURPMXFYOZGBHJ  L  04  I","  R EJMZALYXVBWFCRQUONTSPIKHGD         A","  3 DXACMSWYBZHJQEUPIOFKNLGRTV         I","  2 XUCLREBYTNHDFMQVAWSIGPJZOK         II","  1 EZNAQBOCSDTLXFWGVHUJPIMKRY         III","  P QBXDRGFHOJKPMNILAESYUVWCTZ         OI.XC.QA.PL.FG.ER.TY","    XPOSZNUVJIRQWFCBLKDYGHMATE         "],---                 testShowConfigIntenral (configEnigma "b-γ-V-VIII-II" "LFAQ" "UX.MO.KZ.AY.EF.PL" "03.17.04.11") 'K'---                         ["K > ABCDEFGHIJK\818\773LMNOPQRSTUVWXYZ         ","  P YBCDFEGHIJZ\818\773PONMLQRSTXVWUAK         UX.MO.KZ.AY.EF.PL","  1 LORVFBQNGWKATHJSZPIYUDXEMC\818\773  Q  07  II","  2 BJY\818\773INTKWOARFEMVSGCUDPHZQLX  A  24  VIII","  3 ILHXUBZQPNVGKMCRTEJFADOYS\818\773W  F  16  V","  4 YDSKZPTNCHGQOMXAUWJ\818\773FBRELVI  L  10  \947","  R ENKQAUYWJI\818\773COPBLMDXZVFTHRGS         b","  4 PUIBWTKJZ\818\773SDXNHMFLVCGQYROAE         \947","  3 UFOVRTLCASMBNJWIHPYQEKZDXG\818\773         V","  2 JARTMLQ\818\773VDBGYNEIUXKPFSOHZCW         VIII","  1 LFZVXEINSOKAYHBRG\818\773CPMUDJWTQ         II","  P YBCDFEG\818\773HIJZPONMLQRSTXVWUAK         UX.MO.KZ.AY.EF.PL","G < CMAWFEKLNVG\818\773HBIUYTXZQOJDRPS         "],---                 testShowConfigIntenral (configEnigma "A-I-II-III" "LZR" "OI.XC.QA.PL.FG.ER.TY" "09.02.16") ' '---                         ["    ABCDEFGHIJKLMNOPQRSTUVWXYZ         ","  P QBXDRGFHOJKPMNILAESYUVWCTZ         OI.XC.QA.PL.FG.ER.TY","  1 DFHJANPRVTXLWCGUEYIKSQOMZB  R  03  III","  2 QGCLFMUKTWZDNJYVOESIBPRAHX  Z  25  II","  3 CIDANSWKQLTVEURPMXFYOZGBHJ  L  04  I","  R EJMZALYXVBWFCRQUONTSPIKHGD         A","  3 DXACMSWYBZHJQEUPIOFKNLGRTV         I","  2 XUCLREBYTNHDFMQVAWSIGPJZOK         II","  1 EZNAQBOCSDTLXFWGVHUJPIMKRY         III","  P QBXDRGFHOJKPMNILAESYUVWCTZ         OI.XC.QA.PL.FG.ER.TY","    XPOSZNUVJIRQWFCBLKDYGHMATE         "],                  testDisplayOperation (configEnigma "c-β-VI-VIII-V" "OMLQ" "AI.JF.CM.DQ.HU.LX.PR.SZ" "03.16.04.11") "UBOOT" "bars"                         ["    LQZRYKTWJIFAXUVSBDPGNOHMEC  OMLQ  13 24 09 07","U > TDRBJWSNVEPMLHUKXCGAO\818\773IFQZY  OMLR  13 24 09 08","B > VK\818\773JTYSXMLCBIHRZWUNFDQAPGEO  OMLS  13 24 09 09","O > VTSFJDZWNEPRUIY\818\773KXLCBMAHQOG  OMLT  13 24 09 10","O > VYPSMILKFQHGEZW\818\773CJUDXRAOTBN  OMLU  13 24 09 11","T > BARPQGFWLTUIZXVDECYJ\818\773KOHNSM  OMLV  13 24 09 12"],                 testDisplayOperation (configEnigma "b-γ-V-VIII-II" "LFAP" "UX.MO.KZ.AY.EF.PL" "03.17.04.11") "KRIEG" "bars"                         ["    OHNKJYSBTEDMLCARWPGIXZQUFV  LFAP  10 16 24 06","K > CMAWFEKLNVG\818\773HBIUYTXZQOJDRPS  LFAQ  10 16 24 07","R > HXETCUMASQNZGKRYJO\818\773IDFWVBPL  LFAR  10 16 24 08","I > FGRJUABYW\818\773DZSXVQTOCLPENIMHK  LFAS  10 16 24 09","E > SJWYN\818\773UZPQBVXRETHIMAOFKCLDG  LFAT  10 16 24 10","G > EOKPAQW\818\773JLHCISTBDFVMNXRGUZY  LFAU  10 16 24 11"],---                 testShowOperation (configEnigma "c-β-VI-VIII-V" "OMLQ" "AI.JF.CM.DQ.HU.LX.PR.SZ" "03.16.04.11") "UBOOT"---                         ["    LQZRYKTWJIFAXUVSBDPGNOHMEC  OMLQ  13 24 09 07","U > TDRBJWSNVEPMLHUKXCGAO\818\773IFQZY  OMLR  13 24 09 08","B > VK\818\773JTYSXMLCBIHRZWUNFDQAPGEO  OMLS  13 24 09 09","O > VTSFJDZWNEPRUIY\818\773KXLCBMAHQOG  OMLT  13 24 09 10","O > VYPSMILKFQHGEZW\818\773CJUDXRAOTBN  OMLU  13 24 09 11","T > BARPQGFWLTUIZXVDECYJ\818\773KOHNSM  OMLV  13 24 09 12"],---                 testShowOperation (configEnigma "b-γ-V-VIII-II" "LFAP" "UX.MO.KZ.AY.EF.PL" "03.17.04.11") "KRIEG"---                         ["    OHNKJYSBTEDMLCARWPGIXZQUFV  LFAP  10 16 24 06","K > CMAWFEKLNVG\818\773HBIUYTXZQOJDRPS  LFAQ  10 16 24 07","R > HXETCUMASQNZGKRYJO\818\773IDFWVBPL  LFAR  10 16 24 08","I > FGRJUABYW\818\773DZSXVQTOCLPENIMHK  LFAS  10 16 24 09","E > SJWYN\818\773UZPQBVXRETHIMAOFKCLDG  LFAT  10 16 24 10","G > EOKPAQW\818\773JLHCISTBDFVMNXRGUZY  LFAU  10 16 24 11"],                  testDisplayOperationInternal (configEnigma "b-β-II-IV-V" "MLKQ" "UJ.LK.BV.SF.ZX.QA" "11.12.19.01") "SIE" "bars"                         ["    ABCDEFGHIJKLMNOPQRSTUVWXYZ         ","  P QVCDESGHIULKMNOPARFTJBWZYX         UJ.LK.BV.SF.ZX.QA","  1 KGWTAYPOMUFJLBQSDIEZCNXRVH  Q  17  V","  2 BOSLKUEJMAWDXHRIGYCQZPFTVN  K  19  IV","  3 AJDKSIRUXBLHWTMCQGZNPYFVOE  L  01  II","  4 WHTALGVUNZOKBPRYIXEDSFMQJC  M  03  \946","  R ENKQAUYWJICOPBLMDXZVFTHRGS         b","  4 DMZTSVFBQYLEWIKNXOUCHGARPJ         \946","  3 AJPCZWRLFBDKOTYUQGENHXMIVS         II","  2 JASLGWQNPHEDIZBVTOCXFYKMRU         IV","  1 ENUQSKBZRLAMIVHGOXPDJYCWFT         V","  P QVCDESGHIULKMNOPARFTJBWZYX         UJ.LK.BV.SF.ZX.QA","    IENSBJTYAFXQUCZVLWDGMPRKHO         ","","S > ABCDEFGHIJKLMNOPQRS\818\773TUVWXYZ         ","  P QVCDESGHIULKMNOPARF\818\773TJBWZYX         UJ.LK.BV.SF.ZX.QA","  1 FVSZXO\818\773NLTEIKAPRCHDYBMWQUGJ  R  18  V","  2 BOSLKUEJMAWDXHR\818\773IGYCQZPFTVN  K  19  IV","  3 AJDKSIRUXBLHWTMCQG\818\773ZNPYFVOE  L  01  II","  4 WHTALGV\818\773UNZOKBPRYIXEDSFMQJC  M  03  \946","  R ENKQAUYWJICOPBLMDXZVFT\818\773HRGS         b","  4 DMZTSVFBQYLEWIKNXOUC\818\773HGARPJ         \946","  3 AJP\818\773CZWRLFBDKOTYUQGENHXMIVS         II","  2 JASLGWQNPHEDIZBV\818\773TOCXFYKMRU         IV","  1 MTPRJAYQKZLHUGFNWOCIXB\818\773VESD         V","  P QV\818\773CDESGHIULKMNOPARFTJBWZYX         UJ.LK.BV.SF.ZX.QA","V < XTYNLIMZFRQEGDWUKJV\818\773BPSOACH         ","","I > ABCDEFGHI\818\773JKLMNOPQRSTUVWXYZ         ","  P QVCDESGHI\818\773ULKMNOPARFTJBWZYX         UJ.LK.BV.SF.ZX.QA","  1 URYWNMKSD\818\773HJZOQBGCXALVPTFIE  S  19  V","  2 BOSL\818\773KUEJMAWDXHRIGYCQZPFTVN  K  19  IV","  3 AJDKSIRUXBLH\818\773WTMCQGZNPYFVOE  L  01  II","  4 WHTALGVU\818\773NZOKBPRYIXEDSFMQJC  M  03  \946","  R ENKQAUYWJICOPBLMDXZVF\818\773THRGS         b","  4 DMZTSV\818\773FBQYLEWIKNXOUCHGARPJ         \946","  3 AJPCZWRLFBDKOTYUQGENHX\818\773MIVS         II","  2 JASLGWQNPHEDIZBVTOCXFYKM\818\773RU         IV","  1 SOQIZXPJYKGTF\818\773EMVNBHWAUDRCL         V","  P QVCDES\818\773GHIULKMNOPARFTJBWZYX         UJ.LK.BV.SF.ZX.QA","S < XKWOFEZPS\818\773MBUJVDHTYIQLNCARG         ","","E > ABCDE\818\773FGHIJKLMNOPQRSTUVWXYZ         ","  P QVCDE\818\773SGHIULKMNOPARFTJBWZYX         UJ.LK.BV.SF.ZX.QA","  1 QXVML\818\773JRCGIYNPAFBWZKUOSEHDT  T  20  V","  2 BOSLKUEJMAWD\818\773XHRIGYCQZPFTVN  K  19  IV","  3 AJDK\818\773SIRUXBLHWTMCQGZNPYFVOE  L  01  II","  4 WHTALGVUNZO\818\773KBPRYIXEDSFMQJC  M  03  \946","  R ENKQAUYWJICOPBL\818\773MDXZVFTHRGS         b","  4 DMZTSVFBQYLE\818\773WIKNXOUCHGARPJ         \946","  3 AJPCZ\818\773WRLFBDKOTYUQGENHXMIVS         II","  2 JASLGWQNPHEDIZBVTOCXFYKMRU\818\773         IV","  1 NPHYWOIXJFSEDLUMAGVZT\818\773CQBKR         V","  P QVCDESGHIULKMNOPARFT\818\773JBWZYX         UJ.LK.BV.SF.ZX.QA","T < PIJYT\818\773OQWBCNXRKFAGMZEVUHLDS         ",""],---                 testShowOperationInternal (configEnigma "b-β-II-IV-V" "MLKQ" "UJ.LK.BV.SF.ZX.QA" "11.12.19.01") "SIE"---                         ["    ABCDEFGHIJKLMNOPQRSTUVWXYZ         ","  P QVCDESGHIULKMNOPARFTJBWZYX         UJ.LK.BV.SF.ZX.QA","  1 KGWTAYPOMUFJLBQSDIEZCNXRVH  Q  17  V","  2 BOSLKUEJMAWDXHRIGYCQZPFTVN  K  19  IV","  3 AJDKSIRUXBLHWTMCQGZNPYFVOE  L  01  II","  4 WHTALGVUNZOKBPRYIXEDSFMQJC  M  03  \946","  R ENKQAUYWJICOPBLMDXZVFTHRGS         b","  4 DMZTSVFBQYLEWIKNXOUCHGARPJ         \946","  3 AJPCZWRLFBDKOTYUQGENHXMIVS         II","  2 JASLGWQNPHEDIZBVTOCXFYKMRU         IV","  1 ENUQSKBZRLAMIVHGOXPDJYCWFT         V","  P QVCDESGHIULKMNOPARFTJBWZYX         UJ.LK.BV.SF.ZX.QA","    IENSBJTYAFXQUCZVLWDGMPRKHO         ","","S > ABCDEFGHIJKLMNOPQRS\818\773TUVWXYZ         ","  P QVCDESGHIULKMNOPARF\818\773TJBWZYX         UJ.LK.BV.SF.ZX.QA","  1 FVSZXO\818\773NLTEIKAPRCHDYBMWQUGJ  R  18  V","  2 BOSLKUEJMAWDXHR\818\773IGYCQZPFTVN  K  19  IV","  3 AJDKSIRUXBLHWTMCQG\818\773ZNPYFVOE  L  01  II","  4 WHTALGV\818\773UNZOKBPRYIXEDSFMQJC  M  03  \946","  R ENKQAUYWJICOPBLMDXZVFT\818\773HRGS         b","  4 DMZTSVFBQYLEWIKNXOUC\818\773HGARPJ         \946","  3 AJP\818\773CZWRLFBDKOTYUQGENHXMIVS         II","  2 JASLGWQNPHEDIZBV\818\773TOCXFYKMRU         IV","  1 MTPRJAYQKZLHUGFNWOCIXB\818\773VESD         V","  P QV\818\773CDESGHIULKMNOPARFTJBWZYX         UJ.LK.BV.SF.ZX.QA","V < XTYNLIMZFRQEGDWUKJV\818\773BPSOACH         ","","I > ABCDEFGHI\818\773JKLMNOPQRSTUVWXYZ         ","  P QVCDESGHI\818\773ULKMNOPARFTJBWZYX         UJ.LK.BV.SF.ZX.QA","  1 URYWNMKSD\818\773HJZOQBGCXALVPTFIE  S  19  V","  2 BOSL\818\773KUEJMAWDXHRIGYCQZPFTVN  K  19  IV","  3 AJDKSIRUXBLH\818\773WTMCQGZNPYFVOE  L  01  II","  4 WHTALGVU\818\773NZOKBPRYIXEDSFMQJC  M  03  \946","  R ENKQAUYWJICOPBLMDXZVF\818\773THRGS         b","  4 DMZTSV\818\773FBQYLEWIKNXOUCHGARPJ         \946","  3 AJPCZWRLFBDKOTYUQGENHX\818\773MIVS         II","  2 JASLGWQNPHEDIZBVTOCXFYKM\818\773RU         IV","  1 SOQIZXPJYKGTF\818\773EMVNBHWAUDRCL         V","  P QVCDES\818\773GHIULKMNOPARFTJBWZYX         UJ.LK.BV.SF.ZX.QA","S < XKWOFEZPS\818\773MBUJVDHTYIQLNCARG         ","","E > ABCDE\818\773FGHIJKLMNOPQRSTUVWXYZ         ","  P QVCDE\818\773SGHIULKMNOPARFTJBWZYX         UJ.LK.BV.SF.ZX.QA","  1 QXVML\818\773JRCGIYNPAFBWZKUOSEHDT  T  20  V","  2 BOSLKUEJMAWD\818\773XHRIGYCQZPFTVN  K  19  IV","  3 AJDK\818\773SIRUXBLHWTMCQGZNPYFVOE  L  01  II","  4 WHTALGVUNZO\818\773KBPRYIXEDSFMQJC  M  03  \946","  R ENKQAUYWJICOPBL\818\773MDXZVFTHRGS         b","  4 DMZTSVFBQYLE\818\773WIKNXOUCHGARPJ         \946","  3 AJPCZ\818\773WRLFBDKOTYUQGENHXMIVS         II","  2 JASLGWQNPHEDIZBVTOCXFYKMRU\818\773         IV","  1 NPHYWOIXJFSEDLUMAGVZT\818\773CQBKR         V","  P QVCDESGHIULKMNOPARFT\818\773JBWZYX         UJ.LK.BV.SF.ZX.QA","T < PIJYT\818\773OQWBCNXRKFAGMZEVUHLDS         ",""],                  testDisplayEncoding (configEnigma "c-β-V-VI-VIII" (enigmaEncoding (configEnigma "c-β-V-VI-VIII" "NAEM" "AE.BF.CM.DQ.HU.JN.LX.PR.SZ.VW" "05.16.05.12") "QEOB") "AE.BF.CM.DQ.HU.JN.LX.PR.SZ.VW" "05.16.05.12")                         "KRKR ALLE XX FOLGENDES IST SOFORT BEKANNTZUGEBEN XX ICH HABE FOLGELNBE BEFEHL ERHALTEN XX J ANSTERLE DES BISHERIGXN REICHSMARSCHALLS J GOERING J SETZT DER FUEHRER SIE Y HVRR GRZSSADMIRAL Y ALS SEINEN NACHFOLGER EIN X SCHRIFTLSCHE VOLLMACHT UNTERWEGS X ABSOFORT SOLLEN SIE SAEMTLICHE MASSNAHMEN VERFUEGEN Y DIE SICH AUS DER GEGENWAERTIGEN LAGE ERGEBEN X GEZ X REICHSLEITEI KK TULPE KK J BORMANN J XX OB.D.MMM DURNH FKST.KOM.ADM.UUU BOOIE.KP"