5 <meta name=
"viewport" content=
"width=device-width, initial-scale=1, minimum-scale=1" />
6 <meta name=
"generator" content=
"pdoc 0.9.2" />
7 <title>szyfrow.pocket_enigma API documentation
</title>
8 <meta name=
"description" content=
"The Pocket Enigma machine, a simple example that illustrates the mechanisms
9 of the Enigma machine. See [a …" />
10 <link rel=
"preload stylesheet" as=
"style" href=
"https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity=
"sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin
>
11 <link rel=
"preload stylesheet" as=
"style" href=
"https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity=
"sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin
>
12 <link rel=
"stylesheet preload" as=
"style" href=
"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin
>
13 <style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:
1.5em}#content{padding:
20px}#sidebar{padding:
30px;overflow:hidden}#sidebar
> *:last-child{margin-bottom:
2cm}.http-server-breadcrumbs{font-size:
130%;margin:
0 0 15px
0}#footer{font-size:
.75em;padding:
5px
30px;border-top:
1px solid #ddd;text-align:right}#footer p{margin:
0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:
30px}h1,h2,h3,h4,h5{font-weight:
300}h1{font-size:
2.5em;line-height:
1.1em}h2{font-size:
1.75em;margin:
1em
0 .50em
0}h3{font-size:
1.4em;margin:
25px
0 10px
0}h4{margin:
0;font-size:
105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:
.2em
0}a{color:#
058;text-decoration:none;transition:color
.3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^=
"header-"]{margin-top:
2em}.ident{color:#
900}pre code{background:#f8f8f8;font-size:
.8em;line-height:
1.4em}code{background:#f2f2f1;padding:
1px
4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:
0;border-top:
1px solid #ccc;border-bottom:
1px solid #ccc;margin:
1em
0;padding:
1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:
10%}#http-server-module-list p{margin-top:
0}.toc ul,#index{list-style-type:none;margin:
0;padding:
0}#index code{background:transparent}#index h3{border-bottom:
1px solid #ddd}#index ul{padding:
0}#index h4{margin-top:
.6em;font-weight:bold}@media (min-width:
200ex){#index .two-column{column-count:
2}}@media (min-width:
300ex){#index .two-column{column-count:
3}}dl{margin-bottom:
2em}dl dl:last-child{margin-bottom:
4em}dd{margin:
0 0 1em
3em}#header-classes + dl
> dd{margin-bottom:
3em}dd dd{margin-left:
2em}dd p{margin:
10px
0}.name{background:#eee;font-weight:bold;font-size:
.85em;padding:
5px
10px;display:inline-block;min-width:
40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name
> span:first-child{white-space:nowrap}.name.class
> span:nth-child(
2){margin-left:
.4em}.inherited{color:#
999;border-left:
5px solid #eee;padding-left:
1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:
400;font-size:
1.25em}.desc h3{font-size:
1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#
666;text-align:right;font-weight:
400;font-size:
.8em;text-transform:uppercase}.source summary
> *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:
1em}.source pre{max-height:
500px;overflow:auto;margin:
0}.source pre code{font-size:
12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\
2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:
1em}img{max-width:
100%}td{padding:
0 .5em}.admonition{padding:
.1em
.5em;margin-bottom:
1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}
</style>
14 <style media=
"screen and (min-width: 700px)">@media screen and (min-width:
700px){#sidebar{width:
30%;height:
100vh;overflow:auto;position:sticky;top:
0}#content{width:
70%;max-width:
100ch;padding:
3em
4em;border-left:
1px solid #ddd}pre code{font-size:
1em}.item .name{font-size:
1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:
1.5em}.toc
> ul
> li{margin-top:
.5em}}
</style>
15 <style media=
"print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#
000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:
" (" attr(href)
")";font-size:
90%}a[href][title]:after{content:none}abbr[title]:after{content:
" (" attr(title)
")"}.ir a:after,a[href^=
"javascript:"]:after,a[href^=
"#"]:after{content:
""}pre,blockquote{border:
1px solid #
999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:
100% !important}@page{margin:
0.5cm}p,h2,h3{orphans:
3;widows:
3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}
</style>
16 <script defer
src=
"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity=
"sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin
></script>
17 <script>window.addEventListener('DOMContentLoaded', () =
> hljs.initHighlighting())
</script>
21 <article id=
"content">
23 <h1 class=
"title">Module
<code>szyfrow.pocket_enigma
</code></h1>
25 <section id=
"section-intro">
26 <p>The Pocket Enigma machine, a simple example that illustrates the mechanisms
27 of the Enigma machine. See
<a href=
"http://www.savory.de/pocket_enigma.htm">a review
</a>
28 for more information about the machine.
</p>
29 <details class=
"source">
31 <span>Expand source code
</span>
33 <pre><code class=
"python">"""The Pocket Enigma machine, a simple example that illustrates the mechanisms
34 of the Enigma machine. See [a review](http://www.savory.de/pocket_enigma.htm)
35 for more information about the machine.
38 from szyfrow.support.utilities import *
39 from szyfrow.support.language_models import *
42 class PocketEnigma(object):
43 """A pocket enigma machine
44 The wheel is internally represented as a
26-element list self.wheel_map,
45 where wheel_map[i] == j shows that the position i places on from the arrow
46 maps to the position j places on.
48 def __init__(self, wheel=
1, position=
'a
'):
49 """initialise the pocket enigma, including which wheel to use and the
50 starting position of the wheel.
52 The wheel is either
1 or
2 (the predefined wheels) or a list of letter
55 The position is the letter pointed to by the arrow on the wheel.
57 >>> pe.wheel_map
58 [
25,
4,
23,
10,
1,
7,
9,
5,
12,
6,
3,
17,
8,
14,
13,
21,
19,
11,
20,
16,
18,
15,
24,
2,
22,
0]
59 >>> pe.position
62 self.wheel1 = [(
'a
',
'z
'), (
'b
',
'e
'), (
'c
',
'x
'), (
'd
',
'k
'),
63 (
'f
',
'h
'), (
'g
',
'j
'), (
'i
',
'm
'), (
'l
',
'r
'), (
'n
',
'o
'),
64 (
'p
',
'v
'), (
'q
',
't
'), (
's
',
'u
'), (
'w
',
'y
')]
65 self.wheel2 = [(
'a
',
'c
'), (
'b
',
'd
'), (
'e
',
'w
'), (
'f
',
'i
'),
66 (
'g
',
'p
'), (
'h
',
'm
'), (
'j
',
'k
'), (
'l
',
'n
'), (
'o
',
'q
'),
67 (
'r
',
'z
'), (
's
',
'u
'), (
't
',
'v
'), (
'x
',
'y
')]
69 self.make_wheel_map(self.wheel1)
71 self.make_wheel_map(self.wheel2)
73 self.validate_wheel_spec(wheel)
74 self.make_wheel_map(wheel)
75 if position in string.ascii_lowercase:
76 self.position = pos(position)
78 self.position = position
80 def make_wheel_map(self, wheel_spec):
81 """Expands a wheel specification from a list of letter-letter pairs
82 into a full wheel_map.
84 >>> pe.make_wheel_map(pe.wheel2)
85 [
2,
3,
0,
1,
22,
8,
15,
12,
5,
10,
9,
13,
7,
11,
16,
6,
14,
25,
20,
21,
18,
19,
4,
24,
23,
17]
87 self.validate_wheel_spec(wheel_spec)
88 self.wheel_map = [
0] *
26
90 self.wheel_map[pos(p[
0])] = pos(p[
1])
91 self.wheel_map[pos(p[
1])] = pos(p[
0])
94 def validate_wheel_spec(self, wheel_spec):
95 """Validates that a wheel specificaiton will turn into a valid wheel
98 >>> pe.validate_wheel_spec([])
99 Traceback (most recent call last):
101 ValueError: Wheel specification has
0 pairs, requires
13
102 >>> pe.validate_wheel_spec([(
'a
',
'b
',
'c
')]*
13)
103 Traceback (most recent call last):
105 ValueError: Not all mappings in wheel specificationhave two elements
106 >>> pe.validate_wheel_spec([(
'a
',
'b
')]*
13)
107 Traceback (most recent call last):
109 ValueError: Wheel specification does not contain
26 letters
111 if len(wheel_spec) !=
13:
112 raise ValueError(
"Wheel specification has {} pairs, requires
13".
113 format(len(wheel_spec)))
116 raise ValueError(
"Not all mappings in wheel specification
"
117 "have two elements
")
118 if len(set([p[
0] for p in wheel_spec] +
119 [p[
1] for p in wheel_spec])) !=
26:
120 raise ValueError(
"Wheel specification does not contain
26 letters
")
122 def encipher_letter(self, letter):
123 """Enciphers a single letter, by advancing the wheel before looking up
124 the letter on the wheel.
126 >>> pe.set_position(
'f
')
128 >>> pe.encipher_letter(
'k
')
132 return self.lookup(letter)
133 decipher_letter = encipher_letter
135 def lookup(self, letter):
136 """Look up what a letter enciphers to, without turning the wheel.
138 >>> pe.set_position(
'f
')
140 >>> cat([pe.lookup(l) for l in string.ascii_lowercase])
141 'udhbfejcpgmokrliwntsayqzvx
'
142 >>> pe.lookup(
'A
')
145 if letter in string.ascii_lowercase:
147 (self.wheel_map[(pos(letter) - self.position) %
26] +
153 """Advances the wheel one position.
155 >>> pe.set_position(
'f
')
157 >>> pe.advance()
160 self.position = (self.position +
1) %
26
163 def encipher(self, message, starting_position=None):
164 """Enciphers a whole message.
166 >>> pe.set_position(
'f
')
168 >>> pe.encipher(
'helloworld
')
170 >>> pe.set_position(
'f
')
172 >>> pe.encipher(
'kjsglcjoqc
')
174 >>> pe.encipher(
'helloworld
', starting_position =
'x
')
177 if starting_position:
178 self.set_position(starting_position)
179 transformed =
''
181 transformed += self.encipher_letter(l)
185 def set_position(self, position):
186 """Sets the position of the wheel, by specifying the letter the arrow
189 >>> pe.set_position(
'a
')
191 >>> pe.set_position(
'm
')
193 >>> pe.set_position(
'z
')
196 self.position = pos(position)
200 def pocket_enigma_break_by_crib(message, wheel_spec, crib, crib_position):
201 """Break a pocket enigma using a crib (some plaintext that
's expected to
202 be in a certain position). Returns a list of possible starting wheel
203 positions that could produce the crib.
205 >>> pocket_enigma_break_by_crib(
'kzpjlzmoga
',
1,
'h
',
0)
206 [
'a
',
'f
',
'q
']
207 >>> pocket_enigma_break_by_crib(
'kzpjlzmoga
',
1,
'he
',
0)
209 >>> pocket_enigma_break_by_crib(
'kzpjlzmoga
',
1,
'll
',
2)
211 >>> pocket_enigma_break_by_crib(
'kzpjlzmoga
',
1,
'l
',
2)
213 >>> pocket_enigma_break_by_crib(
'kzpjlzmoga
',
1,
'l
',
3)
214 [
'a
',
'j
',
'n
']
215 >>> pocket_enigma_break_by_crib(
'aaaaa
',
1,
'l
',
3)
218 pe = PocketEnigma(wheel=wheel_spec)
219 possible_positions = []
220 for p in string.ascii_lowercase:
222 plaintext = pe.decipher(message)
223 if plaintext[crib_position:crib_position+len(crib)] == crib:
224 possible_positions += [p]
225 return possible_positions
227 if __name__ ==
"__main__
":
229 doctest.testmod(extraglobs={
'pe
': PocketEnigma(
1,
'a
')})
</code></pre>
237 <h2 class=
"section-title" id=
"header-functions">Functions
</h2>
239 <dt id=
"szyfrow.pocket_enigma.cat"><code class=
"name flex">
240 <span>def
<span class=
"ident">cat
</span></span>(
<span>iterable, /)
</span>
243 <div class=
"desc"><p>Concatenate any number of strings.
</p>
244 <p>The string whose method is called is inserted in between each given string.
245 The result is returned as a new string.
</p>
246 <p>Example: '.'.join(['ab', 'pq', 'rs']) -
> 'ab.pq.rs'
</p></div>
248 <dt id=
"szyfrow.pocket_enigma.lcat"><code class=
"name flex">
249 <span>def
<span class=
"ident">lcat
</span></span>(
<span>iterable, /)
</span>
252 <div class=
"desc"><p>Concatenate any number of strings.
</p>
253 <p>The string whose method is called is inserted in between each given string.
254 The result is returned as a new string.
</p>
255 <p>Example: '.'.join(['ab', 'pq', 'rs']) -
> 'ab.pq.rs'
</p></div>
257 <dt id=
"szyfrow.pocket_enigma.pocket_enigma_break_by_crib"><code class=
"name flex">
258 <span>def
<span class=
"ident">pocket_enigma_break_by_crib
</span></span>(
<span>message, wheel_spec, crib, crib_position)
</span>
261 <div class=
"desc"><p>Break a pocket enigma using a crib (some plaintext that's expected to
262 be in a certain position). Returns a list of possible starting wheel
263 positions that could produce the crib.
</p>
264 <pre><code class=
"language-python-repl">>>> pocket_enigma_break_by_crib('kzpjlzmoga',
1, 'h',
0)
266 >>> pocket_enigma_break_by_crib('kzpjlzmoga',
1, 'he',
0)
268 >>> pocket_enigma_break_by_crib('kzpjlzmoga',
1, 'll',
2)
270 >>> pocket_enigma_break_by_crib('kzpjlzmoga',
1, 'l',
2)
272 >>> pocket_enigma_break_by_crib('kzpjlzmoga',
1, 'l',
3)
274 >>> pocket_enigma_break_by_crib('aaaaa',
1, 'l',
3)
277 <details class=
"source">
279 <span>Expand source code
</span>
281 <pre><code class=
"python">def pocket_enigma_break_by_crib(message, wheel_spec, crib, crib_position):
282 """Break a pocket enigma using a crib (some plaintext that
's expected to
283 be in a certain position). Returns a list of possible starting wheel
284 positions that could produce the crib.
286 >>> pocket_enigma_break_by_crib(
'kzpjlzmoga
',
1,
'h
',
0)
287 [
'a
',
'f
',
'q
']
288 >>> pocket_enigma_break_by_crib(
'kzpjlzmoga
',
1,
'he
',
0)
290 >>> pocket_enigma_break_by_crib(
'kzpjlzmoga
',
1,
'll
',
2)
292 >>> pocket_enigma_break_by_crib(
'kzpjlzmoga
',
1,
'l
',
2)
294 >>> pocket_enigma_break_by_crib(
'kzpjlzmoga
',
1,
'l
',
3)
295 [
'a
',
'j
',
'n
']
296 >>> pocket_enigma_break_by_crib(
'aaaaa
',
1,
'l
',
3)
299 pe = PocketEnigma(wheel=wheel_spec)
300 possible_positions = []
301 for p in string.ascii_lowercase:
303 plaintext = pe.decipher(message)
304 if plaintext[crib_position:crib_position+len(crib)] == crib:
305 possible_positions += [p]
306 return possible_positions
</code></pre>
309 <dt id=
"szyfrow.pocket_enigma.wcat"><code class=
"name flex">
310 <span>def
<span class=
"ident">wcat
</span></span>(
<span>iterable, /)
</span>
313 <div class=
"desc"><p>Concatenate any number of strings.
</p>
314 <p>The string whose method is called is inserted in between each given string.
315 The result is returned as a new string.
</p>
316 <p>Example: '.'.join(['ab', 'pq', 'rs']) -
> 'ab.pq.rs'
</p></div>
321 <h2 class=
"section-title" id=
"header-classes">Classes
</h2>
323 <dt id=
"szyfrow.pocket_enigma.PocketEnigma"><code class=
"flex name class">
324 <span>class
<span class=
"ident">PocketEnigma
</span></span>
325 <span>(
</span><span>wheel=
1, position='a')
</span>
328 <div class=
"desc"><p>A pocket enigma machine
329 The wheel is internally represented as a
26-element list self.wheel_map,
330 where wheel_map[i] == j shows that the position i places on from the arrow
331 maps to the position j places on.
</p>
332 <p>initialise the pocket enigma, including which wheel to use and the
333 starting position of the wheel.
</p>
334 <p>The wheel is either
1 or
2 (the predefined wheels) or a list of letter
336 <p>The position is the letter pointed to by the arrow on the wheel.
</p>
337 <pre><code class=
"language-python-repl">>>> pe.wheel_map
338 [
25,
4,
23,
10,
1,
7,
9,
5,
12,
6,
3,
17,
8,
14,
13,
21,
19,
11,
20,
16,
18,
15,
24,
2,
22,
0]
339 >>> pe.position
342 <details class=
"source">
344 <span>Expand source code
</span>
346 <pre><code class=
"python">class PocketEnigma(object):
347 """A pocket enigma machine
348 The wheel is internally represented as a
26-element list self.wheel_map,
349 where wheel_map[i] == j shows that the position i places on from the arrow
350 maps to the position j places on.
352 def __init__(self, wheel=
1, position=
'a
'):
353 """initialise the pocket enigma, including which wheel to use and the
354 starting position of the wheel.
356 The wheel is either
1 or
2 (the predefined wheels) or a list of letter
359 The position is the letter pointed to by the arrow on the wheel.
361 >>> pe.wheel_map
362 [
25,
4,
23,
10,
1,
7,
9,
5,
12,
6,
3,
17,
8,
14,
13,
21,
19,
11,
20,
16,
18,
15,
24,
2,
22,
0]
363 >>> pe.position
366 self.wheel1 = [(
'a
',
'z
'), (
'b
',
'e
'), (
'c
',
'x
'), (
'd
',
'k
'),
367 (
'f
',
'h
'), (
'g
',
'j
'), (
'i
',
'm
'), (
'l
',
'r
'), (
'n
',
'o
'),
368 (
'p
',
'v
'), (
'q
',
't
'), (
's
',
'u
'), (
'w
',
'y
')]
369 self.wheel2 = [(
'a
',
'c
'), (
'b
',
'd
'), (
'e
',
'w
'), (
'f
',
'i
'),
370 (
'g
',
'p
'), (
'h
',
'm
'), (
'j
',
'k
'), (
'l
',
'n
'), (
'o
',
'q
'),
371 (
'r
',
'z
'), (
's
',
'u
'), (
't
',
'v
'), (
'x
',
'y
')]
373 self.make_wheel_map(self.wheel1)
375 self.make_wheel_map(self.wheel2)
377 self.validate_wheel_spec(wheel)
378 self.make_wheel_map(wheel)
379 if position in string.ascii_lowercase:
380 self.position = pos(position)
382 self.position = position
384 def make_wheel_map(self, wheel_spec):
385 """Expands a wheel specification from a list of letter-letter pairs
386 into a full wheel_map.
388 >>> pe.make_wheel_map(pe.wheel2)
389 [
2,
3,
0,
1,
22,
8,
15,
12,
5,
10,
9,
13,
7,
11,
16,
6,
14,
25,
20,
21,
18,
19,
4,
24,
23,
17]
391 self.validate_wheel_spec(wheel_spec)
392 self.wheel_map = [
0] *
26
394 self.wheel_map[pos(p[
0])] = pos(p[
1])
395 self.wheel_map[pos(p[
1])] = pos(p[
0])
396 return self.wheel_map
398 def validate_wheel_spec(self, wheel_spec):
399 """Validates that a wheel specificaiton will turn into a valid wheel
402 >>> pe.validate_wheel_spec([])
403 Traceback (most recent call last):
405 ValueError: Wheel specification has
0 pairs, requires
13
406 >>> pe.validate_wheel_spec([(
'a
',
'b
',
'c
')]*
13)
407 Traceback (most recent call last):
409 ValueError: Not all mappings in wheel specificationhave two elements
410 >>> pe.validate_wheel_spec([(
'a
',
'b
')]*
13)
411 Traceback (most recent call last):
413 ValueError: Wheel specification does not contain
26 letters
415 if len(wheel_spec) !=
13:
416 raise ValueError(
"Wheel specification has {} pairs, requires
13".
417 format(len(wheel_spec)))
420 raise ValueError(
"Not all mappings in wheel specification
"
421 "have two elements
")
422 if len(set([p[
0] for p in wheel_spec] +
423 [p[
1] for p in wheel_spec])) !=
26:
424 raise ValueError(
"Wheel specification does not contain
26 letters
")
426 def encipher_letter(self, letter):
427 """Enciphers a single letter, by advancing the wheel before looking up
428 the letter on the wheel.
430 >>> pe.set_position(
'f
')
432 >>> pe.encipher_letter(
'k
')
436 return self.lookup(letter)
437 decipher_letter = encipher_letter
439 def lookup(self, letter):
440 """Look up what a letter enciphers to, without turning the wheel.
442 >>> pe.set_position(
'f
')
444 >>> cat([pe.lookup(l) for l in string.ascii_lowercase])
445 'udhbfejcpgmokrliwntsayqzvx
'
446 >>> pe.lookup(
'A
')
449 if letter in string.ascii_lowercase:
451 (self.wheel_map[(pos(letter) - self.position) %
26] +
457 """Advances the wheel one position.
459 >>> pe.set_position(
'f
')
461 >>> pe.advance()
464 self.position = (self.position +
1) %
26
467 def encipher(self, message, starting_position=None):
468 """Enciphers a whole message.
470 >>> pe.set_position(
'f
')
472 >>> pe.encipher(
'helloworld
')
474 >>> pe.set_position(
'f
')
476 >>> pe.encipher(
'kjsglcjoqc
')
478 >>> pe.encipher(
'helloworld
', starting_position =
'x
')
481 if starting_position:
482 self.set_position(starting_position)
483 transformed =
''
485 transformed += self.encipher_letter(l)
489 def set_position(self, position):
490 """Sets the position of the wheel, by specifying the letter the arrow
493 >>> pe.set_position(
'a
')
495 >>> pe.set_position(
'm
')
497 >>> pe.set_position(
'z
')
500 self.position = pos(position)
501 return self.position
</code></pre>
505 <dt id=
"szyfrow.pocket_enigma.PocketEnigma.advance"><code class=
"name flex">
506 <span>def
<span class=
"ident">advance
</span></span>(
<span>self)
</span>
509 <div class=
"desc"><p>Advances the wheel one position.
</p>
510 <pre><code class=
"language-python-repl">>>> pe.set_position('f')
512 >>> pe.advance()
515 <details class=
"source">
517 <span>Expand source code
</span>
519 <pre><code class=
"python">def advance(self):
520 """Advances the wheel one position.
522 >>> pe.set_position(
'f
')
524 >>> pe.advance()
527 self.position = (self.position +
1) %
26
528 return self.position
</code></pre>
531 <dt id=
"szyfrow.pocket_enigma.PocketEnigma.decipher"><code class=
"name flex">
532 <span>def
<span class=
"ident">decipher
</span></span>(
<span>self, message, starting_position=None)
</span>
535 <div class=
"desc"><p>Enciphers a whole message.
</p>
536 <pre><code class=
"language-python-repl">>>> pe.set_position('f')
538 >>> pe.encipher('helloworld')
540 >>> pe.set_position('f')
542 >>> pe.encipher('kjsglcjoqc')
544 >>> pe.encipher('helloworld', starting_position = 'x')
547 <details class=
"source">
549 <span>Expand source code
</span>
551 <pre><code class=
"python">def encipher(self, message, starting_position=None):
552 """Enciphers a whole message.
554 >>> pe.set_position(
'f
')
556 >>> pe.encipher(
'helloworld
')
558 >>> pe.set_position(
'f
')
560 >>> pe.encipher(
'kjsglcjoqc
')
562 >>> pe.encipher(
'helloworld
', starting_position =
'x
')
565 if starting_position:
566 self.set_position(starting_position)
567 transformed =
''
569 transformed += self.encipher_letter(l)
570 return transformed
</code></pre>
573 <dt id=
"szyfrow.pocket_enigma.PocketEnigma.decipher_letter"><code class=
"name flex">
574 <span>def
<span class=
"ident">decipher_letter
</span></span>(
<span>self, letter)
</span>
577 <div class=
"desc"><p>Enciphers a single letter, by advancing the wheel before looking up
578 the letter on the wheel.
</p>
579 <pre><code class=
"language-python-repl">>>> pe.set_position('f')
581 >>> pe.encipher_letter('k')
584 <details class=
"source">
586 <span>Expand source code
</span>
588 <pre><code class=
"python">def encipher_letter(self, letter):
589 """Enciphers a single letter, by advancing the wheel before looking up
590 the letter on the wheel.
592 >>> pe.set_position(
'f
')
594 >>> pe.encipher_letter(
'k
')
598 return self.lookup(letter)
</code></pre>
601 <dt id=
"szyfrow.pocket_enigma.PocketEnigma.encipher"><code class=
"name flex">
602 <span>def
<span class=
"ident">encipher
</span></span>(
<span>self, message, starting_position=None)
</span>
605 <div class=
"desc"><p>Enciphers a whole message.
</p>
606 <pre><code class=
"language-python-repl">>>> pe.set_position('f')
608 >>> pe.encipher('helloworld')
610 >>> pe.set_position('f')
612 >>> pe.encipher('kjsglcjoqc')
614 >>> pe.encipher('helloworld', starting_position = 'x')
617 <details class=
"source">
619 <span>Expand source code
</span>
621 <pre><code class=
"python">def encipher(self, message, starting_position=None):
622 """Enciphers a whole message.
624 >>> pe.set_position(
'f
')
626 >>> pe.encipher(
'helloworld
')
628 >>> pe.set_position(
'f
')
630 >>> pe.encipher(
'kjsglcjoqc
')
632 >>> pe.encipher(
'helloworld
', starting_position =
'x
')
635 if starting_position:
636 self.set_position(starting_position)
637 transformed =
''
639 transformed += self.encipher_letter(l)
640 return transformed
</code></pre>
643 <dt id=
"szyfrow.pocket_enigma.PocketEnigma.encipher_letter"><code class=
"name flex">
644 <span>def
<span class=
"ident">encipher_letter
</span></span>(
<span>self, letter)
</span>
647 <div class=
"desc"><p>Enciphers a single letter, by advancing the wheel before looking up
648 the letter on the wheel.
</p>
649 <pre><code class=
"language-python-repl">>>> pe.set_position('f')
651 >>> pe.encipher_letter('k')
654 <details class=
"source">
656 <span>Expand source code
</span>
658 <pre><code class=
"python">def encipher_letter(self, letter):
659 """Enciphers a single letter, by advancing the wheel before looking up
660 the letter on the wheel.
662 >>> pe.set_position(
'f
')
664 >>> pe.encipher_letter(
'k
')
668 return self.lookup(letter)
</code></pre>
671 <dt id=
"szyfrow.pocket_enigma.PocketEnigma.lookup"><code class=
"name flex">
672 <span>def
<span class=
"ident">lookup
</span></span>(
<span>self, letter)
</span>
675 <div class=
"desc"><p>Look up what a letter enciphers to, without turning the wheel.
</p>
676 <pre><code class=
"language-python-repl">>>> pe.set_position('f')
678 >>> cat([pe.lookup(l) for l in string.ascii_lowercase])
679 'udhbfejcpgmokrliwntsayqzvx'
680 >>> pe.lookup('A')
683 <details class=
"source">
685 <span>Expand source code
</span>
687 <pre><code class=
"python">def lookup(self, letter):
688 """Look up what a letter enciphers to, without turning the wheel.
690 >>> pe.set_position(
'f
')
692 >>> cat([pe.lookup(l) for l in string.ascii_lowercase])
693 'udhbfejcpgmokrliwntsayqzvx
'
694 >>> pe.lookup(
'A
')
697 if letter in string.ascii_lowercase:
699 (self.wheel_map[(pos(letter) - self.position) %
26] +
702 return
''</code></pre>
705 <dt id=
"szyfrow.pocket_enigma.PocketEnigma.make_wheel_map"><code class=
"name flex">
706 <span>def
<span class=
"ident">make_wheel_map
</span></span>(
<span>self, wheel_spec)
</span>
709 <div class=
"desc"><p>Expands a wheel specification from a list of letter-letter pairs
710 into a full wheel_map.
</p>
711 <pre><code class=
"language-python-repl">>>> pe.make_wheel_map(pe.wheel2)
712 [
2,
3,
0,
1,
22,
8,
15,
12,
5,
10,
9,
13,
7,
11,
16,
6,
14,
25,
20,
21,
18,
19,
4,
24,
23,
17]
714 <details class=
"source">
716 <span>Expand source code
</span>
718 <pre><code class=
"python">def make_wheel_map(self, wheel_spec):
719 """Expands a wheel specification from a list of letter-letter pairs
720 into a full wheel_map.
722 >>> pe.make_wheel_map(pe.wheel2)
723 [
2,
3,
0,
1,
22,
8,
15,
12,
5,
10,
9,
13,
7,
11,
16,
6,
14,
25,
20,
21,
18,
19,
4,
24,
23,
17]
725 self.validate_wheel_spec(wheel_spec)
726 self.wheel_map = [
0] *
26
728 self.wheel_map[pos(p[
0])] = pos(p[
1])
729 self.wheel_map[pos(p[
1])] = pos(p[
0])
730 return self.wheel_map
</code></pre>
733 <dt id=
"szyfrow.pocket_enigma.PocketEnigma.set_position"><code class=
"name flex">
734 <span>def
<span class=
"ident">set_position
</span></span>(
<span>self, position)
</span>
737 <div class=
"desc"><p>Sets the position of the wheel, by specifying the letter the arrow
739 <pre><code class=
"language-python-repl">>>> pe.set_position('a')
741 >>> pe.set_position('m')
743 >>> pe.set_position('z')
746 <details class=
"source">
748 <span>Expand source code
</span>
750 <pre><code class=
"python">def set_position(self, position):
751 """Sets the position of the wheel, by specifying the letter the arrow
754 >>> pe.set_position(
'a
')
756 >>> pe.set_position(
'm
')
758 >>> pe.set_position(
'z
')
761 self.position = pos(position)
762 return self.position
</code></pre>
765 <dt id=
"szyfrow.pocket_enigma.PocketEnigma.validate_wheel_spec"><code class=
"name flex">
766 <span>def
<span class=
"ident">validate_wheel_spec
</span></span>(
<span>self, wheel_spec)
</span>
769 <div class=
"desc"><p>Validates that a wheel specificaiton will turn into a valid wheel
771 <pre><code class=
"language-python-repl">>>> pe.validate_wheel_spec([])
772 Traceback (most recent call last):
774 ValueError: Wheel specification has
0 pairs, requires
13
775 >>> pe.validate_wheel_spec([('a', 'b', 'c')]*
13)
776 Traceback (most recent call last):
778 ValueError: Not all mappings in wheel specificationhave two elements
779 >>> pe.validate_wheel_spec([('a', 'b')]*
13)
780 Traceback (most recent call last):
782 ValueError: Wheel specification does not contain
26 letters
784 <details class=
"source">
786 <span>Expand source code
</span>
788 <pre><code class=
"python">def validate_wheel_spec(self, wheel_spec):
789 """Validates that a wheel specificaiton will turn into a valid wheel
792 >>> pe.validate_wheel_spec([])
793 Traceback (most recent call last):
795 ValueError: Wheel specification has
0 pairs, requires
13
796 >>> pe.validate_wheel_spec([(
'a
',
'b
',
'c
')]*
13)
797 Traceback (most recent call last):
799 ValueError: Not all mappings in wheel specificationhave two elements
800 >>> pe.validate_wheel_spec([(
'a
',
'b
')]*
13)
801 Traceback (most recent call last):
803 ValueError: Wheel specification does not contain
26 letters
805 if len(wheel_spec) !=
13:
806 raise ValueError(
"Wheel specification has {} pairs, requires
13".
807 format(len(wheel_spec)))
810 raise ValueError(
"Not all mappings in wheel specification
"
811 "have two elements
")
812 if len(set([p[
0] for p in wheel_spec] +
813 [p[
1] for p in wheel_spec])) !=
26:
814 raise ValueError(
"Wheel specification does not contain
26 letters
")
</code></pre>
828 <li><h3>Super-module
</h3>
830 <li><code><a title=
"szyfrow" href=
"index.html">szyfrow
</a></code></li>
833 <li><h3><a href=
"#header-functions">Functions
</a></h3>
835 <li><code><a title=
"szyfrow.pocket_enigma.cat" href=
"#szyfrow.pocket_enigma.cat">cat
</a></code></li>
836 <li><code><a title=
"szyfrow.pocket_enigma.lcat" href=
"#szyfrow.pocket_enigma.lcat">lcat
</a></code></li>
837 <li><code><a title=
"szyfrow.pocket_enigma.pocket_enigma_break_by_crib" href=
"#szyfrow.pocket_enigma.pocket_enigma_break_by_crib">pocket_enigma_break_by_crib
</a></code></li>
838 <li><code><a title=
"szyfrow.pocket_enigma.wcat" href=
"#szyfrow.pocket_enigma.wcat">wcat
</a></code></li>
841 <li><h3><a href=
"#header-classes">Classes
</a></h3>
844 <h4><code><a title=
"szyfrow.pocket_enigma.PocketEnigma" href=
"#szyfrow.pocket_enigma.PocketEnigma">PocketEnigma
</a></code></h4>
845 <ul class=
"two-column">
846 <li><code><a title=
"szyfrow.pocket_enigma.PocketEnigma.advance" href=
"#szyfrow.pocket_enigma.PocketEnigma.advance">advance
</a></code></li>
847 <li><code><a title=
"szyfrow.pocket_enigma.PocketEnigma.decipher" href=
"#szyfrow.pocket_enigma.PocketEnigma.decipher">decipher
</a></code></li>
848 <li><code><a title=
"szyfrow.pocket_enigma.PocketEnigma.decipher_letter" href=
"#szyfrow.pocket_enigma.PocketEnigma.decipher_letter">decipher_letter
</a></code></li>
849 <li><code><a title=
"szyfrow.pocket_enigma.PocketEnigma.encipher" href=
"#szyfrow.pocket_enigma.PocketEnigma.encipher">encipher
</a></code></li>
850 <li><code><a title=
"szyfrow.pocket_enigma.PocketEnigma.encipher_letter" href=
"#szyfrow.pocket_enigma.PocketEnigma.encipher_letter">encipher_letter
</a></code></li>
851 <li><code><a title=
"szyfrow.pocket_enigma.PocketEnigma.lookup" href=
"#szyfrow.pocket_enigma.PocketEnigma.lookup">lookup
</a></code></li>
852 <li><code><a title=
"szyfrow.pocket_enigma.PocketEnigma.make_wheel_map" href=
"#szyfrow.pocket_enigma.PocketEnigma.make_wheel_map">make_wheel_map
</a></code></li>
853 <li><code><a title=
"szyfrow.pocket_enigma.PocketEnigma.set_position" href=
"#szyfrow.pocket_enigma.PocketEnigma.set_position">set_position
</a></code></li>
854 <li><code><a title=
"szyfrow.pocket_enigma.PocketEnigma.validate_wheel_spec" href=
"#szyfrow.pocket_enigma.PocketEnigma.validate_wheel_spec">validate_wheel_spec
</a></code></li>
863 <p>Generated by
<a href=
"https://pdoc3.github.io/pdoc"><cite>pdoc
</cite> 0.9.2</a>.
</p>