4 <title>Pocket enigma
</title>
5 <meta http-equiv=
"Content-Type" content=
"text/html; charset=UTF-8"/>
6 <style type=
"text/css">
15 h1 { font-size:
3em; }
16 h2 { font-size:
2em; }
17 h3 { font-size:
1.6em; }
19 text-decoration: none;
22 -moz-border-radius:
5px;
23 -web-border-radius:
5px;
31 text-shadow:
0 0 20px #
333;
37 text-shadow:
0 0 20px #
333;
46 <textarea id=
"source">
50 ![centre-aligned Pocket Engima](pocket-enigma-small.jpg)
58 Emulates the Enigma machine from WWII
60 Mechanical cipher machine
63 * Substitution changes with every letter
65 Ciphering method: advance the wheel, then follow the lines to encipher the letter
67 ## Stateful enciphering
69 The cipher depends on the position of the wheel
71 We need to encapsulate that state
77 # The PocketEnigma object
79 What do we want it to do?
81 What data should the object hold?
85 # The PocketEnigma object
87 What do we want it to do?
89 * Initialise with the appropriate wheel (and possible starting position)
90 * Spin the wheel to a given position
91 * Advance the wheel one position
92 * Look up a letter given the wheel position
93 * Encipher a letter (advance the wheel then look up the letter)
94 * Encipher a message (optionally give the key)
95 * Make aliases for deciphering (same as enciphering)
98 * Accept user-defined wheels
99 * ...and validate them
101 What data should it hold?
103 * A description of the wheel being used
104 * The current position of the wheel
110 What's a convenient representation of the wheel
112 1. for the object to use internally
113 2. for a person to use to describe the wheel
115 They may not be the same, and we'll have to translate between them
121 ### Internal use: list of transpositions.
124 [
2,
3,
0,
1,
22,
8,
15,
12,
5, ...
127 so position
0 ('a') swaps with position
2 ('c'), position
3 ('d') swaps with position
1 ('b'), and so on.
129 * This will be a nightmare to enter correctly
131 ### Exernal use: list of pairs
134 [('a', 'c'), ('b', 'd'), ...]
139 * Need to validate the human-entered list, to check it's valid
143 # Validating the wheel description
149 # Validating the wheel specification
155 * ...and
26 letters mentioned overall
159 # Making the PocketEnigma class
162 class PocketEnigma(object):
163 def __init__(self, wheel=
1, position='a'):
164 self.wheel1 = [('a', 'z'), ('b', 'e'), ('c', 'x'), ('d', 'k'),
165 ('f', 'h'), ('g', 'j'), ('i', 'm'), ('l', 'r'), ('n', 'o'),
166 ('p', 'v'), ('q', 't'), ('s', 'u'), ('w', 'y')]
167 self.wheel2 = [('a', 'c'), ('b', 'd'), ('e', 'w'), ('f', 'i'),
168 ('g', 'p'), ('h', 'm'), ('j', 'k'), ('l', 'n'), ('o', 'q'),
169 ('r', 'z'), ('s', 'u'), ('t', 'v'), ('x', 'y')]
170 # Rest of initialisation code here
172 def make_wheel_map(self, wheel_spec):
177 def validate_wheel_spec(self, wheel_spec):
178 if len(wheel_spec) !=
13:
179 raise ValueError(
"Wheel specification has {} pairs, requires 13".
180 format(len(wheel_spec)))
186 # Looking up the enciphered version of a letter
188 *Not* advancing the wheel before
190 Keep `self.position` to record where the wheel is
192 * `__init__` can be passed a letter, but internally it's a number
194 But the wheel map only works if the wheel arrow is pointing at 'a'
198 1. Rotate the source letter back `position` spaces
200 3. Rotate the destination letter forward `position` spaces
206 <script src=
"http://gnab.github.io/remark/downloads/remark-0.6.0.min.js" type=
"text/javascript">
209 <script type=
"text/javascript"
210 src=
"http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML&delayStartupUntil=configured"></script>
212 <script type=
"text/javascript">
213 var slideshow = remark.create({ ratio:
"16:9" });
218 skipTags: ['script', 'noscript', 'style', 'textarea', 'pre']
221 MathJax.Hub.Queue(function() {
222 $(MathJax.Hub.getAllJax()).map(function(index, elem) {
223 return(elem.SourceElement());
224 }).parent().addClass('has-jax');
226 MathJax.Hub.Configured();