From 373d3077e562c81fe35d0f68e6b8e10983908b6c Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Tue, 12 Sep 2017 16:18:57 +0100 Subject: [PATCH] Worked on Enigma, mainly changing how the notch positions are handled --- bombe.ipynb | 686 ++++++----- dtu_notch_big.jpg | Bin 0 -> 123960 bytes enigma-notch.jpg | Bin 0 -> 241861 bytes enigma-old.ipynb | 2639 +++++++++++++++++++++++++++++++++++++++ enigma.ipynb | 3012 ++++++++++++++++++++++++++++++++------------- enigma.py | 54 +- test_enigma.py | 267 ++-- 7 files changed, 5379 insertions(+), 1279 deletions(-) create mode 100644 dtu_notch_big.jpg create mode 100644 enigma-notch.jpg create mode 100644 enigma-old.ipynb diff --git a/bombe.ipynb b/bombe.ipynb index 93e0ccb..e28af9a 100644 --- a/bombe.ipynb +++ b/bombe.ipynb @@ -75,9 +75,9 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 4, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -164,7 +164,10 @@ " self.pending += [Signal(current.wire, current.bank)]\n", " for c in self.connections:\n", " if current.bank in c.banks:\n", - " other_bank = [b for b in c.banks if b != current.bank][0]\n", + " if len(set(c.banks)) == 1:\n", + " other_bank = c.banks[0]\n", + " else:\n", + " other_bank = [b for b in c.banks if b != current.bank][0]\n", " other_wire = c.scrambler.lookup(current.wire)\n", " # print(\" adding\", other_bank, other_wire, \"because\", c.banks)\n", " self.pending += [Signal(other_bank, other_wire)]\n", @@ -200,9 +203,9 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 5, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -212,7 +215,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 6, "metadata": { "collapsed": true }, @@ -228,10 +231,8 @@ }, { "cell_type": "code", - "execution_count": 34, - "metadata": { - "collapsed": false - }, + "execution_count": 7, + "metadata": {}, "outputs": [ { "data": { @@ -239,7 +240,7 @@ "'opgndxcrwomnlnecjz'" ] }, - "execution_count": 34, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -253,10 +254,8 @@ }, { "cell_type": "code", - "execution_count": 35, - "metadata": { - "collapsed": false - }, + "execution_count": 8, + "metadata": {}, "outputs": [ { "data": { @@ -264,7 +263,7 @@ "'aas'" ] }, - "execution_count": 35, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -275,10 +274,8 @@ }, { "cell_type": "code", - "execution_count": 36, - "metadata": { - "collapsed": false - }, + "execution_count": 9, + "metadata": {}, "outputs": [ { "data": { @@ -303,7 +300,7 @@ " MenuIem(before='e', after='z', number=18)]" ] }, - "execution_count": 36, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -315,7 +312,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 10, "metadata": { "collapsed": true }, @@ -328,10 +325,8 @@ }, { "cell_type": "code", - "execution_count": 38, - "metadata": { - "collapsed": false - }, + "execution_count": 11, + "metadata": {}, "outputs": [ { "data": { @@ -356,7 +351,7 @@ " MenuIem(before='e', after='z', number=18)]" ] }, - "execution_count": 38, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -367,10 +362,8 @@ }, { "cell_type": "code", - "execution_count": 39, - "metadata": { - "collapsed": false - }, + "execution_count": 12, + "metadata": {}, "outputs": [ { "data": { @@ -378,7 +371,7 @@ "'s'" ] }, - "execution_count": 39, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -389,9 +382,9 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 13, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -400,10 +393,8 @@ }, { "cell_type": "code", - "execution_count": 43, - "metadata": { - "collapsed": false - }, + "execution_count": 14, + "metadata": {}, "outputs": [ { "data": { @@ -411,7 +402,7 @@ "18" ] }, - "execution_count": 43, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -422,33 +413,13 @@ }, { "cell_type": "code", - "execution_count": 27, - "metadata": { - "collapsed": false - }, + "execution_count": 15, + "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "['t', 'o'] aaa\n", - "['h', 'p'] aab\n", - "['i', 'g'] aac\n", - "['s', 'n'] aad\n", - "['i', 'd'] aae\n", - "['s', 'x'] aaf\n", - "['a', 'c'] aag\n", - "['t', 'r'] aah\n", - "['e', 'w'] aai\n", - "['s', 'o'] aaj\n", - "['t', 'm'] aak\n", - "['m', 'n'] aal\n", - "['e', 'l'] aam\n", - "['s', 'n'] aan\n", - "['s', 'e'] aao\n", - "['a', 'c'] aap\n", - "['g', 'j'] aaq\n", - "['e', 'z'] aar\n", "['t', 'o'] aaa\n", "['h', 'p'] aab\n", "['i', 'g'] aac\n", @@ -477,10 +448,8 @@ }, { "cell_type": "code", - "execution_count": 44, - "metadata": { - "collapsed": false - }, + "execution_count": 16, + "metadata": {}, "outputs": [ { "data": { @@ -488,7 +457,7 @@ "'ot:hp:gi:ns:di:sx:ac:rt:ew:os:mt:mn:el:ns:es:ac:gj:ez'" ] }, - "execution_count": 44, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -499,10 +468,8 @@ }, { "cell_type": "code", - "execution_count": 45, - "metadata": { - "collapsed": false - }, + "execution_count": 17, + "metadata": {}, "outputs": [ { "data": { @@ -510,7 +477,7 @@ "'aaa:aab:aac:aad:aae:aaf:aag:aah:aai:aaj:aak:aal:aam:aan:aao:aap:aaq:aar'" ] }, - "execution_count": 45, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -521,18 +488,16 @@ }, { "cell_type": "code", - "execution_count": 56, - "metadata": { - "collapsed": false - }, + "execution_count": 18, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "True" + "False" ] }, - "execution_count": 56, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -543,43 +508,41 @@ }, { "cell_type": "code", - "execution_count": 57, - "metadata": { - "collapsed": false - }, + "execution_count": 19, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "{'a': False,\n", - " 'b': False,\n", - " 'c': False,\n", - " 'd': False,\n", - " 'e': False,\n", - " 'f': False,\n", - " 'g': False,\n", - " 'h': False,\n", - " 'i': False,\n", - " 'j': False,\n", - " 'k': False,\n", - " 'l': False,\n", - " 'm': False,\n", - " 'n': False,\n", - " 'o': False,\n", - " 'p': False,\n", - " 'q': False,\n", - " 'r': False,\n", - " 's': False,\n", + "{'a': True,\n", + " 'b': True,\n", + " 'c': True,\n", + " 'd': True,\n", + " 'e': True,\n", + " 'f': True,\n", + " 'g': True,\n", + " 'h': True,\n", + " 'i': True,\n", + " 'j': True,\n", + " 'k': True,\n", + " 'l': True,\n", + " 'm': True,\n", + " 'n': True,\n", + " 'o': True,\n", + " 'p': True,\n", + " 'q': True,\n", + " 'r': True,\n", + " 's': True,\n", " 't': True,\n", - " 'u': False,\n", - " 'v': False,\n", - " 'w': False,\n", - " 'x': False,\n", - " 'y': False,\n", - " 'z': False}" + " 'u': True,\n", + " 'v': True,\n", + " 'w': True,\n", + " 'x': True,\n", + " 'y': True,\n", + " 'z': True}" ] }, - "execution_count": 57, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -590,10 +553,8 @@ }, { "cell_type": "code", - "execution_count": 48, - "metadata": { - "collapsed": false - }, + "execution_count": 20, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -641,10 +602,8 @@ }, { "cell_type": "code", - "execution_count": 49, - "metadata": { - "collapsed": false - }, + "execution_count": 21, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -692,10 +651,8 @@ }, { "cell_type": "code", - "execution_count": 50, - "metadata": { - "collapsed": false - }, + "execution_count": 22, + "metadata": {}, "outputs": [ { "data": { @@ -703,7 +660,7 @@ "('a', 'a', 'a')" ] }, - "execution_count": 50, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -714,10 +671,8 @@ }, { "cell_type": "code", - "execution_count": 51, - "metadata": { - "collapsed": false - }, + "execution_count": 23, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -752,9 +707,9 @@ }, { "cell_type": "code", - "execution_count": 52, + "execution_count": 24, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -764,10 +719,8 @@ }, { "cell_type": "code", - "execution_count": 53, - "metadata": { - "collapsed": false - }, + "execution_count": 25, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -818,10 +771,8 @@ }, { "cell_type": "code", - "execution_count": 54, - "metadata": { - "collapsed": false - }, + "execution_count": 26, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -872,10 +823,8 @@ }, { "cell_type": "code", - "execution_count": 55, - "metadata": { - "collapsed": false - }, + "execution_count": 27, + "metadata": {}, "outputs": [ { "data": { @@ -883,7 +832,7 @@ "1" ] }, - "execution_count": 55, + "execution_count": 27, "metadata": {}, "output_type": "execute_result" } @@ -894,9 +843,9 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 28, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -907,9 +856,9 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 29, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -920,10 +869,8 @@ }, { "cell_type": "code", - "execution_count": 27, - "metadata": { - "collapsed": false - }, + "execution_count": 30, + "metadata": {}, "outputs": [ { "data": { @@ -931,7 +878,7 @@ "('a', 'a', 'b')" ] }, - "execution_count": 27, + "execution_count": 30, "metadata": {}, "output_type": "execute_result" } @@ -942,10 +889,8 @@ }, { "cell_type": "code", - "execution_count": 28, - "metadata": { - "collapsed": false - }, + "execution_count": 31, + "metadata": {}, "outputs": [ { "data": { @@ -953,7 +898,7 @@ "False" ] }, - "execution_count": 28, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" } @@ -964,10 +909,8 @@ }, { "cell_type": "code", - "execution_count": 29, - "metadata": { - "collapsed": false - }, + "execution_count": 32, + "metadata": {}, "outputs": [ { "data": { @@ -975,7 +918,7 @@ "('p', 'p', 'p')" ] }, - "execution_count": 29, + "execution_count": 32, "metadata": {}, "output_type": "execute_result" } @@ -986,10 +929,8 @@ }, { "cell_type": "code", - "execution_count": 30, - "metadata": { - "collapsed": false - }, + "execution_count": 33, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -1037,10 +978,8 @@ }, { "cell_type": "code", - "execution_count": 31, - "metadata": { - "collapsed": false - }, + "execution_count": 34, + "metadata": {}, "outputs": [ { "data": { @@ -1048,7 +987,7 @@ "17576" ] }, - "execution_count": 31, + "execution_count": 34, "metadata": {}, "output_type": "execute_result" } @@ -1060,10 +999,8 @@ }, { "cell_type": "code", - "execution_count": 32, - "metadata": { - "collapsed": false - }, + "execution_count": 35, + "metadata": {}, "outputs": [ { "data": { @@ -1071,7 +1008,7 @@ "(('a', 'a', 'b'), True)" ] }, - "execution_count": 32, + "execution_count": 35, "metadata": {}, "output_type": "execute_result" } @@ -1083,9 +1020,9 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 36, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -1094,10 +1031,8 @@ }, { "cell_type": "code", - "execution_count": 34, - "metadata": { - "collapsed": false - }, + "execution_count": 37, + "metadata": {}, "outputs": [ { "data": { @@ -1105,7 +1040,7 @@ "[('a', 'a', 'b')]" ] }, - "execution_count": 34, + "execution_count": 37, "metadata": {}, "output_type": "execute_result" } @@ -1121,7 +1056,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 38, "metadata": { "collapsed": true }, @@ -1143,10 +1078,8 @@ }, { "cell_type": "code", - "execution_count": 36, - "metadata": { - "collapsed": false - }, + "execution_count": 39, + "metadata": {}, "outputs": [ { "data": { @@ -1154,7 +1087,7 @@ "[('a', 'a', 'b')]" ] }, - "execution_count": 36, + "execution_count": 39, "metadata": {}, "output_type": "execute_result" } @@ -1165,9 +1098,9 @@ }, { "cell_type": "code", - "execution_count": 58, + "execution_count": 40, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -1184,10 +1117,8 @@ }, { "cell_type": "code", - "execution_count": 59, - "metadata": { - "collapsed": false - }, + "execution_count": 41, + "metadata": {}, "outputs": [ { "data": { @@ -1195,7 +1126,7 @@ "('e', 'l', 'e')" ] }, - "execution_count": 59, + "execution_count": 41, "metadata": {}, "output_type": "execute_result" } @@ -1207,10 +1138,8 @@ }, { "cell_type": "code", - "execution_count": 39, - "metadata": { - "collapsed": false - }, + "execution_count": 42, + "metadata": {}, "outputs": [ { "data": { @@ -1218,7 +1147,7 @@ "'dhnpforeeimgg'" ] }, - "execution_count": 39, + "execution_count": 42, "metadata": {}, "output_type": "execute_result" } @@ -1232,10 +1161,8 @@ }, { "cell_type": "code", - "execution_count": 40, - "metadata": { - "collapsed": false - }, + "execution_count": 43, + "metadata": {}, "outputs": [ { "data": { @@ -1243,7 +1170,7 @@ "('j', 'e', 'o')" ] }, - "execution_count": 40, + "execution_count": 43, "metadata": {}, "output_type": "execute_result" } @@ -1254,10 +1181,8 @@ }, { "cell_type": "code", - "execution_count": 41, - "metadata": { - "collapsed": false - }, + "execution_count": 44, + "metadata": {}, "outputs": [ { "data": { @@ -1277,7 +1202,7 @@ " MenuIem(before='t', after='g', number=13)]" ] }, - "execution_count": 41, + "execution_count": 44, "metadata": {}, "output_type": "execute_result" } @@ -1289,9 +1214,8 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 45, "metadata": { - "collapsed": false, "scrolled": true }, "outputs": [ @@ -1362,7 +1286,7 @@ " ('z', 'z', 'k')]" ] }, - "execution_count": 42, + "execution_count": 45, "metadata": {}, "output_type": "execute_result" } @@ -1379,10 +1303,8 @@ }, { "cell_type": "code", - "execution_count": 43, - "metadata": { - "collapsed": false - }, + "execution_count": 46, + "metadata": {}, "outputs": [ { "data": { @@ -1390,7 +1312,7 @@ "62" ] }, - "execution_count": 43, + "execution_count": 46, "metadata": {}, "output_type": "execute_result" } @@ -1401,9 +1323,8 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 47, "metadata": { - "collapsed": false, "scrolled": true }, "outputs": [ @@ -1425,7 +1346,7 @@ " ('y', 'n', 'c')]" ] }, - "execution_count": 44, + "execution_count": 47, "metadata": {}, "output_type": "execute_result" } @@ -1442,10 +1363,8 @@ }, { "cell_type": "code", - "execution_count": 45, - "metadata": { - "collapsed": false - }, + "execution_count": 48, + "metadata": {}, "outputs": [ { "data": { @@ -1465,7 +1384,7 @@ " ('y', 'n', 'c')]" ] }, - "execution_count": 45, + "execution_count": 48, "metadata": {}, "output_type": "execute_result" } @@ -1476,9 +1395,9 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 49, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -1493,10 +1412,8 @@ }, { "cell_type": "code", - "execution_count": 47, - "metadata": { - "collapsed": false - }, + "execution_count": 50, + "metadata": {}, "outputs": [ { "data": { @@ -1504,7 +1421,7 @@ "13" ] }, - "execution_count": 47, + "execution_count": 50, "metadata": {}, "output_type": "execute_result" } @@ -1515,9 +1432,9 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 51, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -1527,10 +1444,8 @@ }, { "cell_type": "code", - "execution_count": 49, - "metadata": { - "collapsed": false - }, + "execution_count": 52, + "metadata": {}, "outputs": [ { "data": { @@ -1538,7 +1453,7 @@ "Signal(bank='e', wire='e')" ] }, - "execution_count": 49, + "execution_count": 52, "metadata": {}, "output_type": "execute_result" } @@ -1549,10 +1464,8 @@ }, { "cell_type": "code", - "execution_count": 50, - "metadata": { - "collapsed": false - }, + "execution_count": 53, + "metadata": {}, "outputs": [ { "data": { @@ -1560,7 +1473,7 @@ "True" ] }, - "execution_count": 50, + "execution_count": 53, "metadata": {}, "output_type": "execute_result" } @@ -1571,10 +1484,8 @@ }, { "cell_type": "code", - "execution_count": 51, - "metadata": { - "collapsed": false - }, + "execution_count": 54, + "metadata": {}, "outputs": [ { "data": { @@ -1582,7 +1493,7 @@ "True" ] }, - "execution_count": 51, + "execution_count": 54, "metadata": {}, "output_type": "execute_result" } @@ -1593,10 +1504,8 @@ }, { "cell_type": "code", - "execution_count": 52, - "metadata": { - "collapsed": false - }, + "execution_count": 55, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -1647,10 +1556,8 @@ }, { "cell_type": "code", - "execution_count": 53, - "metadata": { - "collapsed": false - }, + "execution_count": 56, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -1701,23 +1608,21 @@ }, { "cell_type": "code", - "execution_count": 54, - "metadata": { - "collapsed": false - }, + "execution_count": 57, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "{frozenset({'m'}),\n", + "{frozenset({'t', 'x'}),\n", " frozenset({'i', 'n'}),\n", - " frozenset({'f', 'p'}),\n", - " frozenset({'t', 'x'}),\n", + " frozenset({'m'}),\n", " frozenset({'e', 'y'}),\n", + " frozenset({'f', 'p'}),\n", " frozenset({'b', 'g'})}" ] }, - "execution_count": 54, + "execution_count": 57, "metadata": {}, "output_type": "execute_result" } @@ -1729,10 +1634,8 @@ }, { "cell_type": "code", - "execution_count": 55, - "metadata": { - "collapsed": false - }, + "execution_count": 58, + "metadata": {}, "outputs": [ { "data": { @@ -1740,7 +1643,7 @@ "True" ] }, - "execution_count": 55, + "execution_count": 58, "metadata": {}, "output_type": "execute_result" } @@ -1751,21 +1654,19 @@ }, { "cell_type": "code", - "execution_count": 56, - "metadata": { - "collapsed": false - }, + "execution_count": 59, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "({frozenset({1, 2}), frozenset({3, 4}), frozenset({2, 3})},\n", + "({frozenset({1, 2}), frozenset({2, 3}), frozenset({3, 4})},\n", " frozenset({1, 2}),\n", " frozenset({3, 4}),\n", " frozenset({2, 3}))" ] }, - "execution_count": 56, + "execution_count": 59, "metadata": {}, "output_type": "execute_result" } @@ -1784,10 +1685,8 @@ }, { "cell_type": "code", - "execution_count": 57, - "metadata": { - "collapsed": false - }, + "execution_count": 60, + "metadata": {}, "outputs": [ { "data": { @@ -1795,7 +1694,7 @@ "False" ] }, - "execution_count": 57, + "execution_count": 60, "metadata": {}, "output_type": "execute_result" } @@ -1806,10 +1705,8 @@ }, { "cell_type": "code", - "execution_count": 58, - "metadata": { - "collapsed": false - }, + "execution_count": 61, + "metadata": {}, "outputs": [ { "data": { @@ -1817,7 +1714,7 @@ "False" ] }, - "execution_count": 58, + "execution_count": 61, "metadata": {}, "output_type": "execute_result" } @@ -1826,6 +1723,223 @@ "{1, 2}.isdisjoint({1, 6})" ] }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "# Tsest" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'slgncszxltkzebghstgywdmpr'" + ] + }, + "execution_count": 62, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "target_ct = ''.join(c.lower() for c in 'SLGNC SZXLT KZEBG HSTGY WDMPR' if c in string.ascii_letters)\n", + "target_ct" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'theyweredetectedbybritishshipsinclud'" + ] + }, + "execution_count": 63, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "target_pt = ''.join(c.lower() for c in 'Theyw erede tecte d byBri tishs hipsi nclud' if c in string.ascii_letters)\n", + "target_pt" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[MenuIem(before='w', after='c', number=1),\n", + " MenuIem(before='e', after='s', number=2),\n", + " MenuIem(before='r', after='z', number=3),\n", + " MenuIem(before='e', after='x', number=4),\n", + " MenuIem(before='d', after='l', number=5),\n", + " MenuIem(before='e', after='t', number=6),\n", + " MenuIem(before='t', after='k', number=7),\n", + " MenuIem(before='e', after='z', number=8),\n", + " MenuIem(before='c', after='e', number=9),\n", + " MenuIem(before='t', after='b', number=10),\n", + " MenuIem(before='e', after='g', number=11),\n", + " MenuIem(before='d', after='h', number=12),\n", + " MenuIem(before='b', after='s', number=13),\n", + " MenuIem(before='y', after='t', number=14),\n", + " MenuIem(before='b', after='g', number=15),\n", + " MenuIem(before='r', after='y', number=16),\n", + " MenuIem(before='i', after='w', number=17),\n", + " MenuIem(before='t', after='d', number=18),\n", + " MenuIem(before='i', after='m', number=19),\n", + " MenuIem(before='s', after='p', number=20)]" + ] + }, + "execution_count": 64, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tbt_menu = [MenuItem(p, c, i+1) for i, (p, c) in enumerate(zip(target_pt[4:24], target_ct[4:24]))]\n", + "tbt_menu" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "tbt_bombe = Bombe(wheel_iii_spec, wheel_i_spec, wheel_ii_spec, reflector_b_spec, \n", + " menu=tbt_menu)" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[('k', 'r', 'n')]" + ] + }, + "execution_count": 66, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tbt_wheel_posns = run_multi_bombe(wheel_iii_spec, wheel_i_spec, wheel_ii_spec, reflector_b_spec, tbt_menu)\n", + "tbt_wheel_posns" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Signal(bank='e', wire='e')" + ] + }, + "execution_count": 67, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tbt_bombe.test_start" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "False\n", + "a : abcdefghi..lmnop.rst.v.x.z\n", + "b : a...ef.hi..lmnop.r.t...x..\n", + "c : a..defg.i..lmn.p.rst...x..\n", + "d : a.c.efghi.klmnopqrstu.wxyz\n", + "e : abcdefghijklmnopqrstuvwx.z\n", + "f : abcdefghijklmno.qrstuvwxyz\n", + "g : a.cdefghijklmnopqrstuvwxyz\n", + "h : ab.defghi...mnopqrstuvwxyz\n", + "i : abcdefghijklm.opqrstuvwxyz\n", + "j : ....efg.i..lmnop...t...x..\n", + "k : ...defg.i..lmn.p..st...x..\n", + "l : abcdefg.ijklmnopqrstuv.x..\n", + "m : abcdefghijkl.nopqrstuvwxyz\n", + "n : abcdefgh.jklmnopqrstuvwxyz\n", + "o : ab.defghij.lmnop.r.tuvwxyz\n", + "p : abcde.ghijklmnopqrstuvwxyz\n", + "q : ...defghi..lmn.p..st...x..\n", + "r : abcdefghi..lmnop.rst.v.x.z\n", + "s : a.cdefghi.klmn.pqr.tuvwxyz\n", + "t : abcdefghijklmnopqrstuvw.yz\n", + "u : ...defghi..lmnop..st...x..\n", + "v : a...efghi..lmnop.rst...x..\n", + "w : ...defghi...mnop..st...x..\n", + "x : abcdefghijklmnopqrs.uvwxyz\n", + "y : ...d.fghi...mnop..st...x..\n", + "z : a..defghi...mnop.rst...x..\n" + ] + } + ], + "source": [ + "r = tbt_bombe.test(start_positions=('l', 's', 'd'))\n", + "print(r)\n", + "for b in sorted(w_bombe.banks):\n", + " print(b, ': ', end='')\n", + " for w in sorted(w_bombe.banks[b]):\n", + " if w_bombe.banks[b][w]:\n", + " print(w, end='')\n", + " else:\n", + " print('.', end='')\n", + " print('')\n" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "set()" + ] + }, + "execution_count": 69, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ps = tbt_bombe.possible_plugboards()\n", + "ps" + ] + }, { "cell_type": "code", "execution_count": null, @@ -1852,9 +1966,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.5.1+" + "version": "3.5.3" } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 1 } diff --git a/dtu_notch_big.jpg b/dtu_notch_big.jpg new file mode 100644 index 0000000000000000000000000000000000000000..dbdbbf1baf17baacc44fc4ecf73c738749f639b5 GIT binary patch literal 123960 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

WHtT_dLN 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 literal 0 HcmV?d00001 diff --git a/enigma-notch.jpg b/enigma-notch.jpg new file mode 100644 index 0000000000000000000000000000000000000000..31781e6f189e05b710777500d09f4cb0f6e1c008 GIT binary patch literal 241861 zcmbTe1y~$U5GOi|JA@#?U4y$raCdiy#oZ-}y9Rf+;0_7yF2Mr?487G3s|~=Cf{YZUCyeP4 z|C_Ft09Z=^FwZKlPD%MM{r?C(v2ye90sxRYjGNoq#?uOh-@>qyub0~+{Ra%=Svo#q zID|*+0TU30pFLu`KQT-<7|)+r;t^XryI8|`9%Xj3cD8=R127!n<81@O@X9b8<^#6z zh2aGlrgidm2E*`A7{+t9vG4={1dKpK8=w)!uPHXi`6-vU6(^ndgrc=Q*0FE2MCc6MK1UpBCf72Bgh|4IL! z4F7Qcufc!%V|(oHAKOt%+t^xoJ9$w)8r90x$<^C~($met%7&8l|Lw&8*A@RG)_>$+ z(X_F(@vw1$b)^gQGO&vsY`9&l!Cqij7fP_p|7wK)FRT4WhDZ3PU&FxD;s*fFj19n< z#slC_Cjf+}=m5NNF02If&$ub0>H?2Xf3AOT1PGJ!mx7^nbhfd-%z=mI_gL%=vN11th-z!zW-I01eD*T5ZY9zzCU zf}VniKolT4&~p$MNB|@Tk^w1$G(iR+bC4a#1>_A10=)r6gOWg*paM_@s2ZlYPc4- zPjKUKi*R4yPT;QK0eEzH0(dHTR(Jt;DR?z_LwH+w5BL!HDEKt^Lik$v4)|gCdH65z z-{5Z%kPx0CP$IA*2qVZN=pa}jxFduh#2{oMlq0kt3?R%SY$NsCQ^j&=}A}(X`PV&|aavN2^5}L|aFLprfNx zqYI*Ipo7t0qQ6J~fIfo0jed)Pi@}T`g<*{0jS+`YhVc<&1p|VKiAj$sfoX{8g&Bug zf!U9_iTM-jDHa=+0+uyaC{`9$3)URgcWhK_I_wwNrq}`4Y1oa})7al|P;uySq;M>7 zLU6Kh+Hsa~uAV%7!udq)iSv_~CzVe|pB&;M~G;9BFp#Vx|^$K8Dj|CHvb)Kjac zZ=M!E9elcnhlIy~r-0{x7mZhgH-+~D9~YkoUl-pGKMTJb{|f;;0X=~NffGSIK?A`O z0hEx8@CBg_VI*NK;T+-3Gm>W#&upGWJ*#`R_zX%!NhCw$NR&v_O0+?YK+H_6LF`MM zOFT&YjRcQGn8b=Cill*Ll@yMYnN*WBkhF+&g7k`voJ@|)jVyz#pX?hs0l5UZ19=L0 z5BU+rQwlK(FhvSQFU2t>KIIEaC(8Gf1C&3gNU7whyr~MPrl{_y8K`xrUsKmnZ_uF8 z2+-Klq|o%y{Gg?vRiO={t)g9}L!}d-v!_d^8>YLVXQ0=k52tUXKV*2upuiBoP{pv$ zh{-6<=+0QkxWI(OB*5gzl*2T`49CpNY|osO%w@%u z#kIhV$t}wr%H76&&hwndh9{TjGw)Mg72a^(KHgt^{CpmKwR}hXwEX7$+5F1_cmnDI zF#;okh=P)Wp@Ln4w?ceEUP28*XTq$)j>46~hawCjHX_9$yQ0*h7NP~BU&JWI%*FD> zzKBzaTZk8m??}){SWA>j9K2w9;qapR#dk>#Ne{_p$r~vlsbHy(((ux9(oxb=GPp82 zGMO@)vedG6vQ@G_5 zQ0`EHQ&Ch&R#{i2Q*}{oRRh!%)RNUU)EU&>)jKtiG}JY+H1;()HG?#VwVrC3X;o@n zYfEa!Yp>}r>Uit)>0;{|>sILA=t=7(>3z{>*ALboHy}0u8?+fB8|oUC8eSR67^NER z8S@&4884YInE08Dni88jnRc6Dn^~AOnj@O)nOBq(w zuuic)vJtgOvN^C7wN0`;v=g;UwmY&Hw@>ufW5Fi^+5{M9J71$R<74#}-JNQL#K?o?sGNdn*CiHFS z-b=Zc<*(3QIlh{F&G9aClw>LIgNsDv~=g zBl022I%+JMBRVbmKE^6$ES59&eeCZz+qkKCzWCe(qy(3Qr9|<>@}wt80ZF^bD#>$Lj?BKvvCf&xmB_8l zBg>1lP1}2$WQm5|>7o{wi}R`%DZBY;b5skc z#lPi8t9|R2HiNd=cE$F-4&jdGPPWdnE~>7qZv5`}9<-jfJ->ScdapjZef;*x?$d6c zS>IZ}e*eON#=z8|(%{ID>`?#ki{ai8(UGoEq0#m+fw9(czVVg`-ihW(-pS@EzNwaJ z{^_a%*c_HrF@ zJ!%7IBW;s(vv7-PtL_Wmm+o!p?TH<&owZ%7-IK4LU+?$c?qlw!9Z(!p9C96Y9myWe z92*_)ow%LceG5B%a+>{}@q5#m#M#6T{U3Yh9_PO=Vjx72vP+)JzAN>s&1>iDyPK$= zL_f=K1#X9-deDPA-+Scy_rI8abv!6Ntp9fY{rmSe+`Wt+*cJd(Q~+jJG=Ku2g0Nw0 z2v|%D%K;#qKQI~$$AEAFc-R^A7-fKnVR6Hs@kSbm1|ujpD!gVe%Bi{Y8JoumA~mdbBW5jPQ?a--;3cqW8n- zNdMvaTgONK|L9o!w~mi=wEys9{EHv^fThR2V5>2J6qXVHXCwGOqrrF|!_~*SkKXwx z^WPr$`jP%ZOG-fj1}Ogz(j)(4{=E&-`D>Nq;>l)V?P_VmX65S4?q}h~&dJ8X4v6>( z`8m5e+jv<}`Z+tfcnbN6Qvbmw1jCPHc52E$SiBrXsr6OVVXFn0Z}PD5uyIg}p}`~( z@vycP(v+6{t2*pTl=?sGDqn6kR}VXO*g8{?or8;=i;ES;!RqPn;$`8->f%ZBXCr^N zBMn<*dw|{kSd2WjYhmf??IlW0{n*hz=`T5*-Tvw5f2!I)EyF5`z;qPSwD5v0cf>eE z*#C3&SIZ*okKO&J`#*L2g9=kl3=LN4Z$pWp0l(J(DFE(q_X6~IgnLW~@Q+7C1O#{l zBt%$*{FsqZQD7Mv2?-YWqM|(}7{WkD!+5-SY~;_XaES2mh-k=2$bYc>|2q8c1D>G3 z8^Bx{L=C__0l_~3{T=|wU}KLA6AX6xJAvTf5fG7(QBYyU#E*hMroRhep7KZW?^OT; z9t6PQz~jJ3R~T>QuPj^(E{!SzbUMP{c(a9VvuKW5RHq`De_4>rfz=iSXh6U-1R^3# zbA~TnJ>k1l{%hE*e4JE`k|X0j$wQV0ey1VTo>GUOko*a!E;sy(1johr7dnUaCVnB0 z#X5ssFYj?!^7K@lv)&PIe%RhDzQ6e_9iDp8UGE`GWfv!>3E4Unv#aZn3xl$c-azZ8 zh4pR&ed5^%KmBq=*KHcUelRm$yY2oBWL%0;#C>&AG1b6L8G&_*Qr(H1#g)*_fESz}ghuoZI?RcyUPjSC6bZlg*!^s*xXu5H3L(D$f~8c*hI3TUCR91F74SWd-*I zIRQ_42-h1Hl?INZ@mp$!wO3XcG!k;M7LEH)1Kjm#j@}^9r{F%3cxfJ|4zwd+ftd`w zQ*fiDsTS9s>vCDb1eo-0B1^hZf|I~qZq@?5l4F&x7JRJw|M!_uqJHRG)-cn8Ia*9Q6>&Xe2Q1n6iL#! zwr9Px<V=i-kAyY6v+-)=>;o{m;44azWDwI2#*8L>Vl517$&cL$Iu1yif_qz;!pCJ zTt&M{`FkK8V1d{Yk+w4jru}T%6L;5PJ&}huy#P@11SIj&g8mt07#O$wWpPr3B7xDk zy*J(%xsyc&W@1LtqKvH;t-ytq){}kC3aU$S=1r-QvZS4gg?2Op0pdtE2eda_>L?>l zpTdgEIV3nFY%6tCdF*Xzn^y+pE}(D-%4@t0-wU&3sM$o*-)pfRt2!SAgI^e6^DA$~ zo%!hvLY+VGnw9?q&!C#-32>noUAxA1N8k3=m--0z(rh3`bB#y)$1nD1|3aRUUbP8! zMNFZOS5L8<&j4Z4ryyd{T`W|+^P%C`Y#wz#Ud~7&UdYg>!rdqDmDEwxvOdBGT9v)E ziVK)EcMvb9Ondo@RuQYuB&N8 zy75%l$pP40tr>^gWx*l>UW+Bb% z9qt$>V!O(*$OXAhS9q~jg@+Cci{|SuEUB`EA~66Q7k~s$1AE*R7@yxK3ao$ zY`+)PO;QnNtQ|W@4zJPDq|33I3cluRCXnDMQWcMCOZg9+ajxbrLGay-4m#nmFtQ?X zL9)Z2#rUs!55$)GhH%Av3qOTf@BCnA4Y(Wm4V2t+7Amn<>`c#`IyBTC-q(hXLPI42 z`KQ^f?#)6~2Trx1uF+q5WkmN~Ohm!nn$xNQdmk=p_Q~;zMGZGxnGaVFL}EH2TwD^? z@W4BS_vUdh%UI)TGoiQ(@vKe4=7k1fE`#!kG222;*64I{sbxifHZ*TG>yo4|OG==3 zFJ8hz1-QpeVSsYYBuMfVJ-xR~MxNR3CC{8$sv1wX0!OiCvR|I}ITBmdN)V(ZfJ0kP z1bZ(~z&DQvpQJ_T+4XP0^Xt2Jssp0y>n6kQ~VPsf+Y35#SK`|yRk7)~CTUW$^N zniaoj**;4-Z2^TpcCLC!>PX3l~P0)s3_2F&quHBUgsYvG# zVJ~^eLQAlSeFdL(L-Ur%Y3PrT;kga7ly1?!_B{#{yO7_&_{DPmz3WjPL$FUYd*CuR znZ+8Zdo%TA#$uhmP_(NY04zy78U!BZtL9vw;*Tli6__1S;MS~X4pQDk87vF7bljG? zQcD#Boz&S%Nm-G`Ow#7+0sw4-53nG@DK02fax0Q9N3|2ePZO+m@dq~^$~m`w39W^lk#Ku6Eq{3&bI9GH-M$}HP{UV-v|x;n8WZTIMg%_ z)8ZnyyEOwsZnDK$ff7>nCF9ld`$~^Dx$(Lc-TrSg=@XPhB3?0~$d|i(JFlkDxR!0? zADO%(Wa$++4=GyRxz#nMKArMNIxvRkMQ9SPZZU5xLgH3;kk3!GQlXn`sLazL@t5uz zT;gS7=eLA=TYl)rE^~k8t3E5QcOX_YbI_4ZF`g&Y<$5FL$`;Go+X#WwU*f&ryj!CX z`9*U}F>}XrcuC>A=T;{cm^DD2YuXSWxdG`wE>K$VS1=)Ai)O#c&MP!teJM&R0U($I zIOZ_hqVyvGsW@-jVo9WGV)-Ce7$XivjdYp(>Q_tyZA=5TGK{HA{kbb)PtMi*16Kj84>;e&r$XB=v;Hq&ODFefQ)e7|n`X z&jNqG{S2HJvnrA(CPlnxDmgQIdbc~droXGaKL{b4EQ?>PI967*ZaaU8>N{ zUeA`~hkm{7p7WOZh+lPiI4NQWUH_nFFxe${!Cs9 zk-y~6sx4BBS~=q)n9m#=8RRXUP@Oz}%~Ge94e+ACgJ8iIAQ^*$hg+fiQo00OOf{e- z?+wo?HcM84G20OiR;Bx-NcX8c70DXr*RUUgmXUft8u*jMyGjKdFo(|eRl7K00YbBt z?AQr9W5bDq@00I6hRNPXs#41xL+$B`khAe?zsV88-+j>r3xk|+QaQt`>`OaV}@Cy+5n9u9%oIy@1WDf<`deavlc~qN=7{z z(tSSEA8(c)gw6Es2ej4nebp>faKw|};OkM!d3pnv7`9%PWk5ao7Jn*oQ9H%l`R-FX z@-uFP;<1EdI@+Yt7}|cG3RHVj9@HUO`=-=j|CJokY0&~KTBZb}p-b%H%d)BK+a>mf z>aM#V&rP=>d9CAP#Qx;J0UqM2<5BP2&D-;nx{;9Rd9-)jXZLx0JEFYXxf$18ZEy#= z7LqZ7<>4eQCR52d#{nKa_*{XWnIvvV5?ov;pnL$KP*52}shF&wIImK$G?W=!X_J9T z>5g@xXsAb>mij4!^cfAzd#TJRwU<1V@&>~oN(9o3#2EVWTq|pt*vOR<00y7p|IfLR)T=9eQLg8l?HXq)6C62j5Q?|(QQLXxVQkQrcto0t! zt;Uu`>S%Wr;$MRW6-Z`ZQo&>)+VD$8d$vl8-0qCoAwfkz6mw_9M;o`Ea4uS%GfDL0 zXgy$fM^4DOid+8Xw&kfCSd?N-1T+5}D(XLY=a^f^j-Yh(i($|@*H#zj zj;rQ5$r!;LM7MN^2a2jc!@=gcY#**`Z>UpfU<-XZ^Wb(__BB)rbx(H6>G&J|v?;;h zRgVI6>+QNhY=FPk4LN7U&pf?D`t)osQ$GH;!6*9^jbD}>+QNM=E*IGv`b$l<v!=QfxW(w05o3Xn8(?VjG{8LN>dFDt$D*^c5OV3G#xk8 zdsY6-90kC!wvm;fq!@MRELaHBLEPIF-+?q;U)kOw(@1Jlj^Ohea6tdb#7m~Es zBGpL?HF*{*EcB&$nF1dQ~{E5uEkHg8{PkECl%s}Y+KS2s-^8~L+;7Smq1CfoN_ zYB$^7^78B4yYp*0Y*vjeftfFH3`IZ zWyI6fC@oRg87P-u2zWUcp@l6>6$sgFCD>f^ri{i?=h;dbHwm3lALixWnRE_{4p-by zn@#Z^HuM(VqAQ}8(oR$-#*W17a!o>c_r)!PC@MyO>gn$Hobf7VQ55_fHWOomko~N6 zV5Q~7YZ8oQS`Zxvqv|p-;Re_iS~IO*zZLi_@m=sVH+{>O;_1#YQ_ z*08rR-Nr_dLd-W?Mn79uLo@C?PF(VT^=3g1KKIC7VGEZnTKTNLEoPS{&X%Q+#I$?? z?Ha9r1vlhyhF$gY-9AjJWqMw2QurDi5PuK6?g4)+x@2F!714!k@#}9*i)_ue zkxWkrvzz$c)d?!veDB&cvdW!>MAzEB26aUCDvT|sH_7RNA)P5 z97w>u1ZjEm>AbIg7fXV!h^qpJGV|meIt?6&KNnpAq6?~ym{LJ20nDJBuVT%KNs`ii}=<8cdp$Gt}yDifnGAjeWOa1*x46 z{rVe_dQiI*48+z^_ZKA(OfKBd>fjeF?f1`nvBKXIk_{hR4cWZV9;^Bly5A(WaWSlP z9?;F?x{qc`7MvNv(|nX?d=U~FxRxGPN94Kn)!n*gkL|;+a6Y_Wwl(Irrzi%f?o3l1 zW%(j{&KF|oZS+5rkn_qaM5+u3kNhG&1>V1%uUR&|E=%Z+{vp;lOScp(P7(f#X>Zy9 zB7M|mG8AcS_f3(O6P&@y6W4T5H3dd(kePDPWh>C}ydg)`0c2qgjfV01871SZNX0q6 za2&qkItgr$ER{LAin{#gSB!x`z4W#Pr6U8z(~C=X&!GM**Ab{`dW?@)E|D?65zVCgFPc59K!{DO%yQ#Ial*+&Nz<>$46=!1 zCL%ipO4_HE(7OJUgRJijq1Z>~s(RnxPlgX(2a_FO_d-x&e81wBu$Od84R!MOLv3%$;!ssryMuf%7 zltegqV2(L+DVKbwkxLFKN(tZ*Lk4&7>wP_=cJzMJ^KEjm2U*^tZ$a~1 z1V)bS9bG-OIqyT8{5x)U#49|AhY?jKDH^9rczWI&O^~IDAckHR3?!{;5>etY&g}w<1#ZSPs>r9 zz9x>W6m@EpEPQB>KG2}>XgU)5d}uRcZ_CcaIyw*O%debWA0tXLxuIAerI{Yphsb)r z-vGmng*ZKfvW8#uR<6~l$dBUZSD}a>Q}rRU@dnMt{={SI5Rd#c`Lu~Y6Jj$Q>0tTZJ4yq#Pa8N!vO1_Ty zCbHIf9O$Q!e}e~xO~J1@o&j8FxWz@3Xb3Q4qQIe|DG>DZ5r72{BNboD;==PpC}wFB zJ#(b@-}H<*62KA_>~+{NG2Gyuod0oZ!Im-Vq<-xER?~3#SRE27<8LN(jeeh3IqSE( zl3^xpmd7+_`;hla6g`*Rb&fDdknp z9V4cM8VOfBmC{^Em5x|(3{3A(#M4<_aM_9cgcY*VWL-KIHU1kghltCBSe*{W3Yw}m znFe3hyHW^^mw37^2C2(#ZVPN|y4qfavAbV{yxtX^3hoINy_^=lQ%kG5(PxWn`>2&h znGG3@nhq>bZLu@I)sHw@9z{! zaS@i_i^F#Hk`p#v)kGq>Z^uGb5l{xyDZiVmB<63vaZ0il?fm?;m00-03|#h-A^2K$a#e|iH{%zwiwjf9_5OK*WCVy_fx-U;dQF|_>Ueb&YH0x?I+h4Oo?`sw0)sk+{GW12f17R-p|O7B$YE@Q*3 z;#!|sInc;@ffZ$VEc*`Eegld@W+eymo3XKwU#6l%cWcwX0j1#qFMYhgE@*Y%(|I6P zR4^w6Tm4p)q_!M6Yo_vf9w$@)5*PmJ%EdWkjk~#2vtdblb&ks3T2FZSOI*K=k$5k% zG1$c8B1^r|elP((5}BowIGS|DL9#WKiGDVNgx;E19fUEL58zS}drMF!(9S(or5qI} z6dyNgR$uoTf4eF-5jXI*Qk!Q7DVEZMJH}(i88wXn-k?vwyLF{)Im93Yyn4&Vzrxyf zqt&vqruf~+<5@FJ&qhEU`drc1gFNVUQ7y-Y+StaM@Q^G_P2N0WckxnFop_Ptaws{; znVLW1G-2JL;zKa|{+(#qftdM0>!e_?*?i>g$mXWn^ws^9-A1kk)Kmn{l)Y%zh8@9% z9Z@=L{;7_kFQ1+1o)B0kObNkX;=GJlQ5tu?Xorb*;iE$t*T+diOy)v~ROiG<;2WAG zq|VJ*&uPNK$?j|KR0ek`f9y%qm(VS$=F@7J%!EGy_uG(*Lak(mu)gZ=|r%KAaj~R+K@A1 zls>VVj;w4Hf_*;x3u$Q3U379;_}8FfVTAOwUzUjv+g>T%!l`nLb?)1XEXapN)7J+S_RPV>Zo1$5InXNpyqxx(!VqIjYE9y3^2q7iy$j;S2cfob?lQS)f)Krfc z(?U=*e;0)ip{c-E9dSWc_TtDa{7L{4{31 zyKT)WTH8lOycDr;h3ZXj2_G+xod?Kcq&x9{P4CcdglZoMdFJ@cOhv4}u`X2}V5J@* zwQ?Wx&5fRGSnX0`F!XJ~gPpNa)woDzk$phQTTb%wFdv)Am7RkBh*gxsHllGdM6br-bQL#^pdCT z{T&LNIqW%lx1Bd~^#OHq0=arutDYgwji;_`0YN{*zP281&v%0%-|fb3f}fJp2kr-U zNABfnnVem$ISKv-TDx<>tNUB`)2l2#lbPqTB!`5rA8y9#=+fuTTVloT!hVhkV{^CU z$C9-(sniZ;FlR9sjKs_UC{#enj2UB1<#YqMMsO{oO0ly7IA-p^n^)sZi|i!Zvwl~o{3VmYkh#&sV~M-7M8 zrt&NXBX|bL?e}7=O5Me>k2{9Y>{zcR>9E4f1YNmql&cZXsGK{?-)JIZysj8ZPgGf$uo91Hf>T+<)|)wM9P2Gh)L6+_e1LVewO`=l0Dv zKU!ZbqO&bE^igHipW>>#s!?>gY+uc!y0C9TZ0Hi9Z+h^TXbJZoKJEugGHu_x_IBw& z*^@JG2xGcahiiX+x>qa2-Hpur5kC{3muJ*(Fem5{QkMQXlO2;{`U-k5^?ASBm>{9f zHSu}<_pU(qcts!dX~I(ODp9F-CL=0#K;va@31YF;l8YDqMPtR2tUv?n35+gW{wMlm ziekKK8^t)X#oKI+zCDxhF-7DJ_jpve@^yeaGK}-aznnJ|tX#|_RxR`HQ z43)3*1c^j^=2@qM`0K148*B8ecDngJg2LY`sw%7&WIUuF#1c8rAtROt77PTaR^!8K|RO-%+D4u8W$Y}Tn$ zHiYezrdCK5(^g;MmSD^)#?ZDcG&js$J7uI!r?bl>chwBAr8HHh6f@yj!(OZ;ftx5t zag*iWvesDVE63*Gny87wYaDZ}M=VjMY=q69j^Tod<9TEB-EHKCjv4F9C*t@$WBZU% zPIa<7R_p}J3ZYgm^Jx0hFZ6rtmMQ7E%iSCo&*uE6`bqk4PiEG8rw?0B*F($h>%4p1 z$Jy&32U9-dvwanv0u?$TX)LjhnX}i!k}UXfy00%x`E!-d>*omBPb$VojLQyVLb4yg zt(VA|m&1u_?dHBQmU(uy_(hWxqNiMmQ^a&w@6i-=ZcM+>jBm}ah~XIv8T45Pc1>pi zTv%F`s#U}TdA>*4H(y!vnyyHp{&~$V;cT&psbOj(%!?6wfzt{*ISyO;{bxoqN@||; zB3;o_A(aQ46lP3%esw=76r@E0ue_PWm6n2@EZneZcc2XRv?L??cbn#_X8{?lRQ7Pk%B;#sKI6R;C z*f2@sYi4`#EbV>W*d<~a+92A@{>E9=o)E4KK3E!GNNO3nC?nR1t0~b6OH~A61sJIfF-%o8uKPQ;H>^9` z?r z3YOId)rOxrw)+g+ZN-h?g<3wZs%rHFiorfVAM{Q!W4;_VVM~mGTpvaH=DKE{auGvU zPCSYGR>v@NA#6%)u3T>vXBS&KQxWKkncnS>f`Tp!HNgiv3UiiOdh)QC{UoL>jtO0d zSbOv(%Aq^YxNEZtAH)Fm6#+(Hx&ezmm(>9CTEzO5PUo;mZ350ova^iFYC=pTELx4g z-QLqMa@LAfw{0QnTF27zO&O|hf})WgpD2yD|?A9-gVp0%zcd**omqM+_<)kE#ZOjt2SHPT74;r*Cp4L-7@UoLg% zOWE@f$91~Oclng{zQkoOW7KnOL_RpmgGR%`?a~XHxO14!idLKV-0|BtPYZtD`taJk z$uUF2h9<5$GG^O)sv?I#0}_=4jeUM|BL>Fz@9DD9ltg8n4#7n#sZ|qnn}i_T0q16Z z4curGt?D0_Q1mffD3id+rlBlW=2n>~{WMk637H&v4FGMEx%6N_v3<)vyS8p4f;!22W3 zdb}&mEQ;}2_!%q?vUymOUeY_VDS%4bVuZ82zB|LmF-)0BT^+%@;|WK?lnopAYVuHU z+7QHzt*X%{kPUyvYr-cZ$VzMOQeY~wOF5yxt&WZ6_;Lzy>L%WTdoa-3Gn>%6YI48x zcoR$>*7#+OuMg9a$JW!}a?5|Pb zzLm ztW{FF!lhK$7gng68Vy{{jD}BIHXMkZm%?^O?5pZ}qO&9hYkZtk$k^)K7w}!2li6w1 z6Pon<)f%6xm&&HqBG!axry3GFt@k*(W*l_MI(p{DkYXZ=@hZVxSLI#>XH5_ijBL4A z=BT-e@5f8{Zu>cj$NHT$eVE!WE9a(WUiMI&*IZLB<2|cc&hcFfG02*CZo|qnoutW= z&paaNn)*Jeb&10(B(0n>w?a^xdSNw{mTCMsY2;=24&9r@W-cNl88wy@v5=#9d>6qk z`oJxPi=JUMU2JXx&*e^+p!6Bfo}~w*ho%oq-UQnEYEy)~RT-=*H7tEorJ0$g;Tj30 zu_a=5d|8HA-ZXw;)9UkbqMuD|n1?yX^A@t^yP7xJ9Rq%-dZ}ZlUJd49)&=V4fsI_J z)()AxGdsv0jBM>)E6?~@?4%Q`dtRF{}yUA?6KZD8V zra0@4sP&UeQe^1dYcp8xH_vjGGusy4Q^;DiWM7}ExaI_&FMH?~8+Td|*z($d%?hHO zV+od;NYI=^l21QpRgbvSxQ{+rUvO98Tp&hl3#aoaTzpsQUDkfIY?ve{T7^!LG~dm2 zJhNA2NH7)ylEwgHtYcD9+)?ITT6pHGBf$zdYq9gr0xJg2a>#^EG50&8K+3Ly<&gTe z5dlvrZ6vX^Wi5Vch)&Z@>cs)0H_zuKVey9P{oTepW|sA4=U=+Kx(g%E)@5_zRYZ~( z=AblVI2{luk=*{Yw4;dZ^qjv#OE<)*KV|g^SKWJC{b258ogIJFh|DaCDWWGpYNM^}V9L|kRaU)?tbp`)&&;TTmumA1k zRN&UijKSrA;@bOQ_te;;k_8o$ETX0#HADy1DtfXXrrHt9T-t|zvJMwk@N#74G>sHA zB}Oi+_8wqSE$6jdhKOCAWp&U@3sd=-t#7hkdR&WfPX_0O8;7cVwmH5@{BoOTsm}QuFeF_v(IiJ5qOhM_99iiysBlXyVJ?eV zP&1CkoHLEk5%_qI-{^PycuD@_r>S(aCDL*(9iaGN!mQB|u$js6=p{H#{xE!u)s z%+1;t2aaAJia0ikS-!LQpA%4%6Mr&V7UbQy8xE_v$qP`1FgR`UNpe{VYqgnruT+U7 z8+Ae9Uvet<^c-Y!FSfXaN}eRfvdncYeReNM`CHkomrmD(^$?$t5C^zMV0BV$>hySPjAcP`r%i+x;-~EJNfyVkI{5SbD)~|<+zDj zk*ml?rWZSB7#)AHy=M7$y90q`#G|;up{h*<=f>wk+NFDv2Zgg_-3~V%wn?2@y28hp z0qX`*85Q(KE}!qJ1n4ps%Tzwi$K8nHg{3j2CoePeS!1=Wr5vw$%9+}1@3rhc*VJZ& z?e-A^NSd-tw1p&6&B6)_qSXhumU zk;_s{*odkqv*H``>6Q8!s=VB@a|>U$YvOd`+;PFDodLdo^=+SShpchB8{!|tC+H%j zpt&zX^R15VYVSxnuTUvZjbZSr;7m-(bLovgM6F0FyG5lfLwzhV=tS!1fIpsX{L&2n zWU4O3K}f}oE$hfcFR#XCL@ZD{tk{vQEzWGt%azx?h9SfRx#M>KYpQt#R4VL?T^nw>#z|A@U`(2nMEZ3ls@rzUAh{qszrt{A(qq-$d|kWqS@N-R z=@xt>%i;*_=MQ+rEz~kqf)T{d#6xR?SJ{FcaYFM=tvIKw`x|AX&I5)?#oRO)PhR4n zfb3~dUTa9%d()_Nz2@f1pq9xao&MNXb5O24W*)T=7EvQ_?dTf0aBRP=FE{xz+-Uvn zz@Y*X!hT70T}zC{@`j}G23t=B7yc^q&ruDRiu!7Am!Vp2d?@okN#$&logORhfQysy zk~(xhN(z4RsL=$^G+^FKl~%~^^PL(BSjcWQ`F^yWd9DRU0iS`-_%rKe-3pka=u9YlRJJ zhI-j|)`iZ(90ns}DhFm(xMZ{qCNx8>r<-XIdfezX#flh*R;hKU;FmA&Ko<)t! zs(C#}LBn5U9=7HV+xt6?Enf9<1mD@T6V5(Ql}AnSizTWzA83#!#C-3;STP!OTF%^C zf*z32kn!zO3V9w2VNn`Q7uSju8%{UU|I8iMTDIHE>J(nPmt8YBaq$$qb^SciwG@m0 zj({T}!*bH*eS1c-iwPvVgJ`Mh)gcIqW0S!uhtYa!PLC55 z*$>h(9w{VgJgwIAxL*yVl~8f{i4!VTBO4tyDQ0CpA1E#l_f!zLJ1Gz}w^-l0+bKdy z3oMkh`;)N^re65d#1(v7>{=W98dm)D)Zw%`cqgz{s^B9FE8MG>pI*YgE+#?<12H1u z(89i?4U>AyGk=P~O_jvWWkAz(C+!CzVS3Js!|mB2$XnmcJjDV2_)@Wit$!4rD6>yj5-mDYah72RnaKs3DRs0XH;M= zjxX3cy3Wy~8!vld9oy*kVXjVP5V-B77*S~r9GTXK^WxKGc&(i>4^dBrx5r_(PAhq{ zO|pI!6Qp}Od#7vbB5-W7sokKDhrvw)AU#RIz=2an0`ftyk7Q*L=&bqH%AeUvN!waC z$ht^L`)oN383rS&IA8ILa_1L0)a49QZ&Y%s?Hm^^OxJ6aa$5_`>pw4Cky)sHJ;#6+!^>CaybL{J`ckRf=c5C{aj6Acq^(Xr{*3YCDBP*C^PfuCUuUh_&i z6Fy(*M~d(GGqU4j&MDMf?3Lve@V?(XhToZ>C+ z^q`;?$PhK?bJg!!6NEaQ1H&kxsa2LQ(#`SN8qqjf z>V^fNI5!^|gE&Uw04bGmS4!ejZOcMQ83DUAO0`I6It_ugBlg=^M5hVS1n}|*h?Zra zJ%xvgzgg1@Lpr`^FpJ?C4@pH-B~i!9$|6_CSfzagyl)iJYCUvnn3jzyl|ggPsxQ}) zdYU+^p}{onNHV>eP3JQW22n`G$~T%X;yTk@4*IYm2eh7!e!h(34+E=1i9`AlWMv5e zNSuTL38LbChy(1NP>ikPL+v6=}7@YD);BO4MZ+r|CkL5P|~_OL-V zo}+-*LxIJkorRPZb%+UqrO^f$t_(`Kyl5uEh8P{`7LZ07e7I<1inH{}tqjpa$42pt z5EHf?CPk}LR)xT6L#4>IENeu$)JWSAombWH0n6P>t-)YxWpu83rTIRjNL)&8ofE-O zZe{zq;wO2cV@5M#!ju3h+uDReKUQ|415(3~giyg3HACnQ+Ma~XP*^i%wbK8pUQd)_(R-=y9D_JS+=4x18nXDWX zKkK8+T%AfTQ%(gL?u3*)&!4x3g@aRjn4cgjdou1%a5X(kb!cv7;ByUzP&gSY6K4sdXN$ z`AZ-MaIHbR*>WZI`cglsR-}>l%g`LRRn>j-M&`+CB2R|Pg;J?`xoDzZnr{sM!La6v z2Fju@Y-Z$(*FoNj$J5*W(5_d8-YUH4v`+R&`YN^6XpyHUeyq}2HOc)|tY5`wfoIo@ zGo5oKPS^eWWQ*mI-S1l4%NmF2+{0`JGkY4PlzbOERt?#dqr!A&QC<55T_q(u4vkgp zN?ClCtuMNT8nv29{npvc^ZX;lijD}PTbhpTv#K4NE&Th&T0LqJG@MC}IZPsw9!_@? zMtp!>SD4U_Pw-fggOENhNE038qL3WWk%sCgguH~Iz<|R1MqM05gRwy>50RhAnHx~k zr!l8oJFSBWI%tn3hF2wH23X9LaQBT%`_GWFk~cJ4r0q6Njm?@-<(fq(557otop3iOxI(razCOU*roAZvf@5ZW_$x$>dc90fd=N1DA)Gq8fBm7^4amIE{%O2!jE=a(Jp(= z5@u_At4|3U>Ke(yf#dA~oT|iGQD2wf;Qj+qpXvXpW*~B#ghX^+hDB5KBv|ILJ|wC> zhz1e}tsosqlhm|1Mrbc(=}FTh70*+M?Yc?D$G|I5)njc~#FyH2Po<*VEq7M^LkWk4 zv%zJO*DvAXOfth>A$FksJOjyPD4J|Mt18+Vr_y{lv?|saS)=CEeBx;}*8WSQA5o=A zF1emvrt%Ud53iJ`B(px$8q(bt*lk)SgC^T>>YV25D@@!)>UI|ObpaOr-y}b`lBzen zE>mN5YWtr}#i*@+o>?kxg_Ys5d;p;s$|0F(7i!t^uy6akJbz!WeB|39ceB*;=u z)cQ&8KhU7Rz+wk01QP%#0Mdn6iWE`OlxWm;t($~Sl8Dm^61eTLn8a!8xb3!;8%8{$ zEW&>D&&}1kauhrqNhAh%+PTrXbH_zEu`1_0T=f;V+N*}bQPq0zJSnd2(eU842U>L= z%jv{VW_mdCS}~2(mB`qe@*EBsOO>9Q+|=CJc&Xf?Bx&LXhcXOjjJh3?OA`UQ^@afp zRKM$pssr7y3fk?*)4#k|V5eiubLcJmtfy%)Hu+b0I_yQ`XH_5*x|KXg&;B2L{E}b5IOyMtU#=7p5eHKPYIswsy7wXF508ro|QYr!{LIQC}AjIKi zAqVkzEvrgMUkCs|NS=YrB1>pa3`?_M*b+7NTj zL{c2=TX;etL&WA&V8YaO- zv7U1Fn5WKYlWNHq(2AyLHZ3EJ8-}!WL%EF&MPdC<4R&Vb;OT;8eO6V5W$P$YR=3Qb zWC<1Jl}V5-84M+>9V)BR5S>ktVC2Efkep?QtgitBR-}%KN`+>^R;p;hk?^0D$QjM4%_mNdeL6vBPFb7s!)n zf*=ow&Rz05kfQ&;YyzzmN-+hiD4$XtN@GdM`oj^O+B8p*bEsv7%XLnpZ$WN)sxffL z=HS#IrbvH9hcT9fGnJPGW05_waXs0p3;fjlb=m?h)O!CwqMS#m&{({BT_AG~Uj^~! zrW^5TWby7Vb3TCvWV}emPixkz(IvPG)SnzjcN#D!@FWFJC=2^af-7utWf>xvt!jp> zG!aCWr7~f`7kV`7!>%ltyf?o} z^cqEnYCv0#Al@e&Skny9$KyE!Epig`Z5Uju*<){+JQieO+(xj^p zj`0%!1B8MB*v-=enE;&7UnFRxsp&%@5>ss{I~Sm%Xkv=IOybJ5-Smd2XJoUXu}|J;2Livav`o^b>hm_*W^vBAIIBZS=5E(5^ z7fLriDv(ZPbShMdD&V|OOs5*T+?~LN*R-@qaluheWwB`Gw2$3<#^=Uj!_yS9MdUmh zD;93Hr?D4QoHnCprhx+t1e^B#CndBb078WzLd0-@us-;?eMwsi3fk%VQOe2Yqo%`X z4HR}1?hMF>0LV1yL+n#fhsBZjU&<7h)Rt240NQx~S$e*O_IwL*567gWHcv_ta*d3_ znumAk^ftVQ!#1F(H=oy@E`s|43RjeMCIU;i?=Okj9;G_#X2Nd>ttgrDs0=0>Wo04F zl}z=`*XODWI8=b>^i z2m>A+tRBhAf76eJm?h%Vj)k#){bkW{6Ux7TibfowU4o?hm4+xpuUs)^fa`NIJ5iP= z)HhiGjySwHtfg536hJZw(82S|O-D?AVkb1Opar|oz(8_4=B4X^6$o}TANca0d=&r~ zBY=XWi7^0X0#*aY4|4@+>J$kYJB)}V&U6jl2n}vkj0I!L5J))O!;^00Q_~YmN~BlZ z%=tJt;5y|L@$M>>D|sTT>rd9fd~}rNjGxN~^uADKsY7Ms;LN#maJjkMql`FCE>>oG zq9>Fn`i{*ic#hFGXe`#Q;nr+WF%q`fGlnIlb+2Dh(;ZdEofjq*;@BnBr!Uju3$Xp6 z=c&!oU!o8+*9KvM*i*bOT2Y=47QT*`+e*mto_EEwmL60u7&*t0X59R>u-=v7$J!Q_ zfbNHq2FR{gjx#GLdBwL*MhwWbvYZL#=QiE1qq_K+sZ`Y9yxFAQH|z@@D3NI35CGs2 z*%8?RmH+?;L=+qxC5^$3NeGAuQS1xRLrsn%R;nPPlec3{7;_KTxRF&@Af$sL&8&z- z;Ep_^sN|5RVoyLEP@tAiD{jBr79WlzW71U)0rGIt+H0~ebmOzpdN-Bn4ewBtd+J+R zZWD2rq1bN0Se_2Kmurc-2Q8DfQD=Isu2D3T zz3WHoHy7@7eio!z+#pJiZMN@^9nu0{FQ#X-Em$?pTyjQg8A2~rT9t3peWyL(cN}U? z>I^6y`Q!N~MpYQ`5QnM9mB;2FSp-_001_F<6%1K7Oy$)f+d_yWkvSA=OoBOlpl`uQ ze#3||#OHqiIg^IG%MU+3K#WW;{#8?12@a@(aa}G$QAp%Kok%Nsd_eoRKH)DB8Yu@+ zUtwa^Nk;RxJ4U3z@FPZu@H8)z(;#vp7pr)wpiwW94iTsqn++!7$q3_zt+1w8F~=!E z)QBNr>T)3w;=>!Yx4L)(HTrZd@^)2}eS$_~vMKF4Kj{^u(>r=sOJnvE#`{^9uH~Bf z5j*n`tyXZ{%{{FUOHKMG#H$K1mM49{+0Cb7f18a1olU4{rpim#z^y|^rS?3mo%GUP zs@{_GX5*`mBeRSA=O5x+6!Rgx;;@8?5P=c}W^ggecM6Pe!H{@BViATBY^p$y7|W~} z+Ln!>N+J2bcoe!&VeO%YefzmD4fn0_GgfLsN*nz5LSnQ}am}raAz`6P(2~JPJc$1x zX+RfEQGOv;h*+a9p$N+!T1A$6YA7rtl`z!0fKm|)1O*2m%#g*w{Ekti{CQnjRpWZY zgAK0a&fd}oV=pZ-rcp*l$=p~+ONoi6Mhl~P-GDP+NjV9vfyB(dPQgkbqQ<2;?Z9xd zRNJi!{8A=rO?u9c1ah!z&gc%^pE}R@BkSiWHUG=%k-$B`q1s2K{OjD0exmObU?g^c zWH5je>Obd}F#rWJkOE+a6-mX8NgqN}EU%8F6iS^YWx1~}X{5-Tt^v7U4*ZEoUzsEZ ziO{e(of780LdFjzF6G?FP#z1FQ3yp9Ofg1~(1-zovHpRfi$Ma73c0Bk){PkU9JG*e z(|`I@Nb`*e9y0^L4#1(F3P$M*OGqVl(TKj=i)-(4m>i$Sm9U?t^~hDP!FB4Qme=kp z6uQft^s$!p-YlV}lcaK@_Yrfq!Jp}j4ePet@Of%Cstp_#A^b>_ni2wD{XDr@clU5? zV^H{9M8g2UfDlChkqiJJE6xspLal&2i}xkdz{-jP7+|0)*B!9m-qAQeD{t0#*op46oPI zE*sWIIezSskmTTHvezIwm)Ho1ace=F#jj_+*9|1c)qU<2Fcb>=b<|Q%pnqp-;s2#^ z6j?xwEj-0PKTFM3InK694~do~P65@I`12AJC&qm3mfxqh;Wq@*n)n)0* zGsew`B-0@D`q7&m89L&l)WbOB&#H4>>ja0wc{RE|PM|ZBqpNUL{kY*eQ0?G%)Axm3s|%i{5;ci7jn$p5<9xiTsWBihBe4!x+Z|wW2&awAxIG zDtcQw`PHg{#4h#y`?>}chyEIA`mMl&%sfm`TFtgP#d>bTZwfMXnKKd{ZE%Q{zgGa^bQ z?Azs`Ffw^!bc&0TF5#QzKAeh-V!p2lu?#g){@d)J6JE&OTAxG}rEfQ)K&`Ewf833)L#;jD zvFuQ-!On%99efQS{y1bSbvy3xMzZqOhlqTpgk{Y2QL*mGs^Kdp(jOOl4zRNGNXxb@ zE;Hp|&Yo$j8R@%yu)tq5$eE%FG~OCmu1wHpFYfZ5~XnLmXrgXj7ftY zsr`k8Pb*CXx)N^O*lo;jqJw)EocjXmny{SJ%$6Ac^kfAmgG~I16La_4GATs@7=S(M z#$JHXo4m!-k)X>5A%->whP(hiVv$`tv+|nVwQ!c=%&^<<`syPoO!gTkYCn-)>7jqqVO*JYyPW%yXs`0vO0>{b8Uh$0^>Fz!c zX>c+h^Lmb_jn-Q}TQOc7372nTBRR~ffsdWpo;}7Q+Xru#h7tuik3&jBajgrO?pHkw z^5~$(N~-7(f1|Wa=nz^(1LNYB0;F~y_@`&!rXYgHW^=(+t5K0UEWlvlKL8G_AE?-V zOM|gdaX7AxMdsDuy%0=a2${Y(-}pWMizoJHL{CI7@?N2oxJxH99JjaIwSZn4i#^M) zoc5QtvHd+N?v1Cqx#c_yl0 zU|}RI-m8nBWUXAhB~`P|A*!V7UhTGIFGe&K2rFf<*SL2gi=?wg4lhe{VMJ`PP zrEL0d35u@CM7t@^8~xM3a~GZwNyOs0&aFwT3!*f5ux2Kh$U_u{vEF1kn;4}^BvnSu zJ64V^jF)N0SVe^DMKV2tH<|m;K{mX0KTl@btUSW?e@&!S80rP=1IYcmGLw3u;Lv%xW^ZpkWa( zJ!I1Um+|_!DX=9GDKMm-R9|&pd;fR_g(GA0a$ivMIlZOjR7+{w9@MdTBD^>RGW>a& zY^{}vE1A5-6CiUg>(UU$qvjhfyNmmApS(Rpp5JsY7Zj0q2>P`)S;AP&sss zU}gg`thO&WI>NE8H=vH@XzjiK{z1H^hG()b?4ao(RoG9Zkz0|$A_LUYdEIH=T?@<% z-&T_$r^w`FgX)$U8@}^YJ(gx5Y&Ne;a5I59U*o7HpP(+`!#b=#WUAknV1gOd@cv>L zO*ri4`BzU_W$k8(i^GA z(098x9In<~dx29)Qx2k&=I$<|*2$FaoV249l)Eu8^`oeY1N<+I^bM}? zmL7oL8V$2HD=j9#KTYp27s#D$A835osD&JzdseqWEr}A2jy^wjBR}bWQ>!kHy%y|| zW|OhA!zf6c7mIVvWE8@j*-cG!C9#~&7l<*PaPy{$Pjh8p>)r`qp@V&J)T{oq_#;3G zzViv4B|zY(fNia0jSg00)fU5Fg~d3l>$WGocx+%{1`v z<*q-`7edy}|2T#?1!S>|_^VbT+^NPW=iTzwKxmn|Z17peN|x0pK$(*~M7*ToM6+|8h* z;9Qb&{laPqd>O7Ace?NhFYBfego?Ew>f4XHY;Hcq?AcIjgjHC#cT|~Nbcs8%!(du< z{sRJyJK`1!!D_E2%2{FHBs5jw41{bgZKKSuIi)2cC5eDr>>(Ja^6F%~?1Q zV4keJi<_#+FG_kk>hQ}Sjsp5SQHo^aRnZ212Y0buR|nLa(`1hf`?k^zuJ68; z1^+f5Ke$1;*0Krch;`F6Uw}Q~h*x!wQC|yTaN!Nq4T|)`QJ3L|tdsw7uwbbt)&w}_ zO*LO8N-hg9J&dJWN$ST})$cUbJ+d5}yy279o-w9g@tU{a@xxE^hz$Qw6~UNCeatu= z*e{*2Q9M_lE>0?LIVqsrHv8l?YoaB#R~GMmD7Kf4v^OK@=M}0X zC#VZD29Fufy=Booko1f-3FwuR2wRuFqyw9_VFQ2nq@x_zFxlXTgcP&O_Vwg~M>rX> zXMDXhfv6n|OPNXpjMMI;Sp0cb%fI(B_X3N^s6p9>g7t&hxr2AN2`b<*xjokwQ486f z$6b;gI`}hc*lLqY#d_XA{1C(sLYe=I6-5XXteBq}Awc#k_640{&YhY=_I{d@OoQq_ zKw1@rJBlUGZ>*Nlsc5QH6aR~Fc<<2_<=K@ZLAg;Gf1f4w+QQ?WtbDqTb1%ETs?i@i zMtxexNeFvB0UaS_8rG&knujYU<(|warM{rhq(9?{pHi%5D zN>hYz&wE-oL06Fr*Crl3U+;PBm^xBd)`_IO;x{|2*S`Iovkq~Xa^2`fwv4Dq0oG+K z02Q@;820~q2uxwS|49xIUW?vg(w6+0#ag^ey}y-Rx|NzqL`d-cpv3FUw)KG8KQ?eb z(YseIT@oE{5?p^P@n#O;3^^f)lxu+px%>HMg!377iTH*0%}u{;Ew5y$|Axhcj!EU? zwkwk%Ep~8I1q=5~Wh$rkOOYm2II~Rhcf+fXDtkKg9(=ESu8ULS)2r8JLCpRUOnrTo z{hP}?A9C*Q@J=-Zm2}#@5%LadqUM^2-tx19d(ft{^4@pIWWr@^Vb|>R(-%TD1_1Y4 zFj*w48t~d!u}GX4esDWlxw=?@T$wL(K9nL|T9(532?&?-Xy7dn6p}Q$M1Q>^c)|(z zinO$}_PlOD_;)xs3quCHAVI?vG8GWwyc7Cc6zpIv+aucH!5GD4U=aQB;r7RYL2`Pb~?oo9acGw8ei-|JnZ z8#mGe;u-j%1hJhY3mh$~eDr>&i)Lf?{SXM0&}JVIT0g{-=6*>|eW_|H*etM4-)vQUvgBL#bs3n3 z<4tDbl$r7N04?3%k}3||g)D5eJ2uWr7U^z#7oC!WRHP)JyB}DjaW85`O0C+4Vv<7Y ztp(@ZdQ6>W``d~#swCIe@L8Y!0T5?oiN_5d^z{v-K&y^*Jnw&6R_5tiR=3qKsC0L< z?H}MGyS=I$?~4!KR`jDum*lB!UM4a2EOHmax~g)g?OHAbr@Fyk*BY_v_y*}z8vg-s zW3=jco2?k-?9qNKWXHPBpr=|pV<*He=fY06;zfxXBMe8oanvxU>TuTI9Y3FcTtW2j z5MCO(`(KW~l6T)k+qpRM??Lw5#OfD9Ub6*+_qB|8Cr$%j|RsZ|mUtpDvz3O-zwM`yKF^ z4TZlub)QvfhYS7&DN14;beDGex+B?!1lh3j&7~3sWs+cQf&^mW_pM8H3MdB@uT7|(;F;{Pk}PazxRD4T$9l@{sESLwYcoLkv^OWKrW;($n`(>{8Jo z9oD?~tz3f~db&ROsw}&m{5Y~pQ(tV@4Ne2UDB&^)?-B2?4!6>Phm=^6Q!RcwzIosi zJx6fTb!zbRC~xZP`ahVEPteai{n|uoNp>h5BYnf(g20O+guIjQN##T83hy6)*R^hC zJ#YFC6CUFzv7Hi%y1=5?$@x~=<32aA^Q)RMpO3^eiPNnp68d0d0)v=xfK|gDs`Zt; zLCGcBa`m{rs?d^wyNq$MR%ZS!Iw8j7z05K5Z`!=q$(De;2lDGd@OKM+=^CH#M!Nz# z>?WeTU7RGW!1o?bO??bxCm?Q$C!{IgIjP~vd2CHU?lb5B&7hKy_|q)=nBwD&(&6wV zrweDiKrd`YUhOa2J~w7nCp67L^ET#{q^2sRHC2Xw=qB(6Ld(kPR&cR%vV*KyW*oY? zm#N5IDT6>oF65)Wck@+>P9_vcXSC z-{~`3O}{1Swa{UlY2W*EQyn>N`>ZK69ql-iCD??1sG^bnx4O#F8}{1&g^;dgW?T4$ z;v-Pv;{YV*hG|@q^|+YH(y7DpF8Boc_76~1y}4r1?M@!oqQTpndF}1bv4HDv)~kEz zv@PowiR!fwj&!L0Zb&;kzF6uvPxn)ttzoRwv4s3PPE?kOD**9wQpNs;VJxh8q%gar zb_!G+1bZ-05?JK=%z@05TkmVa*N!2%Fptz5lq6ftM-6GaD(&jeJb8X3$Wss8`_8)VX1kilC$*|PG&M`!5WJ(|K3%wfK>NczQ`*%DCGa< zBjaF@LH3{ew|2%vy|y5nG*EiQjKyd#IWAM$+IZFSnDT>RX+wk0TDw4%hIQ+^)#yLK z%certfWP+FScaF5#_0Mt`&$u-t)*v6F|v)7pMl&@&w&jh49ps@0Zw z8OIr^{-^~yk>S8%pz#LDWk%7(;m*<(SDckuUSb*MB*}I9Yuy6o1{(bswlH?q-zYfE zpizs`6(gG%4`}pv1;l`lGucz@6Vfuuiy(_X>%Ep=OpX$wm(Xsa+qC{n>n8}-<7h75t>pa4Ifq|I3!a`J|U)}BdG0p6C}3!%FN_n>i} z4c3dmUD`qndz&%?a%%VZSKFc;^4QKmY?l-&X#+fuv^pc}C5ITRg+4a=e$&m{d;^f^N5$VS{b!tqC_HBH<3fXz;9n`LXCIC2EELS%8%ta z1`npV-ic!HP~cY&-=|uXw z^g}63O?dO9KJ3f=&z_UuVq-;M&kU4y3Kzo^3&MVf$8^(`(E!KRD)xkTi&FHVXG_cX zWW(tB2Va3j<}{5RiZPu&GYz3dH z_<;MKsBuErlbkmKp>H;ULFEmc^EVu^91|p;1MhndF5jrY^nvTD32-#IKnD8W z2lx2q7g2AH#Y`iwYX%mrIu`HJ-k2I3Z-<5ep*%f@ZWG2UG{dvbihHJrE+v^?S$~!U zN97iwNjH9T?>`&M5uJ%>k2k9xCuSRW@G7kzrH6t5i+TyUw86bLQU`bLGZTeiosyFu`6YjBPEJb#S zyMHL0h92%}EJcTMqF!cqbI|rnEcdp8^Va3~9Ug&>B5D0~HmOEWr*7<4k~PaibR$Uq zC9glR-_7CEcRGzp{QwFP9<0`;`7@4}_@|MbcSVsG0~FPX5n-Z-XP#;cSP3NpU=6=+ ze$2&}@2m3v0IxYp9tdj?4py>k{bcQp`44dI#g9@v11biIDVs16tqgJoO^{Mged3p< z5__?wC%ufYc#^A^dib5c?jy64P_&kJM7B71?{-A&TCFz0MGA)!DCk37KXx!?G+}DP zQs732n(dTK3KsR~SVUhuZo`dd^xGurXpG0U*bnDZ`e41RU9vZ5XZDv%>NY-T&$8AQ z2qj;BRFS*d{S>`4c#jZ*zmD&Sm(X+446V4?u|`$W{~9ETOPpB(1KT=f-|1;S7~b2BO2>DM zw!riSTZK9Q04O#7*p;H)orFSOBb?_%n``=#B&7X!t+eTM=_rQ!Ix6`3E~PsJr%qC5 z^j!L}({9hd_|EEA4+21&td|d$eS&&VQ{3JUV#LVy(&%%mzK7dfL)MhDF0bB9xnOeV zYj?G~vgGN21nPofooANvH_3d7fW_=9Hha3K?oo4R$7b#()@w3Ncva?E?9t!rAh6Zn zMxC*ZD)N`#EHb~VGfyU8#61J-jaaXA;y|oiWcP2TEwT^vD*wEr74^m=HZ+&qEj-7 z>rYqD6sU`h7`)SHZt>iWfubT$d7Q$%R7H9T;=8<5ZaEJG#mH5{fy4xl==dp`n%P%$ z5p^92r@s(PEDcHuHG!*w*1hKk5(H^&KbhD($7&0YFdgY2i1o+)D&l+usmG zPW}&&D1SOQS&-1)z!7eC9nLXxo1%0)Jq+>5syDGh36rwo75}rFH~3J~IUL@%Nq)5T zz_1;%dgywD{YkId!;T^=Y}3bwEyu|=+{*ixAhPZ`dm!TZI!UD5vTp0e+=qXF@|il*4~D+A%VAEIp_@;5MXg5D8=FO3@|LJVMxV#~O;DM-N?v0r z#1tM1McF>7-OerMD0uBmu4k*ntNHcKe+97fV;0Jtz4it&f|{vxoE8%e!{XU{>~CD0 zO051mSFEf#j!IQ{E8xZzE^ureYh88ZGYp5$6uHE>`xn*xQkl2`t^1re=;5H;CsuB< zyW^)cVkUe)a5IAS_2AE`H9MJc6QSED9OQcwz8>iaOjsF}nBZ6nTDl~1UMIIjUqUFC zJ5Sw+ev!d_*BI3uSNMKPa*O_~Il6Ckm1uVCOm*t%hf16!DQ5Lv*uf?aW+Ad!cNO?R zaq_4gyLn;3tzSzEkfTbTp>4i!1(6w^iWwBe_xCbma_#5vz4;|%pCZsIOU6w&eB0@x z4_xkVEAz29S2~1}Av>}|A5(vIJBhAuP)cf*{H5B$OX4YpU8%*T{;N4}*z!^>Dyf9X zhw14|Q@ih`)I8{(`=viJ8`&nriqciZDpVJ=FuqxUz2;L>{8!(_q9$f^bkSCaI+}a8hz^q%f?XXiw~q3!ubnbUu%M2(a&=?o;bRU zd99v@uG}d0KSx=L@h2{DO;@8hi1CA@c~e51DKB^OeI-@sOVt&Q#k>n%HPC4fnd~%O z;NsTkZsMmD50`t&$on~E9YpMyEpxvf2v9#5BpkF&ta4PBp<$mp^a9=21N^yB23G39 z=(C+YI*GnadR+qz^-k|?56V(heCu60Re zPSUVbxp+pMuisLd6uFI+TxLF7t7%3dtYd zxrU3nhTM@MzLP^E*(2dp38niNnyIdqK8%2mX@dsZKZpzIJGA)s_yJ? zM2;szYY}so%#C#<&WsreYh{b_`MQK&aDi3^$+_FT>%1;USHExclZpCM_rrR%!Qo0k zN9zb`hm)N}FWut^f1X#eO590?$&Dr)6Bj9duTi@{nG&jL-t?+x=b|A=Q@7`i+okh% z`kRZ+i2k8ZwF&$gotn$CVB`4p-|LU2gW4P&iXkhY;MX}-3uD3izP(9PyH(4CEM}Dg zB1c}HPX~@sJkiF9Os@=mIBWf?p+Fd&2=K@3Ho9Ha25>R{JCebL=&UPfl627+L~8w3 z*a470xo|1@Kh z(6#~{H=cgf3BFxiN-d65oQqv{fMF;?dXKVH-aQp@wx}= zPP;Xy+^=>UYlvYb#o8;&$AtEGKGWYTVnYb2CjSPCWDs6`v#{n93|PwJdI!r) zF+7|3`7VBtDKj2s&=ru{gWw&y61oB{E#Ef_vk7{Y5rB1%?tc8ZzpSW!m&nW6SATt< zGZsf%c2v-N3o6$masMJ%7VT!TOeQ*FBRB%X<@4I!iC9z0XH)FW1&8WA`arlDQYw}@ z!PS)wBaxBA&GS*0)DwhxckKgXR!7x!Hc01yIa%IAF&IM(^YCe>!=(HlfFhO3M}=7M zt;7!J>QZ0t)kQrzZ^dy-4sog#8187V#boM|`R2G{&E!fFdtq5U%EjV^5LpvaWt~>j{%7-^b(?EDHTUK+E2# z#{hw>_yh7QF=diBUYh^_kp)tWZt^2#!`Vf4XmAqBJsssLnR?m`adlUAop8BO)ffIP z)poR)dWz36(6Y*SoFT4M>;+y}ZRjriwCZg8dZFK2=4fXJX#Qh-U%U;6jKuXUt4I^% zXRrY#wDAyyo4AU&TTSodjOmiaon#BAA zXt-^{eF*FKj@^p&Ml}>#MFkIXpd=r2anFj4!g|jcXx^j<$scuheCK%!0Vj%Wfcye_ zIYhUgVbVV{DY>CXf*J@|DQ*7xKMl)d1sZ>7qQt&I3es!{F!8I0$N4~bvLpSri!!nj zRPeg4_a%5fuk>2(22EfwPs1AAJa*ZChzp+Ih^X`zdGh~u=LacJLv}1aD7;mMVGf~k z8Ml@g_d*_i-@k3r1ba1)e#L8i zMq}ywy5-b5N-UMtS2nafCO6xmy5W+zRd-p#RNUpVsAkLoE1~~$WBDa>Ts*pHjnqeY^x`{GhC!C29lnO*>vRbdRW&e_Me7P$UD=ur6;fSoiNMJiDYkco6%zsE? zzt<+bUf2~JpZ;21^$&pY@MiN55Q#J~?UA2oNgTxENBs|QZoKCH&HjGv!yNNszqOfWm*)q*FgyRBdKvzQlW*GK>pEP;Pe*imP1_}psJoVVd9=(!pS||b6Yk^*2 z>UnDcL6kRkBAZe-@2d~sjU8($@X@r_qE**HQm(aceMa(oE=Ts3 z^waSTpD&MhMH>dVdc;THzGDvv&;jGf!fdD=XCiL+4YKwHu0#)qFduT3)=3HDJlp*) z4;3i!3Nex8YaCHe0=gva=O`0v_-Rug-|`n;sdCiC>u`vVdw&i=`+qA>(oEl}7kQBw z+aEa$8W%N*`6(zpN5tE)8c6J)e$mo%RAf^^A~WOf5_xc~UCmn)SbkH4>`M$G-N*yS zuC7ZZqqdEx(U#1<@n>eh(~Ao8%mENB-Y}`H=I^{Fet@O-1;*PDy=sb+_&)%dT$$KS zXb>>bz(9q`?pz3eT4klDMewF&*jP%#SZIR(L-Wl3AK)^l4wyG;NmpURV-dagvzh-& z1ApmoYRr;Lx3fVEZ=&AcD@>IuKW@=Cb5M&5ps1Cjpc z%ie`i+qXH(r_59(|S;K2qd z-o+sN7`@SG zWHBHStC(`YaXz?F($`c$VL8s#9Ns%WWK&6K>8`)t|M(2C-W93y^)Q*{Q&#F}8isM>&xD za+FzBP`gUT6RrI2%mIRar_GE0!=LO@YB=Ily!irV^LALwmxvAgeu;0|l8CRWaCkTp z#?E$eD~rY?P0@0W(9I2c{`zhr;zQ*i^g zPJB=Ld=)d-gKhT1w-A0obn@6=;o*Eti;(r6%%YgRGUq#;`qUX6Ft+vC$^IruXTpzX zxHMIuK}XPIuwY>B4lSK>N+NXB?L*CJ;B*vi%q2%v!)B!U6-#(TYjNTFPno zAgn@8c9eFr#^mp+=vN4)&oo8TPLTl(f~Kz*2$e(p0bxhQN0{(R zbiv(|^zbsV)wOGj-w>|#t+6y;g0wkc9$9I0Wouy5l6GvghJ^~6g-OQOI1wpt`Z)^pP{f z^kIA8UU%xHmaCV@F1sCAg*~i6_Ty$nSA=$7({*Ym$C$*ps9Mz`L;Ui!HCq|Ppv| z-sBe~gA;i24tAS&ZFuM7eqvkMYeQmR&d~u5#tfrzB-bmhaGsZ019`G1ZcuWb{FffH zllPxUWX1JHNO%m7w(^X(sel86XhH~y1w2kF#^FxezM1-Z{@m}PjiWwjnLEvsl zlo(R^)6^WASg(V(c;G18b9CO0F5*Ot!{+(GSM|jkA^>HJXoJqrr ztj_H1i@z)+8liFOXvQvDzX8E1i- z@uHVLY}T-r8*YIuO5352>!Yo&j*dUvO0H4>{mnr9Lw(Kj|IzdoZc%pc7q5k+Akr}8 zNSDOWAzcE}4bm`lh%`z|4c#f-of0ApLw7eb!$`{@UEeeB@0@d8&tI^g9rwNVUZ3T3 z{v*%rI_fwzyliqWPva^Z!ysn>gK@4{8}I7h{yR#AHxquDd1M6fsF+P8i)zM}m@d6> zG(-TtH!DHLgrZ9!zgZTLiYOD|*dD&2Tw5;N+*%yNN72y}lhU+Of-Jyi4v`zH-__n# zNGDq-mARU-=MvYcLX_86a2NghV8UYWGSykpg!oNyndc>AK0wXkHGcugNt=4h{VmPB zk(~HqO)~5hv$aGI05(fl_G!SnEc(3n(AYc?eD_+*$y5SIZr6%rG@^uC-e83K%u=19 z-b73xsgvl*7fMBkxpJ%9C?HqtNtBy%TA$O&mmBIXl`*TB=ExLk{d_eOcvHp!obSe@ zZWt+b=ukL|m~+h@OHPhp7B`yZ@2P$3$-j7oK7D< zb{o)8qF8ZGRxz4%HYZ*ZxHl*JD=zG<>_N}UyldFzNH}pM%`?qLD*5BJPnuu*y=>jm zjY)9%kX73Bi19CPt)AK8sgV}Vp4uM)l3O*Y7^J=g{Ewn46`eqm%cxF#b?4$NQb5TB zXfnF=X6%zETqYGNEh;y_4ZTM3%qQg^|BJB!j=IE`JRu~fV<^x zuVz!@p7CH|khagRSU~!3`;zzz7i^~KIl+&sZdzg*W3h~JopA*w7Otzu#?S2n)v2%7 zF&2Vi>)e~-r0?ZUSvwegwGz8Y&?n}3dnugw1^0f?Vkn;r`Mw|NYADv=aV~WO}3YHf(@C}O~Ma0b($#Cm^281um zyd2G?8@N_sBxS;=)NE+#?=^?}S4}Y@Fes$!vXl31EIs{4zqDwUeK(D2w6m)f!Xx&1 z3)1@%r?^$Se zfb?wq=Bkgh_oH_Ht}DxM?IIdf%0d2E(6r?l^JUpb+CC)NPoJo+5FXLhBRaO^3del+?k*UqJ>(Qfi-XBTNrWOSvvt z!i}QYtvv1nXj~WW?h{PT)a2q#I#r_>ez;47g{p^5Whtl~r}7;ozFun2_CBNwglCZ(%rIZIkN_zy{sHp-YoSAu~zxEI$o7C;g z6JP&!ksUHBO7!m2U0Uf~oq-zHFp2(&w)boRd91o2sk&kc_PtplV+M$Vrw5#ij^?Xh7;qr2+M(-j-riRS-PKzX~PAMJ6 zcoH2df+)bi(jdA{!4f0v zK1R?W(faxuqxZjxbl>o04Vfq;sKsF4h$~%y#G;}{1&{>S8x)D?wFrTnnsdUKoVpE~ zIsbJEVK&#FCzyz=*KB})&z=R4wf1iQY!g<#7E$798_QKnK`a}rfJ(j7_48j} zbuG|!VJjkkl|RYrWTwUIM1F{*pd1n5gQ`h1e> zZmNN2;>WRUyv+5sY3;f!l91w+Gg?)Ue1mDv8jSF zs|tnqYHhxbAeN#d!v3I{Bl5c!6zSn9Si1KRdbf49N7+(sR;Dt$4WjGBmMFKQha`)o z3pQ;R<#J92Ddig!-&q}2-fc`0s`@AU*awg8TfK?#rVc74V87bX3A#>^HKt}}J@%E- zgLD+)pIuQX(XY;pxS!3s42`*!(J;%7NuB_0RP!J9te-BJtGoH79#E2k7e1Ehx(Spr?Ph29S-&o(b}1ZKSQOl@^e7xfjj?8pyEr0yX?c{Tl2 z5S_40`HejN*Wt6m>Jae38l^pWZP5C+4{Lkrrc5s3^idpoSbK{M#E`vKcsZ`=ZuUgm6a)b zi&b7SSQc`9x%8t%8;hes51L>84;I}jgrDe%Q|32mQJcE6Zl3_lfJ;iFxOXY<<`0oz zJMbo4Sfl`WySVuCj0?hEuU{}{&G+t;$Bn;`q7KoR8;VaqFD^qeBmzAkjkQaBW?p1V zlRW+z8%s6~9BBTp3dK)ZdD2dtSNqAPqY%2g_V)8h(?^!~$L2#i!wO?voUaBl5n0Zp zy=?7mNo*{8bvdY=iPOLIK=kk&dq_flSh#hPQOt?ELw<%gyq%E@yi`d)gf!OIAx;=y zI8gdf0{0Z_v>-{R$4#2F@$FOcePj{4U|X?ji`3CaM!H56=J!ZL9U7U%tW3K2D&EVh^QB+UDjTUm-FM-6+d8O(y=C_D&VJ zbv?BdL77MkzuJE#;Z&_3n)^PZ3Ze3G zyI>jKXzP(V1nDNwpZG|YVSCV>9U!6Kr$`O+ptBruLH8<{%SiYETt1YVyxV}UI7@l7 zG1Ml8-g%k&b=OUrZ_2${sfD9;8}6-GHg_duCS-BO z-K9FCL8}v}+|x0zEv+=k$ZP?2Zsb9v!2$M@93UWc^b^|8!B113ayJXn8Aq^+-!GbN zd^|T9;uL{&4-6w4X8*1~d0)JwbDN`Bs$~=Y))C+t=HV-({*LbhUb1qa>E7t%Oe}9q z{&Uh^Zq8y#L%wAasinJ8(Wc0PM6OAu-T<03=ue{L<*g4*)3(*pX+7;YPy>Lj|P>k>@pl@gQvs;!Df zkt@brX>kP~MahNYO%(v7yrW2WkMGRiWJ(rFwuWEJGlYhex~%cZAP;H?K72vZHwDn` zim(F}rJbpdw62yf#irRXbvSaDL7Nk(I{I@D<q*jM(>$B~ejA{iw(tAc;2)i)6@788J>pSxonsnG?;r6e{?wD^=pElj#lr%ZG{#}i zuJr(_)X_g;X<0k#92sv)^P#Zh_y=AQ0(zPWvr>ucdpp6e#lo(bBPw2SuUkvE?0Zz=tjsPguh}%>}tex{7PHYjnOU1TmjpU zC({$WUJx7T%=wE|7RJsIk=bZK9N+rofR%*LJ9OQM5a1-LL=YF4*ei2>xZ_}^+ce_0 z6uX4AyL26_2|3H9cw5`U^w-n(>HJB#UTBd!&QGVK_O+vKpGIG|`A0Ws?Ygx6S7eXN~kvX=9uSOKIoA*{j=(-s#LAl$^M z@*~fmv%Vl>!)r@%DM*LHWe=gWEv?Hwv*0Avi4l_LI;O?`j`zh^F&y@-@pRMF$Cwlq$-G{ui%7YX2BT`t zt5|h|sPYby@dmqNji zS2!xQ#{QO_Aork7!GLVti6I;3w~nQMKxFTB6i^fmp|K{cS@~+#0Vlx^B?s%S zn;ev$Gi~My1J1Dkuk14d&w3tV-WSU^#U@@lrg)5M021NE^YR$`CB{9w5IRpoi8dx# zV(?;mMngbIpj^gohmYp>3$?hj=qwgk`l4HsWrN;r+Jcg2iLIl8JCCD%r0wa=kp)93 z>N|6Y=~}k+wU5|FXRYBG=fr54>I8em=cufY&Urq&u6AE4y4w@qb*JjzJ#86Yzxw3w zHY!ku$RmW#`G{l34nmK8c^&7Tlm=xf0S|b96fQjy$iP)+LTqd(pUcmrVUuC)dMF?L zT?X%{Ff9N>dx7FLaWrfpeE1$@igIHvsH9*09?68wMwW_4K7L$k_TQ@$?E_^$92An>0??^tFM0>$(XakaHZLRUB@OEFeKJ(AR^2jBf|-h*7+f& zb$tj-s7|Rl^12?+bUq>{#K2wp2_O*``80-=w;37$b0vW^l#w~-*V`{}T6?-N(d;wB z;Xc~YB|!h~wLS?JxQ{DVGCW11Q$7*FN9JN%4AUK!aY@-WTm$*(>j3zC8rCE64QXC? z=^I8j-q9s-YzosRx_T8$XtH_b;ZEupNih#M5^~P~&s?w_wRYE2C|CTWChT0Q+v=1J zT9Mtk4fj#pp#@}1H5)!Z9~n4&cW?iU)G2uZ?HR4dd6QJ$YM84zT>x84;kxdY^o+lKBm5qf=Oa|D8o_5n?)stIM5p>vz z3Be-TdG!m1x1xvsG@qMTS4c#%3fJ(x-@6?cDp#rm@ZU>HAw>p8!AoJHUI)F|feG5J zdaj2~0$KkAEZ6BH2?ACZ#?A`DKDpoEoDg^u&s3Wka6B)WE7@vaaS;U(?uZ}rjGUgo z)@tQ@@%rH`X4N_@={ztn15(RG(u>J8zDsI6Y|dFZUY<=k7SVs!z2FhMd+XP{d}&b& z^Ze&gQ$tvrQ%MMSLe7pNx1m}?7UfCxd({iQWxW=ViJ{#glvP?s?pn&*GdK2a!|~ma zb6zGyny16-b2GssM;YJrX-oEy!G%lqY^);V$2jTd9*vR> zd&AD~l}M&tCH1UDq$viQD&iY|j?^v2=078HRIjxAEeKu$q*PrKyiFu5^0I}AJd!*& zACeUUh83{Cl9F2Y%;6f+^e>guCZxy=%>aBB;nRk@FRnf^4)x;te;%~AolHW%7YiC> z8uU^XiL-lCBbqxY)j14P?c+vii=1v!o!j^un;BMmu|{qO>O6=->RE>mMwxM!M&eJqc8jO z$k-sX{FAci7uv|dK%!JNV{ki--5Uxn2nz8))FV8+)Ji}9g22l!!n)?(Kz%7<1A*Ia}BjAU}A}rc!U54c-AFBdxja^F6vl=p&%p zN1)alC%=~_NpM;GHbcX~6#`nm7gvx%(!I%GGoT9WRM`}bS72?pMs?y_f( z!UbRviP3wKcahkF$W6Xs)12QoYV))rD4nVY22@Jb10He;V_SPTD3BFFf-^pJ#PgZp zMprBB?@T0;?Cl}u$KJZ@O7CCFcsw` zs?T!?@G}>dVtof#_Hs@g+{SW7SXZrOE^{ER7x_=LFUEJqk;hh!3Q_&-&&Cyw60}bg zxq@BFB%-ML;amf0#UUg@b|`ysdpZ+2Vvw)M!tESvxK_UaP3={AI`1NP4g2VOznoue zI6{BH1A;d5q5GMIyHvA@Y?8iu2P+;<&A-8p5)t$}7JW01l1J`YT4)*tfwX(6M`je@ ziv#84tPW+#B;C{4gYhh+G8!4@S$T+8G|d(6i;qp07I8aNNr&OHX6;#jL`x(4w=0#$ z6Sz8)CzxU(#(5v_`IT#yZqj~c@GVp|<0hv2db;Lss)|k3n}@51_Ik86OF-g10d<-Q z6LN9rII>&A8{ZJJ$*H7X@I-0{mjGu@WH&hm4zj`{JjgJ}9{}1jIH0pg^yD(Ysc}Rn zKhWssm^BRl=}oQ(3Q4wkJ3_Hca`Oz|!G{g21Vx_|=WSbeM*Ew-NokkuNA19w5RzKm zFMisF`MX@QO~ll{FK%74k8SxuPoh`9l(JuOG}S%S#mB{Zm+Kv?s16`1Q!8@@%?8bP z?yCT;K}`;5345yOFPw;#e4^wXz+bAd%FxpPJ@F9Cv*r8jIc?*6VgON(LGleZX8BQC z=5uoS+FUUHD}wn>bk|8IAgH2tojC6MTLVCv6fXrJRtya*qDlxq=U%+s7+*%16Wo4m z_>MmOOvO1apM*B9ne_a`BgSuy3U38qn())Vm~mtp51e^-1i^nnkWHvyCZ4kEac1y` zSa1=g=PY8^pxxNkaa7c@mw5CUlB{ZAt-+6l#5cWk8YvBq*j}s^EW94UDpKcsa`T?B znJ8m%5g*MlcDVA^UCL4S+v(7wI<%3)ynZ&=?0z77C0I2|U`hx=Gw^AXOL2jFgTAcjPiQLmll z%JHU5Y>kT12yw%xhi!|&L3PM;)bV9R;MG)yc1rwzm9j4A`Qn zFmo>Ib8#j-(YWKjOZq?xHPV-i{bpg+Fd=3eI~qjLi8r$gHjZM1c>*lb3`S?;zEfMr zkE3X%hdtIIFAwy1RF^y@bUgjfG`QkAV+DR6tS6ece#;@w3mtIS{Sm;>h!qJ<@+D*X zu^s||n*8cloDWRDv}(z)3L29Lzzug5<|EXPbYcxi^u+7%nH{t`Zkw6W|%Fp8FV0SI&s_=_lJU1LTvDC7P0)nm$2L{aA!!=Q)e|Lp$$ofCWf=g zdr(nv_gg_@h3RDyo5GA#@fS)zuZmLH7n;buzF*{z7iIGlIn&xTyra?_*w=#1_&J?z znI$(TWRI04d>yt?9YN(ob5I1|EPWH?KmwdH+FV0U6tKqitz=I+3!Z1iY@cf9s2-hf zvS)?`UfR#!&ENyb+>0*@jpa^=>i5fg?}TR`zZ#ny6Mc%ZTn_e(VZ_++L{%?*ISY}U@k_ayk$0E1X1KsPXM#Yyb*V6OA|-`J5?!5JP5Yo^b!KFQ3TFl$`Y zal-5aIv@c4UM^=Xm_3S2K|k<~$Qj{2^vv z7=~ALZA$BEk+jUQH;!M&&cx=SahulZrv0a2UxPMBwHwX1#ZV7J9`3w9?YE(et0<$I z8cIwaszu}+G7GKMx~@|B!{f;CdY)0SnC=^+!0O}lQNRmqyK-@ve=k{0X{rz2N;Ak^ z5?RHtRgywQCCPwtNpV;atY(jUt>kXaGh+M?M_7zkj#UV<<%i8r`dP&yXzzkx;o)8i z8#Y*Cj7-RPn~pxV^4y9g=l?wkvJuc6bN_9KK9X5gQjj+$P0Qh!K#Q%gniLlxQmk*B z!Rhwkd`~KQ4d5X+QR|B4IYJcBNB4ftlmh9!XZG-c?e#&CR=>84dq>%RtN2 zBAiQg)zj9ZG$#*sbPdRoN98oscPQ#Ij*kS|vuzW4@kEX*m4p})`X-<}yi&_`R;Aw9Dq$%>#pfLa6h%0B& zxm_yC5hPPRxkbgh)fB2<&7%A0<tbWu1P;=gWsFxn>~-j ztld`7M?Ds2M9xW=HzOW-S-bkF+${dx35l%Ra_UVOS#GRx!RNDVzRr_Ra{({JF?6-j z|2PR`Oqr~#tW3G&Kr7vVeHW2C&m`s2%W}7vjO8|{C&(ja-B{nK6{zxt&m&k1U6cQ& zSC$}xpq*^kL&{7^S}*0;lLr)!Od6cSr=)4T{rbQr!Q%T>HlO1piu;$x4WCar10t4o zjN?P&N*hR+)v>Dd_KL>%qACt%hlrPQR>nsqF7>KV%}=p!9l^Z-k#>N=7q3y6{lea zy&5CuGK<028p6<+uUFVn3Fc+8yER*km9RquBTVI$Sm*zqKu>lnO&grVY9#{d3X@dT|?m8|~NsFNQ@~1J;PMV8K|Aac;DM=mwKq)bY*?&Vc zE{$_Qjc%_*_)jDFUXM9O#MRPa`|S0fm*CRwl3pGCl0R^EHUEq1H^yTy+@37Au~d{E zf<6*;1L?%V9E~F8PgeWV z#vdf$wPH!ud&p|@6h=)>PbhC`wT6lJq5QZ3W3b%e3Qd!Gv1+LPMf0lbi% z)YfBQ4x5iUos_@RLwVI8&Em_o>x8~IvAH7MbXhnOwd&*VXUY1+W^*gaU&378p?FziL$YA}$8B(dsH545Th#EB8SY>8d-^`dRaBG3WNQn$E&8UB9+28e)<|(dPjO^jz~7(YdSZ5 z3Mh`B9~BoX^0NalK!k?>!%*dKR9b4rmA^pB7EvV#-4O;n1%7&%>xI(K<{c^LV-_Vu zRnH@w=EH@R^q0cbq+WJ(Wig|2#}r=yc`sfkAcPNH84~&L61lu$f}pw2q;7fmoQ&N+ zb{jCrr!UegSCXs0w!;$%NDwp(vL{Nak4R{xA03av`Hfsj-tp@eKRi2%6#HPnUg_9z zcb3SH5*C7r&!)$riu=2rEB#U5Wvd zWW|xJRrpTn->@*-`d44q8h6*;*y&BG@?EdzdM?;80piDd6(7XkOsP`xb$mb6ydG?8 zGKgRm!a26&%jBH4SG1?+vD#E)W)Z6s;;3_gnZ~l)vnBx1{QdSU@V6tuS+#16J?XGn zqkM1Jik)565P_UaaVR$rXWNuj- zIcLVPjq@NWUD{`@QW!Z@Cg!J}-Q9N(eFM&yJD*v6W?mSHME)KFfx3+1E=|hE|A3XN zY(M_OZf+)KG zJ@IA{oiY!_%1N)$uCU5xZtD!m9@%cZ5%MH_cFjaM1uue~!5R^)st8U^2~~-6v{;)l zRYsa4$(kp72u(YU6-rZ2KqNQZu-lv`1>GV5<4q3j$qEh)bOC%wmtuW*=^q%E;UHt| zP*_eb+J0oiFAVGyo`n($lUb$qI3Pca?35#Ja8~<$it0!B8->c>!j|h#7rVx7*XzhX z5b3adojD+5*W~d1i1r zR|^H^vU<@7u24)^`6np_WNCj}>Lgb@tsE5Sl#ATC28dmbnBg-Txhh2<61PwieL2!p zGXVF3N(sd%5=q{AK?wsGRQYr$=PPXVW{&TNlfZgDU+e3ch^lHb96g-(x|G$e?>E>I zIYSa(6<@8cKD8CvHGfJ8#$jQLvBXeG9*QxJ{{OU}cCdq<$jh%6@YWVtw%TLTp!(ze zgO4TJLvL+r(4U9XDi$&qI)ut%p~_o2Fbo@uwM20SGM7^dyHV7Hs1Jz-OD7JHZpuJQ zbJt>#T|wD9>j;u@_Wc8T?w~nb;4iX$F$Oci;BIT~45}Ape+Xe~E_J}P@a3N)@9Ij& z;TlL{6WwP24A4BjuOIv8Vl2keiR(6b1vg@kI!w+&zO^`h@q~#r61hZgnG1oe*BeXm zYMZK=f$n@)seCbeAZ1Mmb@ENEB-m($|Ed;V`B_lzOPqpg^^csVvNF=IhSH~?_TT3a zWfhiVHbq)zG+I@;IsNCN;lBx_KOQZ*(qs>O7EX~l6A)G&8pm7-TwpYMZoChWp+g_u zUYyOn?6HL+AGO@sx;ih3c&GvH=s!G&rbnYxuTYwZb)*I5x9Kkg8RnDQV=}u8YAp`u7Zf z*1r#oDj}IKAX)g(2gtzBA2_3K96@Go&H8j_r0BLYS)-D1Qm4Zw2CY}djT%HMT2| zg&%2`EBcb7JB1Yz(7BP`o1te@Nqo@jW3MtVrSf@sQ!~kXvC|BvQf(5+;r!_HZwHZ^ z!Erz<3Tx3FvVHPRyhnA-8)+ibp@40a`jPo}FvhediRk_NK&HQC|K=*LbY zSRZ!IpncWDj3WnS>DQHdz+s-p_@d5pI*Te(+7909uQBZJ0{_OIDGIA9FaH^#NC|$T z7YE|x?ipwhqW@AhZD@Ovjk2K_MRKowP= zqtX>QF6t9Aloo4#>Y3M@Hdv0Tj2MsG@Pyp@P|>)>CfdPIxKd(XC5SOV<;$>K8BA~MK?D(W>KH93@>3JxATrgfJf4^{{H@H%A~ccS?bt1HHx*r z%cDCDV>dEWXBJ&cW?d&RYk?V=gdIWk5i>rNEI}?AoxeChe}4rN378 zPHxxB`*?2!82WrA{CGE|#INcweo$k)*e>=?M>ms%gS<{lN4(ZAV~OuIUZrG5%n zVW1w|jGlWt5JHyn8!lF#;zqj90;IdCNfgCq9{ltP30Pv!uSc2wJuZ6ZsC3K^GG@|q z5UhliLhQRj)`h4|Bp*Y&EqLi`b)$D5KcX>&8@6 zRfuZ^d-2mMZs(4JW2W$!-gjXvJU=sb5p^8+L!cnQTKX8XB5l#$7I%Z9VJfMRXc&$$UpBFF~}HXK=lW zrKZn9EWLr1(!;pRs-S0ib#_n040tP#B&E+K$gN{@|IX5eb0q0OwF=(5e*Uh48#ST#-h zR>+Ob`#Nmq?(B}ZABO%+l{_9Y5=>#4ev75d-US>!1kOnn%>|rFTEm3Vn@!q=!5;ID zy!si)Sl6?V7Q*oQSAgouz+#H*|2@ghljR0nRkq`6FiO|KejMIcjbS;$i8y>@kA&FRI{YBXvJr=<$k*xgj=H(UdQk8GF2j}T5qalLFQ!U3<|27 zdwOTOa5SH=D!Jo3w#Y;)w-Um+5LJvfY(GGu;uX{B)4Zaf52^u2c z|ABioHFe5CqNLj~cT7Q0&L8QxQoi^>KT5&w8sJpcYJyc?9VH}d_z%(`abMD{wPP4(0ol-|jPnoF~$)OtaN{OYKFGsH_^k-xvP4`qD|C&RhryHSCsp z-jq4}P>tP64cV~6-s+iLVV)m)h;vph_U6R8JE$j^;W$Lsv)(xGIVm)zI=xqRGPpeE z4i8kl7YmDZn8D}G_=R504XZ^jX#Vd>W{^q<-Ch_YWdbA2J>H2D+FT$1(=H=LN3+gt z!Bm*oG$+IUCVpL*ul9TNj{n;DB7NcV=@AhwyxZpup3nPl`3F&y12tC$qJ%2O?UGp~ zsZ7U(eGRm2!Xu#X@mfRG(Bp>qUr=Mos>Hi$ykfdkf>&CvDzY;NH(t!fKvuZSf1~C1 z0*@_o7-?Q~vUUW0nDW-hnu^Fjh=0d`LG^{wcLn4_{}1x3O!n1B3%8$COP;&tZLeMl z-L5>wspzp-J~AUQ^F7x{|6@B3RXbv#bV1Rk)f=@A_SJ>pAnM)9Y@{ z1dP&YY%VS9c_Y*HPO+>kT^mkPtv6OL?ZxbJr-v~nDA42xY3Me`?^(= zUORi49p3E(oN}j>$vKpt1;98b>^Apxb~QrkyQE9qY~yfiv>I3%aauloSEBC#g6qlS zeM8GBx;|f44V3+Yk_Z|uyjBo&YX;)9B=5i_?scz>2P6kLx0-_Ylum@I#xLGr*sU1K zE&Xp!<#1VdO}qi2-1+U?81{Zr1NyCR8dmO?y79}54pGX3C{~aAcL6R-}oQoSdZHI)}+M?^PZ6vZ_Hl)1tnwW97mk6MC-e_ihPO!_Urg_JszDxrWEO zeYB2!gfR~b@iyd}6nH*IHPSk@9(Am{rO=h_^lbk zu67;8FK%@1)Pz6+M{OC)Q2w+L?I92MZ99G^K%He*tQb}$z`4lPQak23exfJ!J6YG} zshI3{X8N|p-1Fs!*6+1ijr`027p?XUaOqK~WTw?>CE)_zL0%A>^((%3w$&eCw>4vR z*NkZPQt?%fi=;gCce8d-es^H1^DCJmK}W?R_KN>THtM)w1%olwTG51n9Y_%D6POHx zB%BCX$Zt*MhkT*j-h+>MRBt1If;gIPiGg5!b}KA3)5@xSHC#NXdujNA@+EU^DVLP$ zgoRAqOT)RMGsQOxT=v0qkWvh76K;W*`-+^3#EMZ?P0z$OMts=xsZvTdg*M8stEP5A zyp~L?JlfBmA7Nk<22|DiCy!EcB_igk)4s1|F`@P<|KRuPM%Tym&wZ`JvFFng<05?o z5Pok5difj|FP17E>;j%HBEfUER0AYPNA#R2=u<;dm{osz(yHx<>(ExrxLUN2Gy1?uLh3%bMX@$`E^W6{fC#9A&W}g%7&SrA$y~&T~WwIUZYy6RiC!% zvry$PY9_l>Yb$2#mcf}48e|v-Qux0o++XP#HWl5LC}o~t8d5gW;OYOvo!`rT*I4CN zs0i1|X}LDmO-ngQy;jx$Grq=vtXHKgM7u1!(SQ9lpZbxvDWB5`nNLtOt18}L!%zhz zsnh!^Pu-J+*)4VCw@oL?-#vZH#o-@ZQh$6}-WV9HGUJD>ulZf{Nw+TKK^len9sAT` z&0LlwbxlceF4ZS@*4{!}t0Bu%ISx=PstcW$QX{Ti$gKer*8ZNKto@Xqv%muan#}XC zGT93tFjsIDr*A|%bAc)RB5fVJ9-2zLaY~}$xa;)^An9C>k4v9vVnFo=5c;p`3x+n* z|AZNVE?)QRRe!jqRQdI6$7B>EeAfmoU?ES(=A&&Mb@%aZbV}GKSH*CK4U(m}xAJpB-yXa)>PUfTV!-`H55DaMn1_($&iby#X^YLX*)4QV{u zUyR|F*IMT{1G|;Cx=+ha$>j}p`2U{F=FXqWx?`#SCYU*zoO*)-9T-nqIumy`&ogcU zN1+V6ARWXhg%s3{Y^UY=l9rMK46S%Z*rQr(-@_WTwJ*H7xwv=<&>!_lVpSS(aa-{` zGgk_huV-}@btV<;;Z-TBATN^y?bpl7^d$wUyqJKuqk`+YKhqf^*CV1cZ}14sZAt&M zQqXO!#ajVwe z)^3GR`c;N(iEsx2m4ebYy(sr7DxwiK%>2TwEaIzr$+r66dPQTjkK9~LM@N!f9!|#P z4=V8{EcF-X%PYrvSUzvVOP6C}U~MI@q-weJ=bjB9K@jT5&z3+G4F`0hzIjnza1lo^ z+h6y-)~avhmMyJB#yv%W6$O_$S3j?gM@(W>&V=s)_O_mfK3AKdAQ!!3uD)Bn<7Mc% zWc00Nf+9-G4iWfJ-?Z)SpuPGx-Kw*9EM@h3;%Xy)m^1W&7j!&)Ov|L@>6OvY!x|v( z_)^@t?#!yJxQ5#D32(+?tihb$6B242CZ5mW!R!{{ci-@Ap6l0jFQw48J~FXSc4IXS4{lB&>F)CGcS7~Yclxl-m>wVbOo>!yMoQhWopv&bT6*QbIkimEnP{7p7b`M$D*&%b_{xhusK z92y!p;h3vDhUJX&juy$%UJjQsKVk$Bu)>Td8cjU;`PLLLzn#BP-YQyA-rx*7MyCmy z@awduI9X5U-1iMiU?ihV6+syS=;5_qY&H3-E9?K>^@M6d4_&QC9icEwYfBcHIf zuNiL8Kgm9aZ@pIa$@nf)i_=+w!4WYmk*?Nxx_n#!SPBs_G1$nts^>P5mqn&d!@Erf zh?47xhOH`|7uMbAOa1)hY^OkKtTkj@OrzE8m{hS!id!QdpP#d*Ix9zA91-u`Sk^P4 zvtdo^`K!`=BFy#(0_M2;5dLEE#dLNyhSPnQaQE&g*y{#UJp32c^Iw39@5Luxrg>XJ zjZ^kswTnF$`KQ{gw}BAH$T=46Msm{sJ!xJo0lQ<7r(TLurogp-mq)1@O02zo)2f16 zz`xfm8pPS*P<`A|1)YZl6TWolws379w}7~%)u_$w-B9gyk?x)Mhz5!iM*MuYPiaaV zaW|JJW`g5TcqIs#?|z;Xb$*RW5eY%R|*^GO||60bE_3{hoqmY+5#<1KJd&EXG1eV3A9$}iE*SsV+qz9L|+eb11c zO@g_)koFjNLm4aNdaJL)nAlcmS>Jx(_`4 zEvh^mU1AtZkuX=x7V*|x1}!SZ`{s7QtqxV``09>;)iqt9VFl1_irW9$MSk6clYIy( zdXC`B(2tbikv>PhyWFIYX{E}>1$q^)daD$+l81IvYt?O$U?<+n8qCoOQBn71tz9F* z&xgmbhcrufkeN)lGgPGRqC@i^4`EI)d10r4ts&WK0AdIJx7_*L^h?TRfE54WGY7Xs zg`ZeapB%+VNk4UGn(BccHC}mXMSShYFL?z`EUJ6CbRQ1b|T%=HZA8YV`X;~~~;TVQ__ebfU zr6vDw_|v>`?gE2O`00Pcg(+4wz%k>AW#c2i5*M-x{>r0@>0@)DK<{oJe4%KC=w?;r ze#K|IZ_V?FlCxR)r08GlwZ(_9^wP%#y3Vb&;LCbFWwi~|)M{`wKK8sdW7V;a&(#&k z$@QojB3xHh^#p4l>udxbrp3?j34r5+5U zd`9jkRwiTw+36#xUU0C%+$oUI+O;ZBbmWu(IfNYfB`XjYG(tJlk=$kPuu#-xN$55; z1auKUrEIqKf?3JjK+xa{pTuO3jXL`^CRq%V!XQJm>vZ=2uRLyTkjDIJ?mT9gFak`p zLgi0OxA^ErZ7PlrgEDN5D%9LMZCaGyw|!ltB%=ftlk9)|iZfULYy)m+X@nX^zK_~> z2p1W#So*zfy3v}?qa&>P?urT4`qHIL=qWR8{lNYFwPL5{(9T&3&H@V+x*TCX^dKBV zcAxPZ#kBP7@8TkamHdwTg@|u0cYu9*wEtz8g#0(`#Iiu5s1@_|Xb$?b5m~lY2_Am`n0DAk=}zadw5{T_J9fqu~FI zklg>CJPCLmjj4A?R?Fj+H&|bw%3o|__A2u96xwZfBCnLS1I1%W%HMoHW@DdmGl~hK zURWy%T3X-*I-;Lg7(vVG2Gb;R!^8aD!*Ji^(tDw{v|#nq1#6}1jC?0IxW=88VfKC z;(?Js-L)r95{8_bZPsP1`;4FBkF9Jxm8J2VCQJhg-TK=`2=g9SUz9!5RsUego>Z|+ z0>qLd`Ao`#$##Q2DzQ8Di)oUs*n2!*mU)3m1q8?UZmZ*fUKairGK3Sd9mA>ogCsOC zK%cV`IO|1{joGpoU$;b?bK)|_tVcIHqJJ#FbLUazjjv<1;(b~9M88qa*eyjncs)-| zY*p78p*{hpWAgK~xPBcIdjTu?pUR_Wgo@`4L8jdm*dZihs(X zD8LmEQq5UoS-78sJFiBw3R_w#$Ykpw+Rrk$vwMn7rC(-bwU%RI-m^e6+ zC6=lI4(}%#H(w4iR~`{*`HE7uSjW8p&c>H2PQ4w*Pu22Ics>0xET^=de6?wx^^^OP z@TC_x>X%>D!I)99)_wH>{7R+*6Px4c)YfV;#@ zsixXqY1PJJEn&VzuMr>Ugg8^=&wJyoK+gLtR(JY4;`%}Ct(Br=F?F)w-ntyzQIQ3t z_WT*QXMmcH>6Fkt;j2%q{S$I0a^~`H2D@!=6Qg6tzjn?H{YWY*GkE^*rXr4)_iHP} zG5#21L=B99#GXF`2u?)HnSoyQ!Pg42l~))86M`(6TxhVQ!Xt!f2-o6ny#RzU_KW`y zQ(qm|^!NQw3j+j%(KT|6?h=8~9UCE?D&3)UjBc3H(%k}5qBM+3_EA@IXMR94k`mmIfC>Sz56igh^&o6# zJwE-$8}2f6$N{r~VGX)S zNDv`5%bj1WXcJB#;A;CfjPM(86akhPfC=%RN6;oCglwZnwrL@9$~OU~FezUo*+rs& zaP{I3+O^PZ*Uqjaoyq@Io{x^?}%WHdrj9e3#`?-k3~R;YVQK1al;KKMSudeP@%w|b>29rDmsCcb!vh&+-h zx8XQobm7N@&^;N}-$m0Gp(ZX9w*qrNa5gLm2u&Z?%v9UX^~!^3gP&;bXfT*@ajA|_ zFT}<4Z9c{#R4tADEx`g_2k|A*Ib2NN_fBCQ+CF%GSacBUPMhTkJ8qNUB-ggpwmVzk z?RjbX7i&++_+=XLkZ^UqjVNhX9@Cz$W<23TcyXr7_Xp|k%#_H2u+%0tA=ycys?{jts?}eN~29;bZ;t%Z9 zbIbW(_3V5?I*ZjmAYx`b+S`V-Ky#6NE&~u*pQp(Z@YD~{q=W-DQlqzT&LBHft}f#@ z17A4Po|_uV8$LJXzFmS)D57L&q;5HKecj{L3{J7lMuvCG(ak1Lwr!o03wycbLO9%Y zOX%2Ll-dWEmquEa$4w$UpPgm*t7Fx3yA2K>wkj+<$ zhpPr{Bsa(iu=3Aq1Mo;MH=0B;+D^k;!xgLRc+#>)8S^a1+CG=mA-$XcTMxOscdV`w z*oc2pFNbq@uO77*Sj6=HliWX7@}HYzW(AEtcQcKkW+T=%NkqO;6MCg6p}tyRhgD$5 z8b)DH^_>1AWTuC#C#_TQh5A|rn*H#`@uR>JsAgF7*)q>bq_snG8Zt^w)ESHA+{bDD)SRbUy^auU$Okwt69h@+}M(vv6F zMeHZ)kN2M4laXkoCSR0dNs69~rP#_NR(DV=Z+b?npf-J7RSF53R?dhg;hx+pI+DuL z2ZIf_nLIe}25r`yL&mW}**%6I<`=T_@ZtiQk2se)8{NjaB;p{iKD9>q=MZ_Pkae8SJF79R8xkozy*=(|$qy^cP&~rcfZ&u|#ow>!=yIGpUX<=|6ww z{?(oIodzK9EWa`vO#;6%cbo1|@->3=u>|TCB9Q}A&Exlnl=Sk*UV85xU{Arq@P{+%Hcy&O#^yst_ zo+jPB!z%O0vKAc9UutAA6i=~cu*f5h6vhd~-D30N3(q_u*ABHAVY`S^r6C_}r6VFr zvf_rzH6}iT&-PM51Pm1VA3mHnC{Si*c(NS-UN~rA`y?cxp5-x?>c`On2FB7Dp}dNs zJ~jt8!p@=x7P&(tni5V}0OA!6SX->{19FxTAS)qOV^~%_Kl>+jRGC?#NdiC6vxwnD zxz6}Wp!*QHt%(M9e7f<$yc-76Kgo6Xf03m;yD_i>{9qr6UXijV!w<4v<6T_xs@w8z z1{uUtQ!S6`#*We^Wbku~mp^O78Qf@v;0HhIB@^P!C@VwocE+%z2eXfCBu`v z>RbPb%DZ|}_2c>?%w%XYk0H};nW8aK>)R^D^#whGHcHdgowsj`;04LKJrr)yOI=K^ zldAc7lQ6GS`;q|uTI?5fvv_sA*?*={oPc$HI0zLd9#}L_ABBMbV=UyjQ@mcac6|R4 zaOh|M`4KAQm8pO}clH6M_^J=hpUr<#TS1#$)NVcjq=Q=Z9%C|MkINt;JnZ)7HZ6)~ zUpHLyxSc;wcC%`?87f)P)|rk@hdu%lr?!>sKuQ=_uYH9(rK5S+vs%fNUnD1gO*G41 zEGD;RiMM%iaXYox);x47-gJpg8F`Uzvm8(OxtA?UEXt%`KfIJOlElm-(>Hf9gB@Q+ z1eeX*MIB3;Fw>4c!(Y`y`|^9PiC{9}oEgw%z?C~s4_r}H2G_~|1Y9V?0hr>b(+=d5 zf~e#r05y|36~^@vD4E#?M3bwzco&%9XCr$PD)Glb!h6(gL+d>h&L=v|+#4rG4LaJP z5bCv1oRt;|;n%V|_kC@~Ie36$$T+iY)V*XJv={RNzcT!9GBxhhY(vY`RV9A*J)*KP zRB9bnuqGJvBB(g1khH~N>jjg7yUEe;#I-~P}A%|`W};n z6Dug*y;BUdDDvyp(y>@;oY`S{!ys@J5%8O*U*l?Klw2u0vFlXL+4&L9ooqZxj10a{ zINU=MDO|-V+?Yhp=Kirwa9@Fi&ebGdD@d7*i6 z)}vre!MYbMIVv2^9pkJKj9e7s$lEcX#^b_In!T!ap%t0%q^Y5a-*63e1q~$d{W;kS z6vW?*`cKbb1EW>3y52xoyjC5*yzHJ^s7@H;ITUg|l_vhRyJ1xs5c1#lb(~67Gd0`1 zS(4N5+--i2T|#U6V^y))9S9WvY`GyP?4rlfGv}%Yd{xKCR>&&=yg_9#|S7L-t z^9ff>`mtNEuG#GI`Ju3gyu?kqSa3tSl(@W`_0I^(a=B8UWph?f;gM3Di@l!AR*65U6qb%ZaeKtc!82V-@ajV^Q@W)Zwo4vgqgik*i|DE) z^9<@vbnGO~!j(ok$;X26@OhVpU2=O%cKgFqJ{PQQDyra=_>8vw)8doPFM`C5H4Kwp z%mP-AdO1(Ptez=OOgz4mNtTm3Y`(fdIhGPkTnaf4QaDDZlS5<)U7s2Zw&OW~H@1RJ zA}Jo^=x1S)b!y1#2A650Nvw4j&Wb_RZ69=O%*+nUaF&jKoadi63&~CKXO3!Iy_`8P zP$*swBm5)(+OjnP$kcp*0(wvo{7I!RexSr>9U5-Z|w z(B@zVw!u;V(g?x?R~tbp`Y3%u{POZLoY{Y6=_H<%yeWMA@?rKD+s1?i^Z1!woTauy z6{--}VR|xQ7|GpEcb4i5A!@Vjla_j$lT%=&r1P_MXFy-JQCA8BOI3DyVK>^ehG;_N zXsu0a;0=5_b$BHEQ)TGO<@nj=g?l6liaibR)n=m&#{V6AV8iG9EvUGJe8Iv8oS*NuOKFD9ef zFjwmqBG_!M(!>SN0lBIJGVaCP@hsVzYzUs#j7K|rMizfs?U7&^s7WA!u zxQ26wDCOD`)x`rF!T+W>zkiB!xoS`Dr{%v`qm19*e?tooo(J8SL{~|SWaddxjB8intG`!aAT(`BmZ%bQ>%RaKxA98Y2iP zZQ)|e({?AoQc-J&nr+ZtmBY>&M4rV8RnU)X1n=^96jLvSD|RVBS6YW5%l!Vcv)C^0 z!_)m(ax?}`#Gn6^|0Zd*d}MOLWsNt!UJy)KA-b7b{&_?ip~&jU1qpTVyc;k44A<*n7DAJdADDH5mcKt)w*FUojQ@?# zXnQBsZcTAGc(n(MnRf_~9MClhzKR&ls*&<_;6~t`d>9kp@RvTgFzN55Vz;Iz`PTyf zl|DiZ?TS2uV$cEcrt`&e53R}UWvQChIwX)yRz$8swY9bFQY?1+>80QIyI8ReYUv8e zs+(HKfM>qUPyGTK?dQ5KY2U8QF~5S7vkPq(_^!JwCr*PaDv83x9UJ^6pY!^BX2|t+ zzIm+_VqDMP`y3;!+|x)r_apP$mGzLcyASsVDS7eH)s3j^-|`R>mXCJLA3h50N4I)2 zVkW=j&TZ$6br}tGQk(F8Xbv8!dEOz+*j>}P+hsoCZBdbKLy1oRi?!n&v*5_6^y5iW zjx_O3`Eg8b*1E%Iy^NcT)zqEDQMqzFa$c9P3;s}GM9KjzruDz(>oI=$Dq$9POoL#q z6ygLF7Io3B%%Nb1iUlugWfXN|vGWycvIs>)9{{ZVS6JsqC2|OX!Bx-Rl1Bj*)f#f5 z#@nSw8J$H)2vNU__-fg9>9_KFd+GI^9LpUI5FmU35J}|hzWs}3GQ)Dbn|gUBd-opx z7whtE*v~eAq6P@^)oEUI^>~m+Nk;q^t2LPBZo!M?T5FEbD~B0-;+Xb};JxV`eXO|ef6INJAbiMWTk*q|AXHAQIL;3N=X>~3=>Jg zCllZwdcTeKt==Z&rCPYv`K;Px73nL6+2Z&1d0gfm0PBL;CAWXF34$9Z8&=H@f`E3= zpydHfcRfG1DiOo4lrC3Dm3UyiAh>)p$@WnP&+*H8;C}zv6plrgw`tbCi@+zqe<}lW zWp?%ia9DuSIQsSU$H!YjzQtOthA+EecTY>c-dZb%4V1`#pZL~o%Jg94mhUeX((6uTB$j4RRrYT9 z?AP7mS=e8!r7QlwSPN&OM?bI1l@}+?VC{T!TQe;cCgNr!UkK2ZgX_Cx!h@ra(;Zlk z^C#vW9Ru!S76>1YT*n_^1NvW8%hV43^*wp(YnqH;4ndq=kv!Z4a3o;(fT93M%1+Dk zd#=<|#!L~VMx>K!*%O@k7!Vk6%vS$2z5u>tGxA>}0^%>(-dXxrKg_->I?cBhs$XoE zc_6<@E!K zottKd*3|@W@B60b*(`IZqDREWiAlkXg_=HeqszyC%Iv!;%!fowPH69%dFrL_|7`|< zc&n_*X2O*a}7Z3PrKU zZ8xN$@Y;#JksXK=xV#agwzaec2^0@@Gb7d*P!GDvy;)UdHK-%6iRO344$SB=elO7N z(!r7m%%Zky!Cxo2pvRgW4P--2?Qa;vNJr@y*yD2^;Sajsk0Vu^)s>9iqWmUI`cGYO!EG477O?ZlXMRSHo3|SvG=28|qSQU|wvguG(Y3iF z#_Of#R&S)5u9O0QsX^;WzRSIsSn!BYhtvt94{?MwYlg%5D~ZWKkyiI1e_m-!3hE*$ zi|#6?C-}4X;d4$@i+POGahTCv@wZ=>MuqYT##ta|eB71y7m#ZXkM{S#x*^@{rt7wZ z{QAc)GEQI=|1AG!@~xZ88?FE<`_I0vfcqXEBa|FyQPWx8alp(@US;dKtfI!AISTun z@OgUc`Mv25hf~kh!KW=L1G3`onSZfZ#zne)B-RsLzLI45G&UPHa%5=T6Rgu-Ny@9A zo3hN_5)oCj(@xQ37yP$x_2do3-zyAAewfM3-?3QffqC*M@5@dlbnvCO)9|T=mR%-q}l@87* z<()~ty0mOeUwxoa%8`2sy0m`7k@xF`&-NTGEroI=*7{fh&b!2+ol*~+zTiJXwB`oP zENP8Qy1bz#tFQMqb$H70K=}Brpsy!|vxtBj(Q6jJhO3)gz{Lu>w!+N1FCRLQxqKSC z)ys+{lN1&{yT4e+od1q1AbN+WO#TjHNl;*6yq3JWPx zvWXbj;wyMj!6Vp3^}!s5>0(OF%70g}2(fXovE{K*AjuV``4t*jBGR|M(>%$#%DFL` z#j)a=xu#DZn+(xpeb4BwGS%cKnJ>aKht&pyTEMXRLW-HAX7KXj0K#gg3tpM(xh=bo zm&pC@qlgiSR#lepd;z99#fI5vbJ9{pgn5Nn(=Qsmk-OmfUU~k85 zF>1l$ya$1S<3qWEFH*#=HRDufl-%EfI?i8{6nv>z&JB&1EoP}Cf;LI9Rb zRYLE{P)sD-ACOr_nDHf6a#QZ<-Q|g;Ae3SJR6H);gT~@ayj_lx^BW|jDtbc$EYTA> z+};I=MMH57F0#_tbWm0*l5$z88HXXY5VIYHQOhyyZQtKkav)vW!Xb z5lqw+QT-iIi^!pw#H8F^7)mjrxa_nBF}sVj zEWXmir`VW}R%YBMqWqIJ61;)kPz8GX#}+|fh;xNf$4)SkkSQ&K1F~Yqp-+Z`<~*q-t_zx!}SV2&fLvH#}yniM@jmN4(moz zYEWCiqHq4>L~+~4gXoG5OtIdWfZkBd09#v4Z z8khy{$}&h^&%&RFIkbjz6PT))Mah&_N{YM^U_Dh!obO7WtTCX8B9Q+%5N}I{r!~ z%oSSdK_&Z90%1|Xl&gK=A%ujTUeNo!WHjzU+FYLc~Bkez0I&AQ2?hCON2(M)XWkRx4xk1R& zp;jZM4%{?SU$upYKn$kyI(nk#+B`GMxi?G^TkLEPNnv)JN(!2Jr^o+fezG=L* z7fO{ax2}+kroo^jbvWA^@*$Y`IV3pVJ-3pN6I*}G%xri4DUKO}|YDrLN@pHkmF< zZ&MTalkcJ6!i>=gS9#vB-}{#70>HEU^%slxFP7=@^DiC?4X^*fF5*g3 zhD~AhZVB;QzaPEJpK zcZ#TGI2=*#HGM|@m6!ln)vuUnz3gEhw_>J|q5xn;R+Cp6ZGQpMz-Ymo^>EX2wX{(Q zmBRX--UD-FH8?___)Sb}bgF^O#H}Pq`gB{T=+!p5wZMshDz;VK2cYNkdut3t;o%b+ z@Pa4L!<87%UrXs;#ooZH4HlTV`GjV)-@|NZ#8*6Br}qRQ(sr zWx(mI16(2vLHgLyH>QoZBho#`3$kDES84}ksc#^QFv)uEv8vimL9Hl5dfa;sh?E3t zG`;D)-jUw~Y7TA;^3Kdp?kEW*VLNM>^c&t(jOT5i1Wc4$a^&f#1r>=P#oc}k=>kE^ zdo>l~KBottN3&c@pF*K6?9WtYI~A+Ug_H=dVC}0xzSiNVHlGCF64f>Krwy&HYVHzkV=yPLW-O8FF&S+_A+ue(lSDs)q z)R9HyUo34kKYDYz8_2%yd+jIwJ~J-CA9*e^gNSEH+&o+C5Y#X+fxn=beDSpyV2{izC6tEWG>2%`-A|##d>r% zzF}U70T=>QH_5qjjQ#pIb;jxN$=@I6v>_ZDoMvoYt z)`-}~!b&H3dioUlBHwWa5RNNjClAxXtY zwcq?CwcrCYCxx*wGvuu;MW#KHkq%y&PDsxt-ExDTq;+&zQuYYa7w6 zQy=mR41vebW*{U`=r|(di}efn7pv_1{#yqDL_V%-snJK`Z}uL0j9wsr#Ua3meuH;qUD+KA%RDcpCe_ypEaP6YrATmpgdB(2pzbdgA*mcz%CGc& z;Z@DBtbM|`j`b>w)7Y$rK<&_MAh@dG@1FV^5&1^^wslX1rSj>?OzTD zmR!d*3*rUb0*Gf1e>u?USzOOe6?spxZd{8Zy8a_wI1+{6_A&SYQGy6F@5pf(1db%+(L` zSUgbJ`N+0+xmpXpPBG0#kgVfzWf#9n8NV+6y|=ECE6?nXvwOH2iE8_ukF#4vS4?>( z-qj1WNhR_Y8lzpy5k3=YJns$O#52NPBTt{>fenkjGQt;p`n?1;9ui~|1_^k}-qT9{ zLhGp(5ImINc|?U_bC*W=isUt%Mi&0q(EchyjV`NqH_NKmZ^IK1oi!jYFU@EZrjKee z`&`tWg$JGT$mX!5d9Gye2!qvWXt7JIPBty2=i7Ndd_NjtWmc%zJ9X(l>cE%(Wdj!) z@5EDz5xHp~hlGk0dEa5f{UN=YMAL0io>z30}khVDOjNb@Xy>thWM)Ce1*Pu znsiLR7MK)Y5w^QiRkthm<1v;y=Wpv;OKT>l`lpqFtG&y;y1xmmSkyzjyB&6wilwo; zOr)9KbhzRNe2lDVi(au{t$F<6+~BL@v{0u3u?FB)L7Cd*Sh7IPP}wzg7=?6z!ef;s z5WG{L!WU9^gReC~*5BfTzN&OBoo3=u)Wk7xU7>ziw5|-^@z}tXKA-x5#IGOMe~1!W zcsCDzZn7b3jK{g5Rd+hY>@t_)@)XA&=yTnh3^ESa3-;UJo@n#+K+k=rAZ2PHu+<0 ztg`NH09YgPa2b#EbR;-{#j(DQ*~q8WuX7LOiv^8amC(E=(#_A_B4OBR73Sb4o9-w2 zw4%9QgtCQ0+{F&xdFoQbFfq5=;n2X{Bqq!Y&P7X({hCu(Ia)({=vDA{U-pjQeSa*d zkUSRdAa69ZVrHpd>P7OU3CJLpkf$h-asS23m)HDMx36LbhhrRQV&&#gTz{a30zD9o z2*&*NFD5xVyW%G}ebl0zS>N&f+*-QN#Gx>W*G&No(ufwH{C?Z;WDm#shTrTODQ6`k zlJ?P^Og(}WwU{8tW+A2DAB&_SoyE2t{SHKj$A)(u)!9d#@wckRb=xF$I9tUI78DRC z=V|JUIPWer3|N~u8)`-t4~fLFY4Sfaj8{I)k6A`!f3r2LJaD9dG8LS*uP9V26d70R zv@@m}`M6XYNEQ`liCRIf>tD#@4>ID-`DiiQ&pF4jVnA%RKnd+ePW}6_K3I#*5zd_-h z7Ws1O`rKI&SQKN^s!8eVFNfaTj_yyX1>f$5b1FOxizPM?qdeBE_;Cm9{G zbok?S$9G>~wBnGk?d_T$u?MQ%n7B=M|5lyJ_ho0F3ikc>Qyzd#r2d0V@bK}lfFB&( z{|lQ4<5RLK8n6k8*ix}8c!A;i5$U2zhRqzsVs;z<0Vg>BfRjBmEF?E|-o{rv)2GGD zFTlxtlwi*NW!)3;Z2#K|!}_G^>K~+0E;w#N3&O7+40h)fYk0ey<(NLbgGGbmJ}lVR z<*BwFG?{Ym&u{IBA4b+3V>~2~7e*2c6$m$BY&)U427!WpD^m1*D#cd<`fmIX6Z>jp z*CME7&7(y;FSbOSeTW1g#Zaf*CrWks1d$G}>3Gt?r;9xylik$uM`*XEdI9hUM1Pcb z*$j+pJ>FXBJJZqL?`yB`RShDi#5S%Vu0>F?a|dXZF9y7$>ufwYrqmdcg2 z5*`{yS9X)8IM)ui;O-$WET6I%4%mK*bs(uAzwb>C=X`)f6KkS~HD})`f)Y%(l$lew ztBkww_?5u}RytCK`75RelrF+HCuIG`+wzXOWfrhQv4Y7bqgQ$LRg7ByWLJFIo6#wb@S?w|F;m_4oDhg{=5^2n=p#zLm-DidaVoE(ol@rAj1d!h%M z;HBb{egndeU$bue?W1B|xgwsDn!h~Edgl8ixS~MmETn7Oz25ON! zY_5YTmy9+)RNP5*B`vy&3}n;yF>cY1UcxL{MFzC73Y>=-6VA*&vUxkgGSF33-`kN6~TBdn2LkB=;J4(PwTZZ8EyY zVD(jSSBg>*6!RiKR_W~{>ObR`=&;}Pl#8+pmdV=W6LI&+jjZStr(R}BDQR>fp(0U` z&QvX1uypj|b5+XKS!$7HaWMoemE=Bs4cEHoK#LTKXzY;D#?;fAbPM^o&W7!GgwUh6 z2GDj25T$NLK4dQ4^c980zTxa3iL`Cu_ZhtHVWbUz*_cxZ;TEeCtciCz$aO50 z3FClg|LMMVm*j4Vzny;9!y4jQqb6M}?-$oAlda@nEE$Is7ZY`ys*Is)7L_y7AA+>_X4mZ{>vUZ{f)DkVBOKq8^OT0C4 zl1;EFr{pU{`!X9DXg|I^R!`ze(#*GGz;6K^$RAR^LbIsy94d88&`MLu?JE0v%&Kga zaAEX?Y>m$ropjgi_>(KVJ=2K=SH)%V6RCj z-uS+0FhUsj5H3kfC}wX#`AB10_4ux(dM&? z7u}r4T~KDICa^B&f8X*KEAUM6TiTxu=9ZMN&LeXhK#qe1NKMgFY>U%<8(!)uN1UeA z9sPR(oC$sed+ysl%%{0mNj+;e!q#z>A^pU?x?j2C2wf9=G(l|=^Ofb}U{ozCwBn$^ zsPU4^aG+D3IQkiSvRKbiD<`44yp}lDojwWgBu>PsqMJ!?YsEVGnb5k?Lq9en?s2y? z!Y9f#H^Pnn6|~j^yt+S#Bix7!eiiQzKdiXP{F%f8RQCBA=|z<}SoE+k*7Ta?R9UaG zY0a7a4;&vYS_OZy-AnQA)qVfSeYJKA#Qm#q>8clC%tl~s- zh!z1a-DjSWwZ{qKB<-WeX7!I=vG?<)pCSWk7k==Pp~@9|!y`lM_zlSh4{~o68IDpp zyHVQY^8{+HC)tey?Vqv^oI??cMFRI^?+_Vpx0tCXcCgh+PRD$nw#p$o3>ziy z)T2fcR3X>+K!jMgC>ZKUUD_)gP3nWrP>eHXg6i{w6#=b!b1sE<-Kl_v>}eVlbv z?U$0u*hk@-OvMtPF5g8H`~@3IK)`mC?fIOY7Xyn3PoFs+#}L3NbIC)A2PELSQ(ibtR; zZq4)RV`<{d@(vS|R7|F>SsudNfqS|f;rX6q=Y}z&VMOskb>uKsMM!vwCbx+1=St&& z?m38j%ybp!OYIGkd-DjM_B`88`+R33H`Z{Yf)aFQOs-;-eCyY=Jz1`6k?!qJ%bZx^ zEUj|LpDRoVCQKT(T;yC>>&T1BmZ~+ud2*3j@d?kG$^J@%Hd99M3wWDIf32-BErJ4q zV_`=__F;Y}p^;)5)NX6k|E|)K^7fVZx2;+7pn^A=Wg`>s^qOcj;}A@=2Z$PD{sT&- zx2D0CW`by)&2pjja=E^wd1FTU6miQn@v!Q+RFIz$_lSzzm1P(6*6)l27I7I^2-qNI zT~Nzo*|iAR^y-p)@9^~^%Q4kh+pB;6FV?<(hcZs5>v6M%Myq9UUgKt9wW%%?Caa?L zgoG!*zHqc!afPImb=jP4OV`o9$-~Y2`~Z=BkUg>>1SasVirG%Aa#`4VdtDKZhi6&d zk}WM(b`*9f-o-$NQgeR=Ibe=h^cEs15uXG3wP+^ppEQ~2u1)2KVu!wofN5)PJ=@o-emU1Q{!B`% zbYdfq$EI#Re1$Hejfo;ZsWH<+h;D58Td0@w)?POSCdQ)yoh zKx5}8!=*E2bV6Es9?XT{y!!h7md(~;Ev(`Z28U`#H|C@7Oc{3C9?_`VqH0i<8loj| zenDZ}w=(;8%GhKYBh@~k+4pt~*~m?;$1+rwH7FTv*1G!DGLzRZpl=qnn6c#Sm{1va zZ}tb6m}Vf)dj1pmMi9(PJn-Co@fWAPFiUK?8|L9ij#rlWoCxTH-4v^n|2OWXQoR5! zlTyT{H({Ej;)iX+(r0fFXkCG))8I#ffq^3dxe@$#wg>c~|a@F!SD zhHkF;rFLc6Sf}zHQN2%r-|_9zS0yY-vn~2c_fZEKNkvLdw?z?N2bmOQ-nnX6op|$d zrH*8{KTkgi>M0R%5I_%AW*<7>Xta~}=(Oj{!LEQ}^r^v)5P|3OuoQ9%dAGuMnjV)U>Ym7_2 zKf&+6VRyn3TUy&yZS~GXE5Xg|EUC4QKzKPu=?`(Dv)HGNXGG)C??wOIhrSlHNlHc>=8Ki#Mw0BZ+1Qam(b@wv{YE{=z44kE-3 z)GJaI*Q{GFrc~s*A|2$qK=T%?MHoDH`0h zu^ce#6x3Z8LbF)B_nDn_?SbY7vY=}Ipk~g^*vTJLNm@fzvLP93$LQf0JMfldlAS-Z znQ91y@!6lhBC2=sSFXR$Q%_1v7w67EHX(6xUUQN##l}xeHZ1)zu**&VBC;AO=$cM= zf9z;x*L~Y*dX#B8!nSF`kq$3lG>9^@i{NST>5?;Hd@NpoLVW``fwg9^xqO1g^hIEW zJYuBUc6l!sr6GA_GHn)TNSd%Mc7UkvthjGLFp8{tG~FN@4Qu*i2=bGV-=c)hI)1=~ z8hK{%21k034v0;#PS0Sgs!VwJy1Z$dtL-^RsSIw2=0S}IYqUIbK@N}JHgH#? zuUHBu|3fAi3ZYojLlfJxdxtZGp+l|7xfa~Lnop}pPY?nv?uli)`mlK;PTC%Eog<#hJB)pb%(q%ozf|-e^`!za1(oJ>D8s*Z<*gsYtZ|nHamie1CUfcg zzt(Eke``YQ$L+8yvR&D}A5@j9d2L>O+{Qz!e%y+xJbb2_H{uXrY}m$|g*(;fRD}}c zd}hO}?;l~4nApYIe`Q$OvbLJWjLfvj9d7GNaD(sA#}49aSjy8CUY&S zLEJ}{mul=uQ+Z!C{j$>FP+E>x`YzD?^|F+J+8I@}Ivyp|IQVm)mmBb2U^dT#Nt zmE}C@Zm|vGEcddUQ#~%}ybHCWRtx_L#fQ`!U2=8S^W+xj9C002lX|Ul(|ux%F^o}h zQY9A&d6QKnIB%c^wH90xzjEDD^P?Fn)z30D6KG7w<1tnSSKg5HqKD>r&~0z*#b2*D ziNI$K(tDpQnp?}4pLfG$w{6PK^>MsYD}O)r{O<204OolCQRm;ZV!DeJpGNQ4fb$(GDBUbh`Fuc{xXAFnvb zy3@n9BtA<%qrW;t{Sw%zl(tkb;B>NkAmN>WvT&y^D(^)`I*KJLs>85VD%qK)n_D=l zuN5eL&E&JIJ!~5EwQZm4)i%!QP6Dx?!(<2fcOg2K?L>7EoYJ!p#t)+;l~rUff~$59 z^VvioROV1guJ@SfC4N5!d(VOr&Q438r#qYk2uT7O&Xa8lVh4x%Oe-~C=Pu)tAUunQ zJiTMU)_V0hk=m^M1@GGER7 zseP)TsnN~>hgs&z$`*F0$~y)K0u%19Uq`yMb*VEwnS`n!s8Nxr{j$uHFjo9=#e1K$ zKe0*~59cRDL7xhb{wK&Ili2S?yTwjw6tbt?Sq3L)(p;hsn|c&S|C#%4N1iYCG*$Iz z7LjEdOGyiVa@y~9{k>@Od;ph(INYcf%z05+uPK

9ZZHkL;rpnJ>ZWkMH%m>epKY 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 M2lt=eYI~pm*((j?pa1{> literal 0 HcmV?d00001 diff --git a/enigma-old.ipynb b/enigma-old.ipynb new file mode 100644 index 0000000..a9e832d --- /dev/null +++ b/enigma-old.ipynb @@ -0,0 +1,2639 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Enigma machine\n", + "Specification from [Codes and Ciphers](http://www.codesandciphers.org.uk/enigma/rotorspec.htm) page.\n", + "\n", + "Example Enigma machines from [Louise Dale](http://enigma.louisedade.co.uk/enigma.html) (full simulation) and [EnigmaCo](http://enigmaco.de/enigma/enigma.html) (good animation of the wheels, but no ring settings).\n", + "\n", + "There's also the nice Enigma simulator for Android by [Franklin Heath](https://franklinheath.co.uk/2012/02/04/our-first-app-published-enigma-simulator/), available on the [Google Play store](https://play.google.com/store/apps/details?id=uk.co.franklinheath.enigmasim&hl=en_GB)." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import string\n", + "import collections\n", + "\n", + "cat = ''.join\n", + "\n", + "def clean(text): return cat(l.lower() for l in text if l in string.ascii_letters)\n", + "\n", + "def pos(letter): \n", + " if letter in string.ascii_lowercase:\n", + " return ord(letter) - ord('a')\n", + " elif letter in string.ascii_uppercase:\n", + " return ord(letter) - ord('A')\n", + " else:\n", + " return ''\n", + " \n", + "def unpos(number): return chr(number % 26 + ord('a'))" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "wheel_i_spec = 'ekmflgdqvzntowyhxuspaibrcj'\n", + "wheel_ii_spec = 'ajdksiruxblhwtmcqgznpyfvoe'\n", + "wheel_iii_spec = 'bdfhjlcprtxvznyeiwgakmusqo'\n", + "wheel_iv_spec = 'esovpzjayquirhxlnftgkdcmwb'\n", + "wheel_v_spec = 'vzbrgityupsdnhlxawmjqofeck'\n", + "wheel_vi_spec = 'jpgvoumfyqbenhzrdkasxlictw'\n", + "wheel_vii_spec = 'nzjhgrcxmyswboufaivlpekqdt'\n", + "wheel_viii_spec = 'fkqhtlxocbjspdzramewniuygv'\n", + "beta_wheel_spec = 'leyjvcnixwpbqmdrtakzgfuhos'\n", + "gamma_wheel_spec = 'fsokanuerhmbtiycwlqpzxvgjd'\n", + "\n", + "wheel_i_pegs = ['q']\n", + "wheel_ii_pegs = ['e']\n", + "wheel_iii_pegs = ['v']\n", + "wheel_iv_pegs = ['j']\n", + "wheel_v_pegs = ['z']\n", + "wheel_vi_pegs = ['z', 'm']\n", + "wheel_vii_pegs = ['z', 'm']\n", + "wheel_viii_pegs = ['z', 'm']\n", + "\n", + "reflector_b_spec = 'ay br cu dh eq fs gl ip jx kn mo tz vw'\n", + "reflector_c_spec = 'af bv cp dj ei go hy kr lz mx nw tq su'" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "class LetterTransformer(object):\n", + " def __init__(self, specification, raw_transform=False):\n", + " if raw_transform:\n", + " transform = specification\n", + " else:\n", + " transform = self.parse_specification(specification)\n", + " self.validate_transform(transform)\n", + " self.make_transform_map(transform)\n", + " \n", + " def parse_specification(self, specification):\n", + " return list(zip(string.ascii_lowercase, clean(specification)))\n", + " # return specification\n", + " \n", + " def validate_transform(self, transform):\n", + " \"\"\"A set of pairs, of from-to\"\"\"\n", + " if len(transform) != 26:\n", + " raise ValueError(\"Transform specification has {} pairs, requires 26\".\n", + " format(len(transform)))\n", + " for p in transform:\n", + " if len(p) != 2:\n", + " raise ValueError(\"Not all mappings in transform \"\n", + " \"have two elements\")\n", + " if len(set([p[0] for p in transform])) != 26:\n", + " raise ValueError(\"Transform specification must list 26 origin letters\") \n", + " if len(set([p[1] for p in transform])) != 26:\n", + " raise ValueError(\"Transform specification must list 26 destination letters\") \n", + "\n", + " def make_empty_transform(self):\n", + " self.forward_map = [0] * 26\n", + " self.backward_map = [0] * 26\n", + " \n", + " def make_transform_map(self, transform):\n", + " self.make_empty_transform()\n", + " for p in transform:\n", + " self.forward_map[pos(p[0])] = pos(p[1])\n", + " self.backward_map[pos(p[1])] = pos(p[0])\n", + " return self.forward_map, self.backward_map\n", + " \n", + " def forward(self, letter):\n", + " if letter in string.ascii_lowercase:\n", + " return unpos(self.forward_map[pos(letter)])\n", + " else:\n", + " return ''\n", + " \n", + " def backward(self, letter):\n", + " if letter in string.ascii_lowercase:\n", + " return unpos(self.backward_map[pos(letter)])\n", + " else:\n", + " return ''" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[('z', 'a'),\n", + " ('a', 'b'),\n", + " ('b', 'c'),\n", + " ('c', 'd'),\n", + " ('d', 'e'),\n", + " ('e', 'f'),\n", + " ('f', 'g'),\n", + " ('g', 'h'),\n", + " ('h', 'i'),\n", + " ('i', 'j'),\n", + " ('j', 'k'),\n", + " ('k', 'l'),\n", + " ('l', 'm'),\n", + " ('m', 'n'),\n", + " ('n', 'o'),\n", + " ('o', 'p'),\n", + " ('p', 'q'),\n", + " ('q', 'r'),\n", + " ('r', 's'),\n", + " ('s', 't'),\n", + " ('t', 'u'),\n", + " ('u', 'v'),\n", + " ('v', 'w'),\n", + " ('w', 'x'),\n", + " ('x', 'y'),\n", + " ('y', 'z')]" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tmap = [('z', 'a')] + [(l, string.ascii_lowercase[i+1]) for i, l in enumerate(string.ascii_lowercase[:-1])]\n", + "tmap" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'zyxwcabdefghijklmnopqrstuv'" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cat(collections.OrderedDict.fromkeys('zyxwc' + string.ascii_lowercase))" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": true, + "scrolled": true + }, + "outputs": [], + "source": [ + "tmap2 = list(zip(string.ascii_lowercase, cat(collections.OrderedDict.fromkeys('zyxwc' + string.ascii_lowercase))))" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "([1,\n", + " 2,\n", + " 3,\n", + " 4,\n", + " 5,\n", + " 6,\n", + " 7,\n", + " 8,\n", + " 9,\n", + " 10,\n", + " 11,\n", + " 12,\n", + " 13,\n", + " 14,\n", + " 15,\n", + " 16,\n", + " 17,\n", + " 18,\n", + " 19,\n", + " 20,\n", + " 21,\n", + " 22,\n", + " 23,\n", + " 24,\n", + " 25,\n", + " 0],\n", + " [25,\n", + " 0,\n", + " 1,\n", + " 2,\n", + " 3,\n", + " 4,\n", + " 5,\n", + " 6,\n", + " 7,\n", + " 8,\n", + " 9,\n", + " 10,\n", + " 11,\n", + " 12,\n", + " 13,\n", + " 14,\n", + " 15,\n", + " 16,\n", + " 17,\n", + " 18,\n", + " 19,\n", + " 20,\n", + " 21,\n", + " 22,\n", + " 23,\n", + " 24])" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "lt = LetterTransformer(tmap, raw_transform = True)\n", + "assert(lt.forward_map == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0])\n", + "assert(lt.backward_map == [25, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24])\n", + "lt.forward_map, lt.backward_map" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "([25,\n", + " 24,\n", + " 23,\n", + " 22,\n", + " 2,\n", + " 0,\n", + " 1,\n", + " 3,\n", + " 4,\n", + " 5,\n", + " 6,\n", + " 7,\n", + " 8,\n", + " 9,\n", + " 10,\n", + " 11,\n", + " 12,\n", + " 13,\n", + " 14,\n", + " 15,\n", + " 16,\n", + " 17,\n", + " 18,\n", + " 19,\n", + " 20,\n", + " 21],\n", + " [5,\n", + " 6,\n", + " 4,\n", + " 7,\n", + " 8,\n", + " 9,\n", + " 10,\n", + " 11,\n", + " 12,\n", + " 13,\n", + " 14,\n", + " 15,\n", + " 16,\n", + " 17,\n", + " 18,\n", + " 19,\n", + " 20,\n", + " 21,\n", + " 22,\n", + " 23,\n", + " 24,\n", + " 25,\n", + " 3,\n", + " 2,\n", + " 1,\n", + " 0])" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "lt = LetterTransformer(cat(collections.OrderedDict.fromkeys('zyxwc' + string.ascii_lowercase)))\n", + "assert(lt.forward_map == [25, 24, 23, 22, 2, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21])\n", + "assert(lt.backward_map == [5, 6, 4, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 3, 2, 1, 0])\n", + "assert(cat(lt.forward(l) for l in string.ascii_lowercase) == 'zyxwcabdefghijklmnopqrstuv')\n", + "assert(cat(lt.backward(l) for l in string.ascii_lowercase) == 'fgehijklmnopqrstuvwxyzdcba')\n", + "lt.forward_map, lt.backward_map" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'zyxwcabdefghijklmnopqrstuv'" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cat(lt.forward(l) for l in string.ascii_lowercase)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'fgehijklmnopqrstuvwxyzdcba'" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cat(lt.backward(l) for l in string.ascii_lowercase)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "class Plugboard(LetterTransformer):\n", + " def parse_specification(self, specification):\n", + " return [tuple(clean(p)) for p in specification.split()]\n", + " \n", + " def validate_transform(self, transform):\n", + " \"\"\"A set of pairs, of from-to\"\"\"\n", + " for p in transform:\n", + " if len(p) != 2:\n", + " raise ValueError(\"Not all mappings in transform\"\n", + " \"have two elements\")\n", + " \n", + " def make_empty_transform(self):\n", + " self.forward_map = list(range(26))\n", + " self.backward_map = list(range(26))\n", + " \n", + " def make_transform_map(self, transform):\n", + " expanded_transform = transform + [tuple(reversed(p)) for p in transform]\n", + " return super(Plugboard, self).make_transform_map(expanded_transform)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "pb = Plugboard([('a', 'z'), ('b', 'y')], raw_transform=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'zycdefghijklmnopqrstuvwxba'" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cat(pb.forward(l) for l in string.ascii_lowercase)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'zycdefghijklmnopqrstuvwxba'" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cat(pb.backward(l) for l in string.ascii_lowercase)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "pb = Plugboard('az by')" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('zycdefghijklmnopqrstuvwxba', 'zycdefghijklmnopqrstuvwxba')" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cat(pb.forward(l) for l in string.ascii_lowercase), cat(pb.backward(l) for l in string.ascii_lowercase)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('ugcdypblnzkhmisfrqoxavwtej', 'ugcdypblnzkhmisfrqoxavwtej')" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pb = Plugboard('ua pf rq so ni ey bg hl tx zj'.upper())\n", + "assert(pb.forward_map == pb.backward_map)\n", + "assert(pb.forward_map == [20, 6, 2, 3, 24, 15, 1, 11, 13, 25, 10, 7, 12, 8, 18, 5, 17, 16, 14, 23, 0, 21, 22, 19, 4, 9])\n", + "assert(cat(pb.forward(l) for l in string.ascii_lowercase) == 'ugcdypblnzkhmisfrqoxavwtej')\n", + "assert(cat(pb.backward(l) for l in string.ascii_lowercase) == 'ugcdypblnzkhmisfrqoxavwtej')\n", + "cat(pb.forward(l) for l in string.ascii_lowercase), cat(pb.backward(l) for l in string.ascii_lowercase)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "class Reflector(Plugboard):\n", + " def validate_transform(self, transform):\n", + " if len(transform) != 13:\n", + " raise ValueError(\"Reflector specification has {} pairs, requires 13\".\n", + " format(len(transform)))\n", + " if len(set([p[0] for p in transform] + \n", + " [p[1] for p in transform])) != 26:\n", + " raise ValueError(\"Reflector specification does not contain 26 letters\")\n", + " try:\n", + " super(Reflector, self).validate_transform(transform)\n", + " except ValueError as v:\n", + " raise ValueError(\"Not all mappings in reflector have two elements\")" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[('a', 'y'),\n", + " ('b', 'r'),\n", + " ('c', 'u'),\n", + " ('d', 'h'),\n", + " ('e', 'q'),\n", + " ('f', 's'),\n", + " ('g', 'l'),\n", + " ('i', 'p'),\n", + " ('j', 'x'),\n", + " ('k', 'n'),\n", + " ('m', 'o'),\n", + " ('t', 'z'),\n", + " ('v', 'w')]" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# reflector_b_text = '(AY) (BR) (CU) (DH) (EQ) (FS) (GL) (IP) (JX) (KN) (MO) (TZ) (VW)'\n", + "reflector_b_l = [tuple(clean(p)) for p in reflector_b_spec.split()]\n", + "reflector_b_l" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "reflector_b = Reflector(reflector_b_spec)\n", + "assert(reflector_b.forward_map == reflector_b.backward_map)\n", + "assert(reflector_b.forward_map == [24, 17, 20, 7, 16, 18, 11, 3, 15, 23, 13, 6, 14, 10, 12, 8, 4, 1, 5, 25, 2, 22, 21, 9, 0, 19])\n", + "assert(cat(reflector_b.forward(l) for l in string.ascii_lowercase) == 'yruhqsldpxngokmiebfzcwvjat')\n", + "assert(cat(reflector_b.backward(l) for l in string.ascii_lowercase) == 'yruhqsldpxngokmiebfzcwvjat')" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'yruhqsldpxngokmiebfzcwvjat'" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cat(reflector_b.forward(l) for l in string.ascii_lowercase)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "reflector_c = Reflector(reflector_c_spec)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'fvpjiaoyedrzxwgctkuqsbnmhl'" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cat(reflector_c.forward(l) for l in string.ascii_lowercase)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "class SimpleWheel(LetterTransformer):\n", + " def __init__(self, transform, position='a', raw_transform=False):\n", + " super(SimpleWheel, self).__init__(transform, raw_transform)\n", + " self.set_position(position)\n", + " \n", + " def __getattribute__(self,name):\n", + " if name=='position_l':\n", + " return unpos(self.position)\n", + " else:\n", + " return object.__getattribute__(self, name)\n", + " \n", + " def set_position(self, position):\n", + " self.position = ord(position) - ord('a')\n", + " \n", + " def forward(self, letter):\n", + " if letter in string.ascii_lowercase:\n", + " return unpos((self.forward_map[(pos(letter) + self.position) % 26] - self.position))\n", + " else:\n", + " return ''\n", + " \n", + " def backward(self, letter):\n", + " if letter in string.ascii_lowercase:\n", + " return unpos((self.backward_map[(pos(letter) + self.position) % 26] - self.position))\n", + " else:\n", + " return ''\n", + " \n", + " def advance(self):\n", + " self.position = (self.position + 1) % 26\n", + " return self.position" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[('a', 'e'),\n", + " ('b', 'k'),\n", + " ('c', 'm'),\n", + " ('d', 'f'),\n", + " ('e', 'l'),\n", + " ('f', 'g'),\n", + " ('g', 'd'),\n", + " ('h', 'q'),\n", + " ('i', 'v'),\n", + " ('j', 'z'),\n", + " ('k', 'n'),\n", + " ('l', 't'),\n", + " ('m', 'o'),\n", + " ('n', 'w'),\n", + " ('o', 'y'),\n", + " ('p', 'h'),\n", + " ('q', 'x'),\n", + " ('r', 'u'),\n", + " ('s', 's'),\n", + " ('t', 'p'),\n", + " ('u', 'a'),\n", + " ('v', 'i'),\n", + " ('w', 'b'),\n", + " ('x', 'r'),\n", + " ('y', 'c'),\n", + " ('z', 'j')]" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rotor_1_transform = list(zip(string.ascii_lowercase, 'EKMFLGDQVZNTOWYHXUSPAIBRCJ'.lower()))\n", + "rotor_1_transform" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "rotor_1_transform = list(zip(string.ascii_lowercase, 'EKMFLGDQVZNTOWYHXUSPAIBRCJ'.lower()))\n", + "wheel_1 = SimpleWheel(rotor_1_transform, raw_transform=True)\n", + "assert(cat(wheel_1.forward(l) for l in string.ascii_lowercase) == 'ekmflgdqvzntowyhxuspaibrcj')\n", + "assert(cat(wheel_1.backward(l) for l in string.ascii_lowercase) == 'uwygadfpvzbeckmthxslrinqoj')" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('ekmflgdqvzntowyhxuspaibrcj', 'uwygadfpvzbeckmthxslrinqoj')" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cat(wheel_1.forward(l) for l in string.ascii_lowercase), cat(wheel_1.backward(l) for l in string.ascii_lowercase)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'a'" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "wheel_1.position_l" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "wheel_2 = SimpleWheel(wheel_ii_spec)\n", + "assert(cat(wheel_2.forward(l) for l in string.ascii_lowercase) == 'ajdksiruxblhwtmcqgznpyfvoe')\n", + "assert(cat(wheel_2.backward(l) for l in string.ascii_lowercase) == 'ajpczwrlfbdkotyuqgenhxmivs')" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('ajdksiruxblhwtmcqgznpyfvoe', 'ajpczwrlfbdkotyuqgenhxmivs')" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cat(wheel_2.forward(l) for l in string.ascii_lowercase), cat(wheel_2.backward(l) for l in string.ascii_lowercase)" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('bdfhjlcprtxvznyeiwgakmusqo', 'tagbpcsdqeufvnzhyixjwlrkom')" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "wheel_3 = SimpleWheel(wheel_iii_spec)\n", + "wheel_3.set_position('a')\n", + "wheel_3.advance()\n", + "assert(cat(wheel_3.forward(l) for l in string.ascii_lowercase) == 'cegikboqswuymxdhvfzjltrpna')\n", + "assert(cat(wheel_3.backward(l) for l in string.ascii_lowercase) == 'zfaobrcpdteumygxhwivkqjnls')\n", + "assert(wheel_3.position == 1)\n", + "assert(wheel_3.position_l == 'b')\n", + "\n", + "for _ in range(24): wheel_3.advance()\n", + "assert(wheel_3.position == 25)\n", + "assert(wheel_3.position_l == 'z')\n", + "assert(cat(wheel_3.forward(l) for l in string.ascii_lowercase) == 'pcegikmdqsuywaozfjxhblnvtr')\n", + "assert(cat(wheel_3.backward(l) for l in string.ascii_lowercase) == 'nubhcqdterfvgwoaizjykxmslp')\n", + "\n", + "wheel_3.advance()\n", + "assert(wheel_3.position == 0)\n", + "assert(wheel_3.position_l == 'a')\n", + "assert(cat(wheel_3.forward(l) for l in string.ascii_lowercase) == 'bdfhjlcprtxvznyeiwgakmusqo')\n", + "assert(cat(wheel_3.backward(l) for l in string.ascii_lowercase) == 'tagbpcsdqeufvnzhyixjwlrkom')\n", + "\n", + "cat(wheel_3.forward(l) for l in string.ascii_lowercase), cat(wheel_3.backward(l) for l in string.ascii_lowercase)" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "class Wheel(SimpleWheel):\n", + " def __init__(self, transform, ring_peg_letters, ring_setting=1, position='a', raw_transform=False):\n", + " self.ring_peg_letters = ring_peg_letters\n", + " self.ring_setting = ring_setting\n", + " super(Wheel, self).__init__(transform, position=position, raw_transform=raw_transform)\n", + " self.set_position(position)\n", + " \n", + " def __getattribute__(self,name):\n", + " if name=='position_l':\n", + " return unpos(self.position + self.ring_setting - 1)\n", + " else:\n", + " return object.__getattribute__(self, name)\n", + "\n", + " def set_position(self, position):\n", + " self.position = (pos(position) - self.ring_setting + 1) % 26\n", + " # self.position_l = position\n", + " self.peg_positions = [(pos(p) - pos(position)) % 26 for p in self.ring_peg_letters]\n", + " \n", + " def advance(self):\n", + " super(Wheel, self).advance()\n", + " self.peg_positions = [(p - 1) % 26 for p in self.peg_positions]\n", + " # self.position_l = unpos(self.position + self.ring_setting - 1)\n", + " return self.position" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "wheel_3 = Wheel(wheel_iii_spec, wheel_iii_pegs, position='b', ring_setting=1)" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(1, [20])" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "wheel_3.position, wheel_3.peg_positions" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(25, [24, 11])" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "wheel_6 = Wheel(wheel_vi_spec, wheel_vi_pegs, position='b', ring_setting=3)\n", + "wheel_6.position, wheel_6.peg_positions" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 [23, 10]\n", + "1 [22, 9]\n", + "2 [21, 8]\n", + "3 [20, 7]\n", + "4 [19, 6]\n", + "5 [18, 5]\n", + "6 [17, 4]\n", + "7 [16, 3]\n", + "8 [15, 2]\n", + "9 [14, 1]\n", + "10 [13, 0]\n", + "11 [12, 25]\n", + "12 [11, 24]\n", + "13 [10, 23]\n", + "14 [9, 22]\n", + "15 [8, 21]\n", + "16 [7, 20]\n", + "17 [6, 19]\n", + "18 [5, 18]\n", + "19 [4, 17]\n", + "20 [3, 16]\n", + "21 [2, 15]\n", + "22 [1, 14]\n", + "23 [0, 13]\n", + "24 [25, 12]\n", + "25 [24, 11]\n", + "0 [23, 10]\n" + ] + } + ], + "source": [ + "for _ in range(27):\n", + " wheel_6.advance()\n", + " print(wheel_6.position, wheel_6.peg_positions)" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "wheel_3 = Wheel(wheel_iii_spec, wheel_iii_pegs, position='b', ring_setting=1)\n", + "assert(wheel_3.position == 1)\n", + "assert(wheel_3.peg_positions == [20])\n", + "assert(wheel_3.position_l == 'b')\n", + "wheel_3.advance()\n", + "assert(wheel_3.position == 2)\n", + "assert(wheel_3.peg_positions == [19])\n", + "assert(wheel_3.position_l == 'c')" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "wheel_6 = Wheel(wheel_vi_spec, wheel_vi_pegs, position='b', ring_setting=3)\n", + "assert(cat(wheel_6.forward(l) for l in string.ascii_lowercase) == 'xkqhwpvngzrcfoiaselbtymjdu')\n", + "assert(cat(wheel_6.backward(l) for l in string.ascii_lowercase) == 'ptlyrmidoxbswhnfckquzgeavj')\n", + "assert(wheel_6.position == 25)\n", + "assert(11 in wheel_6.peg_positions)\n", + "assert(24 in wheel_6.peg_positions)\n", + "assert(wheel_6.position_l == 'b')\n", + "\n", + "wheel_6.advance()\n", + "assert(cat(wheel_6.forward(l) for l in string.ascii_lowercase) == 'jpgvoumfyqbenhzrdkasxlictw')\n", + "assert(cat(wheel_6.backward(l) for l in string.ascii_lowercase) == 'skxqlhcnwarvgmebjptyfdzuio')\n", + "assert(wheel_6.position == 0)\n", + "assert(10 in wheel_6.peg_positions)\n", + "assert(23 in wheel_6.peg_positions)\n", + "assert(wheel_6.position_l == 'c')\n", + "\n", + "for _ in range(22): wheel_6.advance()\n", + "assert(cat(wheel_6.forward(l) for l in string.ascii_lowercase) == 'mgxantkzsyqjcufirldvhoewbp')\n", + "assert(cat(wheel_6.backward(l) for l in string.ascii_lowercase) == 'dymswobuplgraevzkqifntxcjh')\n", + "assert(wheel_6.position == 22)\n", + "assert(1 in wheel_6.peg_positions)\n", + "assert(14 in wheel_6.peg_positions)\n", + "assert(wheel_6.position_l == 'y')\n", + "\n", + "wheel_6.advance()\n", + "assert(cat(wheel_6.forward(l) for l in string.ascii_lowercase) == 'fwzmsjyrxpibtehqkcugndvaol')\n", + "assert(cat(wheel_6.backward(l) for l in string.ascii_lowercase) == 'xlrvnatokfqzduyjphemswbigc')\n", + "assert(wheel_6.position == 23)\n", + "assert(0 in wheel_6.peg_positions)\n", + "assert(13 in wheel_6.peg_positions)\n", + "assert(wheel_6.position_l == 'z')\n", + "\n", + "wheel_6.advance()\n", + "assert(cat(wheel_6.forward(l) for l in string.ascii_lowercase) == 'vylrixqwohasdgpjbtfmcuznke')\n", + "assert(cat(wheel_6.backward(l) for l in string.ascii_lowercase) == 'kqumzsnjepyctxiogdlrvahfbw')\n", + "assert(wheel_6.position == 24)\n", + "assert(25 in wheel_6.peg_positions)\n", + "assert(12 in wheel_6.peg_positions)\n", + "assert(wheel_6.position_l == 'a')\n", + "\n", + "wheel_6.advance()\n", + "assert(cat(wheel_6.forward(l) for l in string.ascii_lowercase) == 'xkqhwpvngzrcfoiaselbtymjdu')\n", + "assert(cat(wheel_6.backward(l) for l in string.ascii_lowercase) == 'ptlyrmidoxbswhnfckquzgeavj')\n", + "assert(wheel_6.position == 25)\n", + "assert(24 in wheel_6.peg_positions)\n", + "assert(11 in wheel_6.peg_positions)\n", + "assert(wheel_6.position_l == 'b')\n", + "\n", + "wheel_6.advance()\n", + "assert(cat(wheel_6.forward(l) for l in string.ascii_lowercase) == 'jpgvoumfyqbenhzrdkasxlictw')\n", + "assert(cat(wheel_6.backward(l) for l in string.ascii_lowercase) == 'skxqlhcnwarvgmebjptyfdzuio')\n", + "assert(wheel_6.position == 0)\n", + "assert(23 in wheel_6.peg_positions)\n", + "assert(10 in wheel_6.peg_positions)\n", + "assert(wheel_6.position_l == 'c')" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(0, 'c', [23, 10])" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "wheel_6.position, wheel_6.position_l, wheel_6.peg_positions" + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "class Enigma(object):\n", + " def __init__(self, reflector_spec,\n", + " left_wheel_spec, left_wheel_pegs,\n", + " middle_wheel_spec, middle_wheel_pegs,\n", + " right_wheel_spec, right_wheel_pegs,\n", + " left_ring_setting, middle_ring_setting, right_ring_setting,\n", + " plugboard_setting):\n", + " self.reflector = Reflector(reflector_spec)\n", + " self.left_wheel = Wheel(left_wheel_spec, left_wheel_pegs, ring_setting=left_ring_setting)\n", + " self.middle_wheel = Wheel(middle_wheel_spec, middle_wheel_pegs, ring_setting=middle_ring_setting)\n", + " self.right_wheel = Wheel(right_wheel_spec, right_wheel_pegs, ring_setting=right_ring_setting)\n", + " self.plugboard = Plugboard(plugboard_setting)\n", + " \n", + " def __getattribute__(self,name):\n", + " if name=='wheel_positions':\n", + " return self.left_wheel.position, self.middle_wheel.position, self.right_wheel.position \n", + " elif name=='wheel_positions_l':\n", + " return self.left_wheel.position_l, self.middle_wheel.position_l, self.right_wheel.position_l \n", + " elif name=='peg_positions':\n", + " return self.left_wheel.peg_positions, self.middle_wheel.peg_positions, self.right_wheel.peg_positions\n", + " else:\n", + " return object.__getattribute__(self, name)\n", + "\n", + " \n", + " def set_wheels(self, left_wheel_position, middle_wheel_position, right_wheel_position):\n", + " self.left_wheel.set_position(left_wheel_position)\n", + " self.middle_wheel.set_position(middle_wheel_position)\n", + " self.right_wheel.set_position(right_wheel_position)\n", + " \n", + " def lookup(self, letter):\n", + " a = self.plugboard.forward(letter)\n", + " b = self.right_wheel.forward(a)\n", + " c = self.middle_wheel.forward(b)\n", + " d = self.left_wheel.forward(c)\n", + " e = self.reflector.forward(d)\n", + " f = self.left_wheel.backward(e)\n", + " g = self.middle_wheel.backward(f)\n", + " h = self.right_wheel.backward(g)\n", + " i = self.plugboard.backward(h)\n", + " return i\n", + " \n", + " def advance(self):\n", + " advance_middle = False\n", + " advance_left = False\n", + " if 0 in self.right_wheel.peg_positions:\n", + " advance_middle = True\n", + " if 0 in self.middle_wheel.peg_positions:\n", + " advance_left = True\n", + " advance_middle = True\n", + " self.right_wheel.advance()\n", + " if advance_middle: self.middle_wheel.advance()\n", + " if advance_left: self.left_wheel.advance()\n", + " \n", + " def encipher_letter(self, letter):\n", + " self.advance()\n", + " return self.lookup(letter)\n", + " \n", + " def encipher(self, message, debug=False):\n", + " enciphered = ''\n", + " for letter in clean(message):\n", + " enciphered += self.encipher_letter(letter)\n", + " if debug:\n", + " print('Wheels now', list(self.wheel_positions_l), 'enciphering {} -> {}'.format(letter, self.lookup(letter)))\n", + " return enciphered" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\"('a', 'b', 'c')\"" + ] + }, + "execution_count": 82, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sfsdf = ('a', 'b', 'c')\n", + "str(sfsdf)" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "enigma = Enigma(reflector_b_spec, \n", + " wheel_i_spec, wheel_i_pegs,\n", + " wheel_ii_spec, wheel_ii_pegs,\n", + " wheel_iii_spec, wheel_iii_pegs,\n", + " 1, 1, 1,\n", + " '')" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'u'" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "enigma.lookup('a')" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'a'" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "enigma.lookup('u')" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'uejobtpzwcnsrkdgvmlfaqiyxh'" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cat(enigma.lookup(l) for l in string.ascii_lowercase)" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 :: a a a ; [16] [4] [21] uejobtpzwcnsrkdgvmlfaqiyxh\n", + "1 :: a a b ; [16] [4] [20] baqmfexihswpdytlcvjozrkgnu\n", + "2 :: a a c ; [16] [4] [19] djralkwpobfeyqihncxzvugsmt\n", + "3 :: a a d ; [16] [4] [18] zlejcuitgdmbkonsvxphfqyrwa\n", + "4 :: a a e ; [16] [4] [17] gcblwtakqzhdosmxiunfryepvj\n", + "5 :: a a f ; [16] [4] [16] osnirgfmdpvuhcajwebxlkqtzy\n", + "6 :: a a g ; [16] [4] [15] wymvnqzjlhoicekuftxrpdasbg\n", + "7 :: a a h ; [16] [4] [14] cjafkdztpbeuormiwnvhlsqyxg\n", + "8 :: a a i ; [16] [4] [13] xijuyslvbczgnmqwotfrdhpaek\n", + "9 :: a a j ; [16] [4] [12] lfzrwbytjisaovmuxdkhpneqgc\n", + "10 :: a a k ; [16] [4] [11] tkezcqynuwbpvhslfxoaimjrgd\n", + "11 :: a a l ; [16] [4] [10] kiwfnduxbsaotelqpvjmgrchzy\n", + "12 :: a a m ; [16] [4] [9] sfkutbpoxycrnmhgwlaedzqijv\n", + "13 :: a a n ; [16] [4] [8] baqwlkhgrsfextpocijnvudmzy\n", + "14 :: a a o ; [16] [4] [7] teofbdzxqkjyrscvimnawpuhlg\n", + "15 :: a a p ; [16] [4] [6] mhypswrbzxqvaondkgeutlfjci\n", + "16 :: a a q ; [16] [4] [5] cpasnrhgkuixzevbyfdwjotlqm\n", + "17 :: a a r ; [16] [4] [4] dlfatcjwygvbnmzrxpueskhqio\n", + "18 :: a a s ; [16] [4] [3] lxymzjuqtfpadsrkhonigwvbce\n", + "19 :: a a t ; [16] [4] [2] puvioztjdhxmlyeawsrgbcqknf\n", + "20 :: a a u ; [16] [4] [1] baigpldqcowfyzjehvtsxrkumn\n", + "21 :: a a v ; [16] [4] [0] mnvfydiwgzsoablrxpkutchqej\n", + "22 :: a b w ; [16] [3] [25] ulfopcykswhbzvderqixanjtgm\n", + "23 :: a b x ; [16] [3] [24] qmwftdyovursbzhxaklejicpgn\n", + "24 :: a b y ; [16] [3] [23] oljmzxrvucybdqasngpwihtfke\n", + "25 :: a b z ; [16] [3] [22] fwevcalzxutgysrqponkjdbimh\n" + ] + } + ], + "source": [ + "enigma.set_wheels('a', 'a', 'a')\n", + "for i in range(26):\n", + " print(i, '::', \n", + " enigma.left_wheel.position_l, enigma.middle_wheel.position_l, enigma.right_wheel.position_l, ';',\n", + " enigma.left_wheel.peg_positions, enigma.middle_wheel.peg_positions, enigma.right_wheel.peg_positions, \n", + " cat(enigma.lookup(l) for l in string.ascii_lowercase))\n", + " enigma.advance()" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "collapsed": true, + "scrolled": true + }, + "outputs": [], + "source": [ + "enigma.set_wheels('a', 'a', 't')\n", + "assert(enigma.wheel_positions == (0, 0, 19))\n", + "assert(cat(enigma.wheel_positions_l) == 'aat')\n", + "assert(enigma.peg_positions == ([16], [4], [2]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'puvioztjdhxmlyeawsrgbcqknf')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (0, 0, 20))\n", + "assert(cat(enigma.wheel_positions_l) == 'aau')\n", + "assert(enigma.peg_positions == ([16], [4], [1]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'baigpldqcowfyzjehvtsxrkumn')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (0, 0, 21))\n", + "assert(cat(enigma.wheel_positions_l) == 'aav')\n", + "assert(enigma.peg_positions == ([16], [4], [0]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'mnvfydiwgzsoablrxpkutchqej')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (0, 1, 22))\n", + "assert(cat(enigma.wheel_positions_l) == 'abw')\n", + "assert(enigma.peg_positions == ([16], [3], [25]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'ulfopcykswhbzvderqixanjtgm')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (0, 1, 23))\n", + "assert(cat(enigma.wheel_positions_l) == 'abx')\n", + "assert(enigma.peg_positions == ([16], [3], [24]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'qmwftdyovursbzhxaklejicpgn')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (0, 1, 24))\n", + "assert(cat(enigma.wheel_positions_l) == 'aby')\n", + "assert(enigma.peg_positions == ([16], [3], [23]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'oljmzxrvucybdqasngpwihtfke')\n" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(1, 5, 24) ('b', 'f', 'y') ([15], [25], [23]) baknstqzrmcxjdvygiefwoulph\n" + ] + } + ], + "source": [ + "enigma.set_wheels('a', 'd', 't')\n", + "assert(enigma.wheel_positions == (0, 3, 19))\n", + "assert(cat(enigma.wheel_positions_l) == 'adt')\n", + "assert(enigma.peg_positions == ([16], [1], [2]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'zcbpqxwsjiuonmldethrkygfva')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (0, 3, 20))\n", + "assert(cat(enigma.wheel_positions_l) == 'adu')\n", + "assert(enigma.peg_positions == ([16], [1], [1]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'ehprawjbngotxikcsdqlzyfmvu')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (0, 3, 21))\n", + "assert(cat(enigma.wheel_positions_l) == 'adv')\n", + "assert(enigma.peg_positions == ([16], [1], [0]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'eqzxarpihmnvjkwgbfuyslodtc')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (0, 4, 22))\n", + "assert(cat(enigma.wheel_positions_l) == 'aew')\n", + "assert(enigma.peg_positions == ([16], [0], [25]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'qedcbtpluzmhkongavwfirsyxj')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 5, 23))\n", + "assert(cat(enigma.wheel_positions_l) == 'bfx')\n", + "assert(enigma.peg_positions == ([15], [25], [24]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'iwuedhsfazqxytvrkpgncoblmj')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 5, 24))\n", + "assert(cat(enigma.wheel_positions_l) == 'bfy')\n", + "assert(enigma.peg_positions == ([15], [25], [23]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'baknstqzrmcxjdvygiefwoulph')\n", + "\n", + "print(enigma.wheel_positions, enigma.wheel_positions_l, enigma.peg_positions, \n", + " cat(enigma.lookup(l) for l in string.ascii_lowercase))\n" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'olpfhnvflyn'" + ] + }, + "execution_count": 48, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "enigma.set_wheels('a', 'a', 'a')\n", + "ct = enigma.encipher('testmessage')\n", + "assert(ct == 'olpfhnvflyn')\n", + "ct" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'lawnjgpwjik'" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "enigma.set_wheels('a', 'd', 't')\n", + "ct = enigma.encipher('testmessage')\n", + "assert(ct == 'lawnjgpwjik')\n", + "ct" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 5, 5))\n", + "assert(cat(enigma.wheel_positions_l) == 'bff')\n", + "assert(enigma.peg_positions == ([15], [25], [16]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'zpqiogfsdlmjkyebcvhxwrutna')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 5, 6))\n", + "assert(cat(enigma.wheel_positions_l) == 'bfg')\n", + "assert(enigma.peg_positions == ([15], [25], [15]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'fjmnwayslbxicdpouthrqzekgv')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 5, 7))\n", + "assert(cat(enigma.wheel_positions_l) == 'bfh')\n", + "assert(enigma.peg_positions == ([15], [25], [14]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'csafzdyloxuhnmitwvbpkrqjge')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 5, 8))\n", + "assert(cat(enigma.wheel_positions_l) == 'bfi')\n", + "assert(enigma.peg_positions == ([15], [25], [13]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'kihyvulcbtagwrqzonxjfemsdp')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 5, 9))\n", + "assert(cat(enigma.wheel_positions_l) == 'bfj')\n", + "assert(enigma.peg_positions == ([15], [25], [12]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'pgzrytbksqhwxvuajdifonlmec')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 5, 10))\n", + "assert(cat(enigma.wheel_positions_l) == 'bfk')\n", + "assert(enigma.peg_positions == ([15], [25], [11]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'fkirsazncwbvyhpoudexqljtmg')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 5, 11))\n", + "assert(cat(enigma.wheel_positions_l) == 'bfl')\n", + "assert(enigma.peg_positions == ([15], [25], [10]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'mhkronubsvctafeqpdilgjxwzy')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 5, 12))\n", + "assert(cat(enigma.wheel_positions_l) == 'bfm')\n", + "assert(enigma.peg_positions == ([15], [25], [9]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'gnkuoxarzycmlbetvhwpdqsfji')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 5, 13))\n", + "assert(cat(enigma.wheel_positions_l) == 'bfn')\n", + "assert(enigma.peg_positions == ([15], [25], [8]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'bainslqkcxhfudpogtermwvjzy')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 5, 14))\n", + "assert(cat(enigma.wheel_positions_l) == 'bfo')\n", + "assert(enigma.peg_positions == ([15], [25], [7]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'xemfbdnwjitycgzusvqkprhalo')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 5, 15))\n", + "assert(cat(enigma.wheel_positions_l) == 'bfp')\n", + "assert(enigma.peg_positions == ([15], [25], [6]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'qixksmhgbtdvfonrapejwluczy')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 5, 16))\n", + "assert(cat(enigma.wheel_positions_l) == 'bfq')\n", + "assert(enigma.peg_positions == ([15], [25], [5]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'cgaulmbskwiefrtzynhodxjvqp')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 5, 17))\n", + "assert(cat(enigma.wheel_positions_l) == 'bfr')\n", + "assert(enigma.peg_positions == ([15], [25], [4]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'iwqfldszaxvenmyrcpgutkbjoh')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 5, 18))\n", + "assert(cat(enigma.wheel_positions_l) == 'bfs')\n", + "assert(enigma.peg_positions == ([15], [25], [3]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'vxykrjilgfdhqtusmepnoazbcw')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 5, 19))\n", + "assert(cat(enigma.wheel_positions_l) == 'bft')\n", + "assert(enigma.peg_positions == ([15], [25], [2]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'ieysbvkjahgmlpxnwtdrzfqocu')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 5, 20))\n", + "assert(cat(enigma.wheel_positions_l) == 'bfu')\n", + "assert(enigma.peg_positions == ([15], [25], [1]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'baihkjvdcfepywsltxoqzgnrmu')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 5, 21))\n", + "assert(cat(enigma.wheel_positions_l) == 'bfv')\n", + "assert(enigma.peg_positions == ([15], [25], [0]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'bayjtrilgdshvzuwxfkeompqcn')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 6, 22))\n", + "assert(cat(enigma.wheel_positions_l) == 'bgw')\n", + "assert(enigma.peg_positions == ([15], [24], [25]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'rszqohpfxyutvwegdablkmnijc')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 6, 23))\n", + "assert(cat(enigma.wheel_positions_l) == 'bgx')\n", + "assert(enigma.peg_positions == ([15], [24], [24]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'nfoxhbzeyrwqpacmljtsvukdig')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 6, 24))\n", + "assert(cat(enigma.wheel_positions_l) == 'bgy')\n", + "assert(enigma.peg_positions == ([15], [24], [23]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'czaogmeihtuqfsdxlwnjkyrpvb')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 6, 25))\n", + "assert(cat(enigma.wheel_positions_l) == 'bgz')\n", + "assert(enigma.peg_positions == ([15], [24], [22]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'omwgysdjkhizbxarupfvqtcnel')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 6, 0))\n", + "assert(cat(enigma.wheel_positions_l) == 'bga')\n", + "assert(enigma.peg_positions == ([15], [24], [21]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'cxafmdrzoqutepinjgvlksybwh')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 6, 1))\n", + "assert(cat(enigma.wheel_positions_l) == 'bgb')\n", + "assert(enigma.peg_positions == ([15], [24], [20]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'jymvnrxkoahwceiuzftspdlgbq')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 6, 2))\n", + "assert(cat(enigma.wheel_positions_l) == 'bgc')\n", + "assert(enigma.peg_positions == ([15], [24], [19]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'uzlyiqwrestcnmxvfhjkapgodb')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 6, 3))\n", + "assert(cat(enigma.wheel_positions_l) == 'bgd')\n", + "assert(enigma.peg_positions == ([15], [24], [18]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'veosbuhgpzqynmcikwdxfartlj')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 6, 4))\n", + "assert(cat(enigma.wheel_positions_l) == 'bge')\n", + "assert(enigma.peg_positions == ([15], [24], [17]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'ydhbmtrclxsiezpougkfqwvjan')\n", + "\n" + ] + } + ], + "source": [ + "\n", + "for i in range(26):\n", + " enigma.advance()\n", + " print('enigma.advance()')\n", + " print(\"assert(enigma.wheel_positions == {})\".format(enigma.wheel_positions))\n", + " print(\"assert(cat(enigma.wheel_positions_l) == '{}')\".format(cat(enigma.wheel_positions_l)))\n", + " print(\"assert(enigma.peg_positions == {})\".format(enigma.peg_positions))\n", + " print(\"assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == '{}')\".format(cat(enigma.lookup(l) for l in string.ascii_lowercase)))\n", + " print()" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'bahxvfrpdc'" + ] + }, + "execution_count": 51, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "enigma.set_wheels('a', 'd', 't')\n", + "ct = enigma.encipher('hellothere')\n", + "assert(ct == 'bahxvfrpdc')\n", + "ct" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'kvmmwrlqlqsqpeugjrcxzwpfyiyybwloewrouvkpoztceuwtfjzqwpbqldttsr'" + ] + }, + "execution_count": 52, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "enigma.set_wheels('b', 'd', 'q')\n", + "ct = enigma.encipher('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')\n", + "assert(ct == 'kvmmwrlqlqsqpeugjrcxzwpfyiyybwloewrouvkpoztceuwtfjzqwpbqldttsr')\n", + "assert(enigma.left_wheel.position_l == 'c')\n", + "assert(enigma.middle_wheel.position_l == 'h')\n", + "assert(enigma.right_wheel.position_l == 'a')\n", + "ct" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'c'" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "enigma.left_wheel.position_l" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Setting sheet line 31 from http://www.codesandciphers.org.uk/enigma/enigma3.htm\n", + "# Enigma simulation settings are \n", + "# http://enigma.louisedade.co.uk/enigma.html?m3;b;b153;AFTX;AJFE;AU-BG-EY-FP-HL-IN-JZ-OS-QR-TX\n", + "w_enigma = Enigma(reflector_b_spec, \n", + " wheel_i_spec, wheel_i_pegs,\n", + " wheel_v_spec, wheel_v_pegs,\n", + " wheel_iii_spec, wheel_iii_pegs,\n", + " 6, 20, 24,\n", + " 'ua pf rq so ni ey bg hl tx zj')" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Setting sheet line 31 from http://www.codesandciphers.org.uk/enigma/enigma3.htm\n", + "# Enigma simulation settings are \n", + "# http://enigma.louisedade.co.uk/enigma.html?m3;b;b153;AFTX;AJFE;AU-BG-EY-FP-HL-IN-JZ-OS-QR-TX\n", + "enigma = Enigma(reflector_b_spec, \n", + " wheel_i_spec, wheel_i_pegs,\n", + " wheel_v_spec, wheel_v_pegs,\n", + " wheel_iii_spec, wheel_iii_pegs,\n", + " 6, 20, 24,\n", + " 'ua pf rq so ni ey bg hl tx zj')" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "enigma.set_wheels('j', 'e', 'u')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (4, 11, 24))\n", + "assert(cat(enigma.wheel_positions_l) == 'jev')\n", + "assert(enigma.peg_positions == ([7], [21], [0]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'mvqjlyowkdieasgzcunxrbhtfp')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (4, 12, 25))\n", + "assert(cat(enigma.wheel_positions_l) == 'jfw')\n", + "assert(enigma.peg_positions == ([7], [20], [25]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'sjolzuyvrbwdpxcmtiaqfhknge')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (4, 12, 0))\n", + "assert(cat(enigma.wheel_positions_l) == 'jfx')\n", + "assert(enigma.peg_positions == ([7], [20], [24]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'qrxedkoywufmlvgsabpzjnicht')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (4, 12, 1))\n", + "assert(cat(enigma.wheel_positions_l) == 'jfy')\n", + "assert(enigma.peg_positions == ([7], [20], [23]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'hpsukliagqefwvtbjxcodnmrzy')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (4, 12, 2))\n", + "assert(cat(enigma.wheel_positions_l) == 'jfz')\n", + "assert(enigma.peg_positions == ([7], [20], [22]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'zevnbpyqowrtxdifhkulscjmga')\n" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "enigma.set_wheels('i', 'd', 'z')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 3))\n", + "assert(cat(enigma.wheel_positions_l) == 'ida')\n", + "assert(enigma.peg_positions == ([8], [22], [21]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'ikhpqrvcambzjondefwyxgsutl')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 4))\n", + "assert(cat(enigma.wheel_positions_l) == 'idb')\n", + "assert(enigma.peg_positions == ([8], [22], [20]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'cdabskhgzwfmlqvunyexpojtri')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 5))\n", + "assert(cat(enigma.wheel_positions_l) == 'idc')\n", + "assert(enigma.peg_positions == ([8], [22], [19]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'pcbwiqhgemyvjsuaftnroldzkx')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 6))\n", + "assert(cat(enigma.wheel_positions_l) == 'idd')\n", + "assert(enigma.peg_positions == ([8], [22], [18]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'xcbfvdnouptmlghjzwykierasq')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 7))\n", + "assert(cat(enigma.wheel_positions_l) == 'ide')\n", + "assert(enigma.peg_positions == ([8], [22], [17]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'xfvglbdynuseriwqpmkzjcoaht')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 8))\n", + "assert(cat(enigma.wheel_positions_l) == 'idf')\n", + "assert(enigma.peg_positions == ([8], [22], [16]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'tfpqlbouynsewjgcdxkahzmriv')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 9))\n", + "assert(cat(enigma.wheel_positions_l) == 'idg')\n", + "assert(enigma.peg_positions == ([8], [22], [15]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'cjaunvlwtbygzexrspqidfhokm')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 10))\n", + "assert(cat(enigma.wheel_positions_l) == 'idh')\n", + "assert(enigma.peg_positions == ([8], [22], [14]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'yltxkrqvowebzpingfucshjdam')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 11))\n", + "assert(cat(enigma.wheel_positions_l) == 'idi')\n", + "assert(enigma.peg_positions == ([8], [22], [13]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'myktluzrnxceaiqsohpdfwvjbg')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 12))\n", + "assert(cat(enigma.wheel_positions_l) == 'idj')\n", + "assert(enigma.peg_positions == ([8], [22], [12]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'pynjrmiugdqxfcvakewzhoslbt')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 13))\n", + "assert(cat(enigma.wheel_positions_l) == 'idk')\n", + "assert(enigma.peg_positions == ([8], [22], [11]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'mwvedyplnoxhaijgrqtszcbkfu')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 14))\n", + "assert(cat(enigma.wheel_positions_l) == 'idl')\n", + "assert(enigma.peg_positions == ([8], [22], [10]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'qcbrfeutvoxpnmjladzhgiykws')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 15))\n", + "assert(cat(enigma.wheel_positions_l) == 'idm')\n", + "assert(enigma.peg_positions == ([8], [22], [9]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'dnoahryetsmukbcvwfjilpqzgx')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 16))\n", + "assert(cat(enigma.wheel_positions_l) == 'idn')\n", + "assert(enigma.peg_positions == ([8], [22], [8]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'nidcfehgbqsovalyjzkxwmutpr')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 17))\n", + "assert(cat(enigma.wheel_positions_l) == 'ido')\n", + "assert(enigma.peg_positions == ([8], [22], [7]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'joifxdulcarhzpbntkwqgysevm')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 18))\n", + "assert(cat(enigma.wheel_positions_l) == 'idp')\n", + "assert(enigma.peg_positions == ([8], [22], [6]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'ptnlsxvozmwdjchayuebrgkfqi')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 19))\n", + "assert(cat(enigma.wheel_positions_l) == 'idq')\n", + "assert(enigma.peg_positions == ([8], [22], [5]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'slwopzqnmxybihdeguavrtcjkf')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 20))\n", + "assert(cat(enigma.wheel_positions_l) == 'idr')\n", + "assert(enigma.peg_positions == ([8], [22], [4]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'hcbedwlamzogixkytsrqvufnpj')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 21))\n", + "assert(cat(enigma.wheel_positions_l) == 'ids')\n", + "assert(enigma.peg_positions == ([8], [22], [3]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'odxbjwzrmelkisavuhnyqpfctg')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 22))\n", + "assert(cat(enigma.wheel_positions_l) == 'idt')\n", + "assert(enigma.peg_positions == ([8], [22], [2]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'udgbfeclrwnhxksvtioqapjmzy')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 23))\n", + "assert(cat(enigma.wheel_positions_l) == 'idu')\n", + "assert(enigma.peg_positions == ([8], [22], [1]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'nrdczqxmowvshaiufblypkjgte')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 24))\n", + "assert(cat(enigma.wheel_positions_l) == 'idv')\n", + "assert(enigma.peg_positions == ([8], [22], [0]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'hkifjdoacebqtzgulyvmpsxwrn')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 11, 25))\n", + "assert(cat(enigma.wheel_positions_l) == 'iew')\n", + "assert(enigma.peg_positions == ([8], [21], [25]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'yptzuhofqvnmlkgbixwcejsrad')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 11, 0))\n", + "assert(cat(enigma.wheel_positions_l) == 'iex')\n", + "assert(enigma.peg_positions == ([8], [21], [24]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'vkdcwhqfjibzsptngumoraeyxl')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 11, 1))\n", + "assert(cat(enigma.wheel_positions_l) == 'iey')\n", + "assert(enigma.peg_positions == ([8], [21], [23]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'wenpbqrouxlkychdfgzvitajms')\n" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('verylongtestmessagewithanextrabitofmessageforgoodmeasure',\n", + " (3, 12, 6),\n", + " ('i', 'f', 'd'),\n", + " ([8], [20], [18]),\n", + " 'urygzpdmxtwshqvfnbljaokice')" + ] + }, + "execution_count": 58, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "enigma.set_wheels('i', 'd', 'z')\n", + "ct = enigma.encipher('verylongtestmessagewithanextrabitofmessageforgoodmeasure')\n", + "assert(ct == 'gstsegeqdrthkfwesljjomfvcqwcfspxpfqqmewvddybarzwubxtpejz')\n", + "assert(enigma.wheel_positions == (3, 12, 6))\n", + "assert(cat(enigma.wheel_positions_l) == 'ifd')\n", + "assert(enigma.peg_positions == ([8], [20], [18]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'urygzpdmxtwshqvfnbljaokice')\n", + "\n", + "enigma.set_wheels('i', 'd', 'z')\n", + "pt = enigma.encipher('gstsegeqdrthkfwesljjomfvcqwcfspxpfqqmewvddybarzwubxtpejz')\n", + "assert(pt == 'verylongtestmessagewithanextrabitofmessageforgoodmeasure')\n", + "\n", + "pt, enigma.wheel_positions, enigma.wheel_positions_l, enigma.peg_positions, cat(enigma.lookup(l) for l in string.ascii_lowercase)" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 3))\n", + "assert(cat(enigma.wheel_positions_l) == 'ida')\n", + "assert(enigma.peg_positions == ([8], [22], [21]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'ikhpqrvcambzjondefwyxgsutl')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 4))\n", + "assert(cat(enigma.wheel_positions_l) == 'idb')\n", + "assert(enigma.peg_positions == ([8], [22], [20]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'cdabskhgzwfmlqvunyexpojtri')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 5))\n", + "assert(cat(enigma.wheel_positions_l) == 'idc')\n", + "assert(enigma.peg_positions == ([8], [22], [19]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'pcbwiqhgemyvjsuaftnroldzkx')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 6))\n", + "assert(cat(enigma.wheel_positions_l) == 'idd')\n", + "assert(enigma.peg_positions == ([8], [22], [18]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'xcbfvdnouptmlghjzwykierasq')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 7))\n", + "assert(cat(enigma.wheel_positions_l) == 'ide')\n", + "assert(enigma.peg_positions == ([8], [22], [17]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'xfvglbdynuseriwqpmkzjcoaht')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 8))\n", + "assert(cat(enigma.wheel_positions_l) == 'idf')\n", + "assert(enigma.peg_positions == ([8], [22], [16]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'tfpqlbouynsewjgcdxkahzmriv')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 9))\n", + "assert(cat(enigma.wheel_positions_l) == 'idg')\n", + "assert(enigma.peg_positions == ([8], [22], [15]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'cjaunvlwtbygzexrspqidfhokm')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 10))\n", + "assert(cat(enigma.wheel_positions_l) == 'idh')\n", + "assert(enigma.peg_positions == ([8], [22], [14]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'yltxkrqvowebzpingfucshjdam')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 11))\n", + "assert(cat(enigma.wheel_positions_l) == 'idi')\n", + "assert(enigma.peg_positions == ([8], [22], [13]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'myktluzrnxceaiqsohpdfwvjbg')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 12))\n", + "assert(cat(enigma.wheel_positions_l) == 'idj')\n", + "assert(enigma.peg_positions == ([8], [22], [12]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'pynjrmiugdqxfcvakewzhoslbt')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 13))\n", + "assert(cat(enigma.wheel_positions_l) == 'idk')\n", + "assert(enigma.peg_positions == ([8], [22], [11]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'mwvedyplnoxhaijgrqtszcbkfu')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 14))\n", + "assert(cat(enigma.wheel_positions_l) == 'idl')\n", + "assert(enigma.peg_positions == ([8], [22], [10]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'qcbrfeutvoxpnmjladzhgiykws')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 15))\n", + "assert(cat(enigma.wheel_positions_l) == 'idm')\n", + "assert(enigma.peg_positions == ([8], [22], [9]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'dnoahryetsmukbcvwfjilpqzgx')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 16))\n", + "assert(cat(enigma.wheel_positions_l) == 'idn')\n", + "assert(enigma.peg_positions == ([8], [22], [8]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'nidcfehgbqsovalyjzkxwmutpr')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 17))\n", + "assert(cat(enigma.wheel_positions_l) == 'ido')\n", + "assert(enigma.peg_positions == ([8], [22], [7]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'joifxdulcarhzpbntkwqgysevm')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 18))\n", + "assert(cat(enigma.wheel_positions_l) == 'idp')\n", + "assert(enigma.peg_positions == ([8], [22], [6]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'ptnlsxvozmwdjchayuebrgkfqi')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 19))\n", + "assert(cat(enigma.wheel_positions_l) == 'idq')\n", + "assert(enigma.peg_positions == ([8], [22], [5]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'slwopzqnmxybihdeguavrtcjkf')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 20))\n", + "assert(cat(enigma.wheel_positions_l) == 'idr')\n", + "assert(enigma.peg_positions == ([8], [22], [4]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'hcbedwlamzogixkytsrqvufnpj')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 21))\n", + "assert(cat(enigma.wheel_positions_l) == 'ids')\n", + "assert(enigma.peg_positions == ([8], [22], [3]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'odxbjwzrmelkisavuhnyqpfctg')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 22))\n", + "assert(cat(enigma.wheel_positions_l) == 'idt')\n", + "assert(enigma.peg_positions == ([8], [22], [2]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'udgbfeclrwnhxksvtioqapjmzy')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 23))\n", + "assert(cat(enigma.wheel_positions_l) == 'idu')\n", + "assert(enigma.peg_positions == ([8], [22], [1]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'nrdczqxmowvshaiufblypkjgte')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 10, 24))\n", + "assert(cat(enigma.wheel_positions_l) == 'idv')\n", + "assert(enigma.peg_positions == ([8], [22], [0]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'hkifjdoacebqtzgulyvmpsxwrn')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 11, 25))\n", + "assert(cat(enigma.wheel_positions_l) == 'iew')\n", + "assert(enigma.peg_positions == ([8], [21], [25]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'yptzuhofqvnmlkgbixwcejsrad')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 11, 0))\n", + "assert(cat(enigma.wheel_positions_l) == 'iex')\n", + "assert(enigma.peg_positions == ([8], [21], [24]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'vkdcwhqfjibzsptngumoraeyxl')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 11, 1))\n", + "assert(cat(enigma.wheel_positions_l) == 'iey')\n", + "assert(enigma.peg_positions == ([8], [21], [23]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'wenpbqrouxlkychdfgzvitajms')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (3, 11, 2))\n", + "assert(cat(enigma.wheel_positions_l) == 'iez')\n", + "assert(enigma.peg_positions == ([8], [21], [22]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'szgyqvclkoihurjwenaxmfptdb')\n", + "\n" + ] + } + ], + "source": [ + "enigma.set_wheels('i', 'd', 'z')\n", + "\n", + "for i in range(26):\n", + " enigma.advance()\n", + " print('enigma.advance()')\n", + " print(\"assert(enigma.wheel_positions == {})\".format(enigma.wheel_positions))\n", + " print(\"assert(cat(enigma.wheel_positions_l) == '{}')\".format(cat(enigma.wheel_positions_l)))\n", + " print(\"assert(enigma.peg_positions == {})\".format(enigma.peg_positions))\n", + " print(\"assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == '{}')\".format(cat(enigma.lookup(l) for l in string.ascii_lowercase)))\n", + " print()" + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Reflector B\n", + "# Rotors III, I, II with rings 17, 11, 19\n", + "# Plugboard pairs GU FZ BD LK TC PS HV WN JE AM\n", + "\n", + "tbt_enigma = Enigma(reflector_b_spec, \n", + " wheel_iii_spec, wheel_iii_pegs,\n", + " wheel_i_spec, wheel_i_pegs,\n", + " wheel_ii_spec, wheel_ii_pegs,\n", + " 17, 11, 19,\n", + " 'GU FZ BD LK TC PS HV WN JE AM'.lower())" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'jbvbwwzfslhxnhzzccsngebmrnswgjonwbjnzcfgadeuoyameylmpvny'" + ] + }, + "execution_count": 61, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tbt_enigma.set_wheels('a', 'q', 'v')\n", + "ct = tbt_enigma.encipher('verylongtestmessagewithanextrabitofmessageforgoodmeasure')\n", + "ct" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'slgncszxltkzebghstgywdmpr'" + ] + }, + "execution_count": 62, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "target_ct = ''.join(c.lower() for c in 'SLGNC SZXLT KZEBG HSTGY WDMPR' if c in string.ascii_letters)\n", + "target_ct" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'theyweredetectebybritishshipsinclud'" + ] + }, + "execution_count": 63, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "target_pt = ''.join(c.lower() for c in 'Theyw erede tecte byBri tishs hipsi nclud' if c in string.ascii_letters)\n", + "target_pt" + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'theyweredetectedbybritishshipsinclud'" + ] + }, + "execution_count": 91, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "target_pt = ''.join(c.lower() for c in 'Theyw erede tecte d byBri tishs hipsi nclud' if c in string.ascii_letters)\n", + "target_pt" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(25, 35)" + ] + }, + "execution_count": 64, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(target_ct), len(target_pt)" + ] + }, + { + "cell_type": "code", + "execution_count": 88, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "slgncszxltkzebghstgywdmpr\n", + "theyweredetectebybritishshipsinclud\n" + ] + } + ], + "source": [ + "print('{}\\n{}'.format(target_ct, target_pt))" + ] + }, + { + "cell_type": "code", + "execution_count": 92, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "theyweredetectedbybritishshipsinclud\n", + "slgncszxltkzebghstgywdmpr\n", + "slgncszxltkzebghstgywdmprucuzqdqzpve\n", + "theyweredetectedbybritish\n" + ] + } + ], + "source": [ + "tbt_enigma.set_wheels('a', 'a', 'a')\n", + "this_pt = tbt_enigma.encipher(target_ct)\n", + "\n", + "tbt_enigma.set_wheels('a', 'a', 'a')\n", + "this_ct = tbt_enigma.encipher(target_pt)\n", + "\n", + "\n", + "print('{}\\n{}\\n{}\\n{}'.format(target_pt, target_ct, this_ct, this_pt))" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import itertools" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def str_ham(s1, s2):\n", + " \"\"\"Hamming distance for strings\"\"\"\n", + " return sum(1 for c1, c2 in zip(s1, s2) if c1 == c2)" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5" + ] + }, + "execution_count": 68, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "str_ham('hello', 'hello')" + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "best ('a', 'a', 'a') 25\n", + "best ('a', 'a', 'a') 25\n", + "best ('a', 'a', 'a') 25\n", + "best ('a', 'a', 'a') 25\n", + "1 loop, best of 3: 17.6 s per loop\n" + ] + } + ], + "source": [ + "%%timeit\n", + "best = ('a', 'a', 'a')\n", + "best_hd = 0\n", + "for w1, w2, w3 in itertools.product(string.ascii_lowercase, repeat=3):\n", + " tbt_enigma.set_wheels(w1, w2, w3)\n", + " this_ct = tbt_enigma.encipher(target_pt)\n", + " if this_ct == target_ct:\n", + " print(w1, w2, w3)\n", + " if str_ham(this_ct, target_ct) > best_hd:\n", + " best = (w1, w2, w3)\n", + " best_hd = str_ham(this_ct, target_ct)\n", + "print('best', best, best_hd)" + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Wheels now ['a', 'a', 'b'] enciphering t -> s\n", + "Wheels now ['a', 'a', 'c'] enciphering h -> l\n", + "Wheels now ['a', 'a', 'd'] enciphering e -> g\n", + "Wheels now ['a', 'a', 'e'] enciphering y -> n\n", + "Wheels now ['a', 'b', 'f'] enciphering w -> c\n", + "Wheels now ['a', 'b', 'g'] enciphering e -> s\n", + "Wheels now ['a', 'b', 'h'] enciphering r -> z\n", + "Wheels now ['a', 'b', 'i'] enciphering e -> x\n", + "Wheels now ['a', 'b', 'j'] enciphering d -> l\n", + "Wheels now ['a', 'b', 'k'] enciphering e -> t\n", + "Wheels now ['a', 'b', 'l'] enciphering t -> k\n", + "Wheels now ['a', 'b', 'm'] enciphering e -> z\n", + "Wheels now ['a', 'b', 'n'] enciphering c -> e\n", + "Wheels now ['a', 'b', 'o'] enciphering t -> b\n", + "Wheels now ['a', 'b', 'p'] enciphering e -> g\n", + "Wheels now ['a', 'b', 'q'] enciphering d -> h\n", + "Wheels now ['a', 'b', 'r'] enciphering b -> s\n", + "Wheels now ['a', 'b', 's'] enciphering y -> t\n", + "Wheels now ['a', 'b', 't'] enciphering b -> g\n", + "Wheels now ['a', 'b', 'u'] enciphering r -> y\n", + "Wheels now ['a', 'b', 'v'] enciphering i -> w\n", + "Wheels now ['a', 'b', 'w'] enciphering t -> d\n", + "Wheels now ['a', 'b', 'x'] enciphering i -> m\n", + "Wheels now ['a', 'b', 'y'] enciphering s -> p\n", + "Wheels now ['a', 'b', 'z'] enciphering h -> r\n", + "Wheels now ['a', 'b', 'a'] enciphering s -> u\n", + "Wheels now ['a', 'b', 'b'] enciphering h -> c\n", + "Wheels now ['a', 'b', 'c'] enciphering i -> u\n", + "Wheels now ['a', 'b', 'd'] enciphering p -> z\n", + "Wheels now ['a', 'b', 'e'] enciphering s -> q\n", + "Wheels now ['a', 'c', 'f'] enciphering i -> d\n", + "Wheels now ['a', 'c', 'g'] enciphering n -> q\n", + "Wheels now ['a', 'c', 'h'] enciphering c -> z\n", + "Wheels now ['a', 'c', 'i'] enciphering l -> p\n", + "Wheels now ['a', 'c', 'j'] enciphering u -> v\n", + "Wheels now ['a', 'c', 'k'] enciphering d -> e\n" + ] + }, + { + "data": { + "text/plain": [ + "('slgncszxltkzebghstgywdmprucuzqdqzpve', 'slgncszxltkzebghstgywdmpr')" + ] + }, + "execution_count": 94, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tbt_enigma.set_wheels('a', 'a', 'a')\n", + "tbt_enigma.encipher(target_pt, debug=True), target_ct" + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Wheels now ['a', 'a', 'b'] enciphering s -> t\n", + "Wheels now ['a', 'a', 'c'] enciphering l -> h\n", + "Wheels now ['a', 'a', 'd'] enciphering g -> e\n", + "Wheels now ['a', 'a', 'e'] enciphering n -> y\n", + "Wheels now ['a', 'b', 'f'] enciphering c -> w\n", + "Wheels now ['a', 'b', 'g'] enciphering s -> e\n", + "Wheels now ['a', 'b', 'h'] enciphering z -> r\n", + "Wheels now ['a', 'b', 'i'] enciphering x -> e\n", + "Wheels now ['a', 'b', 'j'] enciphering l -> d\n", + "Wheels now ['a', 'b', 'k'] enciphering t -> e\n", + "Wheels now ['a', 'b', 'l'] enciphering k -> t\n", + "Wheels now ['a', 'b', 'm'] enciphering z -> e\n", + "Wheels now ['a', 'b', 'n'] enciphering e -> c\n", + "Wheels now ['a', 'b', 'o'] enciphering b -> t\n", + "Wheels now ['a', 'b', 'p'] enciphering g -> e\n", + "Wheels now ['a', 'b', 'q'] enciphering h -> d\n", + "Wheels now ['a', 'b', 'r'] enciphering s -> b\n", + "Wheels now ['a', 'b', 's'] enciphering t -> y\n", + "Wheels now ['a', 'b', 't'] enciphering g -> b\n", + "Wheels now ['a', 'b', 'u'] enciphering y -> r\n", + "Wheels now ['a', 'b', 'v'] enciphering w -> i\n", + "Wheels now ['a', 'b', 'w'] enciphering d -> t\n", + "Wheels now ['a', 'b', 'x'] enciphering m -> i\n", + "Wheels now ['a', 'b', 'y'] enciphering p -> s\n", + "Wheels now ['a', 'b', 'z'] enciphering r -> h\n" + ] + }, + { + "data": { + "text/plain": [ + "('theyweredetectedbybritish', 'theyweredetectedbybritishshipsinclud')" + ] + }, + "execution_count": 95, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tbt_enigma.set_wheels('a', 'a', 'a')\n", + "tbt_enigma.encipher(target_ct, debug=True), target_pt" + ] + }, + { + "cell_type": "code", + "execution_count": 96, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('theyweredetectedbybritish', 'theyweredetectedbybritishshipsinclud')" + ] + }, + "execution_count": 96, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tbt_enigma.set_wheels('a', 'a', 'a')\n", + "tbt_enigma.encipher(target_ct), target_pt" + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'mdtbjzuvielkawosqrpcghnxyf'" + ] + }, + "execution_count": 97, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cat(tbt_enigma.plugboard.forward(l) for l in string.ascii_lowercase)" + ] + }, + { + "cell_type": "code", + "execution_count": 99, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10" + ] + }, + "execution_count": 99, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tbt_enigma.set_wheels('a', 'a', 'a')\n", + "tbt_enigma.left_wheel.position" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.3" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/enigma.ipynb b/enigma.ipynb index 06f684a..50d708f 100644 --- a/enigma.ipynb +++ b/enigma.ipynb @@ -4,17 +4,71 @@ "cell_type": "markdown", "metadata": {}, "source": [ + "\n", "# Enigma machine\n", - "Specification from [Codes and Ciphers](http://www.codesandciphers.org.uk/enigma/rotorspec.htm) page.\n", "\n", - "Example Enigma machines from [Louise Dale](http://enigma.louisedade.co.uk/enigma.html) (full simulation) and [EnigmaCo](http://enigmaco.de/enigma/enigma.html) (good animation of the wheels, but no ring settings).\n", + "This is an implementation of an Enigma machine in Python. See below for links that describe the Enigma machine and how it was used.\n", "\n", - "There's also the nice Enigma simulator for Android by [Franklin Heath](https://franklinheath.co.uk/2012/02/04/our-first-app-published-enigma-simulator/), available on the [Google Play store](https://play.google.com/store/apps/details?id=uk.co.franklinheath.enigmasim&hl=en_GB)." + "The Enigma machine has a bunch of components which can be swapped or modified to change its behaviour. The components are:\n", + "\n", + "* The plugboard\n", + "* The wheels (three chosen from a set of five)\n", + "* The reflector (two available, though generally not swapped)\n", + "\n", + "The plugboard and wheel selection were changed every day. The wheel orientation was changed every message.\n", + "\n", + "## Design sketch\n", + "Each of the components can be thought of as a \"letter transformer\", which take a letter and input and give a different letter as output. From a given setup (plugboard setting or wheel orientation), these transformations are deterministic: if nothing moves, the same letter input will give the same letter output. Depending on the component, forward and backward transformations can be different. For instance, the wheel I converts `a` to `e` forward, and `a` to `u` backward.\n", + "\n", + "This means we can take an object oriented approach to building the Enigma machine. The machine itself is a collection (aggregation) of components. Each component keeps track of its current state. \n", + "\n", + "The components have an inheritance hierarchy.\n", + "\n", + "* [LetterTransformer](#lettertransformer)\n", + " * [Plugobard](#plugboard)\n", + " * [Reflector](#reflector)\n", + " * [SimpleWheel](#simplewheel)\n", + " * [Wheel](#wheel)\n", + "\n", + "The `LetterTransformer` is the base class and defines the basic operations all the transformers apply. \n", + "\n", + "A `Plugboard` is a type of `LetterTransformer` that swaps only some letters, and acts the same both forward and backward. The `Reflector` acts like a `Plugboard` but with 13 pairs of swaps.\n", + "\n", + "A `SimpleWheel` has different forward and backward transforms, and also rotates. A `Wheel` is the same, but the indicator \"ring\" around the outside can be rotated around the core. This ring of a `Wheel` has a notch that can control when other `SimpleWheel`s and `Wheel`s are rotated in the Enigma.\n", + "\n", + "Note that all the logic of when the wheels rotate is controlled by the Enigma machine.\n", + "\n", + "* [Engima](#enigma)\n", + "* [Testing Enigma](#testingenigma)\n", + "\n", + "### Implmentation note\n", + "The normal way to define a class in Python is to define all the methods, class variables, and instance variables at the same time. However, that makes it difficult to place the discussion of the various methods and what they do near the definitions. \n", + "\n", + "This notebook takes a variant approach of defining the base class, then defining methods in separate cells and adding them to the class with the `setattr()` procedure.\n", + "\n", + "\n", + "## See also\n", + "* Specification from [Codes and Ciphers](http://www.codesandciphers.org.uk/enigma/rotorspec.htm) page.\n", + "\n", + "* Example Enigma machines from [Louise Dale](http://enigma.louisedade.co.uk/enigma.html) (full simulation) and [EnigmaCo](http://enigmaco.de/enigma/enigma.html) (good animation of the wheels, but no ring settings).\n", + "\n", + "* There's also the nice Enigma simulator for Android by [Franklin Heath](https://franklinheath.co.uk/2012/02/04/our-first-app-published-enigma-simulator/), available on the [Google Play store](https://play.google.com/store/apps/details?id=uk.co.franklinheath.enigmasim&hl=en_GB).\n", + "\n", + "* Enigma wiring from the [Crypto Museum](http://www.cryptomuseum.com/crypto/enigma/wiring.htm)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First, some general-purpose and utility imports. \n", + "\n", + "`pos` and `unpos` convert between letters and numbers (in range 0-25 inclusive)." ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 108, "metadata": { "collapsed": true }, @@ -38,9 +92,16 @@ "def unpos(number): return chr(number % 26 + ord('a'))" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The wheel specifications show what positions `a` to `z` (ignoring the ring) go to. For instance, Wheel 1 converts `a` to `e` forward, and `a` to `u` backward. The notch positions show where the wheel advance notches are on the wheel rings. The reflector specifications show the reflected pairs." + ] + }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 109, "metadata": { "collapsed": true }, @@ -57,14 +118,14 @@ "beta_wheel_spec = 'leyjvcnixwpbqmdrtakzgfuhos'\n", "gamma_wheel_spec = 'fsokanuerhmbtiycwlqpzxvgjd'\n", "\n", - "wheel_i_pegs = ['q']\n", - "wheel_ii_pegs = ['e']\n", - "wheel_iii_pegs = ['v']\n", - "wheel_iv_pegs = ['j']\n", - "wheel_v_pegs = ['z']\n", - "wheel_vi_pegs = ['z', 'm']\n", - "wheel_vii_pegs = ['z', 'm']\n", - "wheel_viii_pegs = ['z', 'm']\n", + "wheel_i_notches = ['q']\n", + "wheel_ii_notches = ['e']\n", + "wheel_iii_notches = ['v']\n", + "wheel_iv_notches = ['j']\n", + "wheel_v_notches = ['z']\n", + "wheel_vi_notches = ['z', 'm']\n", + "wheel_vii_notches = ['z', 'm']\n", + "wheel_viii_notches = ['z', 'm']\n", "\n", "reflector_b_spec = 'ay br cu dh eq fs gl ip jx kn mo tz vw'\n", "reflector_c_spec = 'af bv cp dj ei go hy kr lz mx nw tq su'" @@ -72,9 +133,85 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 110, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# class LetterTransformer(object):\n", + "# def __init__(self, specification, raw_transform=False):\n", + "# if raw_transform:\n", + "# transform = specification\n", + "# else:\n", + "# transform = self.parse_specification(specification)\n", + "# self.validate_transform(transform)\n", + "# self.make_transform_map(transform)\n", + " \n", + "# def parse_specification(self, specification):\n", + "# return list(zip(string.ascii_lowercase, clean(specification)))\n", + "# # return specification\n", + " \n", + "# def validate_transform(self, transform):\n", + "# \"\"\"A set of pairs, of from-to\"\"\"\n", + "# if len(transform) != 26:\n", + "# raise ValueError(\"Transform specification has {} pairs, requires 26\".\n", + "# format(len(transform)))\n", + "# for p in transform:\n", + "# if len(p) != 2:\n", + "# raise ValueError(\"Not all mappings in transform \"\n", + "# \"have two elements\")\n", + "# if len(set([p[0] for p in transform])) != 26:\n", + "# raise ValueError(\"Transform specification must list 26 origin letters\") \n", + "# if len(set([p[1] for p in transform])) != 26:\n", + "# raise ValueError(\"Transform specification must list 26 destination letters\") \n", + "\n", + "# def make_empty_transform(self):\n", + "# self.forward_map = [0] * 26\n", + "# self.backward_map = [0] * 26\n", + " \n", + "# def make_transform_map(self, transform):\n", + "# self.make_empty_transform()\n", + "# for p in transform:\n", + "# self.forward_map[pos(p[0])] = pos(p[1])\n", + "# self.backward_map[pos(p[1])] = pos(p[0])\n", + "# return self.forward_map, self.backward_map\n", + " \n", + "# def forward(self, letter):\n", + "# if letter in string.ascii_lowercase:\n", + "# return unpos(self.forward_map[pos(letter)])\n", + "# else:\n", + "# return ''\n", + " \n", + "# def backward(self, letter):\n", + "# if letter in string.ascii_lowercase:\n", + "# return unpos(self.backward_map[pos(letter)])\n", + "# else:\n", + "# return ''" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "# Letter transformer\n", + "[Top](#top)\n", + "\n", + "A generic transformer of letters. All components in the Enigma are based on this. \n", + "\n", + "The transformer has two directions, `forward` and `backward`. In each direction, a given letter is transformed into a different letter. Both transformations are general permutations of the alphabet (i.e. each letter goes to one and only one new letter). There is no general requirement for the `forward` and `backward` transformations to have any particular relationship to each other (even though most do in the Enigma machine).\n", + "\n", + "When created, it must be given the transformation which should be applied. A raw transform is a sequence of letter pairs, such that `p[0]` is transformed to `p[1]` forwards, and `p[1]` goes to `p[0]` backwards.\n", + "\n", + "If the transform is not raw, it's assumed that the specification is a sequence of the `p[1]`s, and the standard alphabet gives the `p[0]`s." + ] + }, + { + "cell_type": "code", + "execution_count": 111, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -85,56 +222,200 @@ " else:\n", " transform = self.parse_specification(specification)\n", " self.validate_transform(transform)\n", - " self.make_transform_map(transform)\n", - " \n", - " def parse_specification(self, specification):\n", - " return list(zip(string.ascii_lowercase, clean(specification)))\n", - " # return specification\n", - " \n", - " def validate_transform(self, transform):\n", - " \"\"\"A set of pairs, of from-to\"\"\"\n", - " if len(transform) != 26:\n", - " raise ValueError(\"Transform specification has {} pairs, requires 26\".\n", - " format(len(transform)))\n", - " for p in transform:\n", - " if len(p) != 2:\n", - " raise ValueError(\"Not all mappings in transform \"\n", - " \"have two elements\")\n", - " if len(set([p[0] for p in transform])) != 26:\n", - " raise ValueError(\"Transform specification must list 26 origin letters\") \n", - " if len(set([p[1] for p in transform])) != 26:\n", - " raise ValueError(\"Transform specification must list 26 destination letters\") \n", - "\n", - " def make_empty_transform(self):\n", - " self.forward_map = [0] * 26\n", - " self.backward_map = [0] * 26\n", - " \n", - " def make_transform_map(self, transform):\n", - " self.make_empty_transform()\n", - " for p in transform:\n", - " self.forward_map[pos(p[0])] = pos(p[1])\n", - " self.backward_map[pos(p[1])] = pos(p[0])\n", - " return self.forward_map, self.backward_map\n", - " \n", - " def forward(self, letter):\n", - " if letter in string.ascii_lowercase:\n", - " return unpos(self.forward_map[pos(letter)])\n", - " else:\n", - " return ''\n", - " \n", - " def backward(self, letter):\n", - " if letter in string.ascii_lowercase:\n", - " return unpos(self.backward_map[pos(letter)])\n", - " else:\n", - " return ''" + " self.make_transform_map(transform)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Parse a specification: convert a string of destination letters into a list of pairs. " + ] + }, + { + "cell_type": "code", + "execution_count": 112, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def parse_specification(self, specification):\n", + " return list(zip(string.ascii_lowercase, clean(specification)))\n", + " # return specification\n", + "\n", + "setattr(LetterTransformer, \"parse_specification\", parse_specification)" + ] + }, + { + "cell_type": "code", + "execution_count": 113, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[('a', 'e'),\n", + " ('b', 'k'),\n", + " ('c', 'm'),\n", + " ('d', 'f'),\n", + " ('e', 'l'),\n", + " ('f', 'g'),\n", + " ('g', 'd'),\n", + " ('h', 'q'),\n", + " ('i', 'v'),\n", + " ('j', 'z'),\n", + " ('k', 'n'),\n", + " ('l', 't'),\n", + " ('m', 'o'),\n", + " ('n', 'w'),\n", + " ('o', 'y'),\n", + " ('p', 'h'),\n", + " ('q', 'x'),\n", + " ('r', 'u'),\n", + " ('s', 's'),\n", + " ('t', 'p'),\n", + " ('u', 'a'),\n", + " ('v', 'i'),\n", + " ('w', 'b'),\n", + " ('x', 'r'),\n", + " ('y', 'c'),\n", + " ('z', 'j')]" + ] + }, + "execution_count": 113, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "parse_specification(None, wheel_i_spec)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Checks that a transform is valid." + ] + }, + { + "cell_type": "code", + "execution_count": 114, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def validate_transform(self, transform):\n", + " \"\"\"A set of pairs, of from-to\"\"\"\n", + " if len(transform) != 26:\n", + " raise ValueError(\"Transform specification has {} pairs, requires 26\".\n", + " format(len(transform)))\n", + " for p in transform:\n", + " if len(p) != 2:\n", + " raise ValueError(\"Not all mappings in transform \"\n", + " \"have two elements\")\n", + " if len(set([p[0] for p in transform])) != 26:\n", + " raise ValueError(\"Transform specification must list 26 origin letters\") \n", + " if len(set([p[1] for p in transform])) != 26:\n", + " raise ValueError(\"Transform specification must list 26 destination letters\") \n", + "\n", + "setattr(LetterTransformer, \"validate_transform\", validate_transform) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The empty transform maps each letter to itself, forward and backward. A useful starting point for creating the maps needed.\n", + "\n", + "The forward and backward maps are `list`s of numbers (rather than `dict`s of letters to letters) to make the calculations easier when it comes to the wheels, and wheels with turnable indicator rings." + ] + }, + { + "cell_type": "code", + "execution_count": 115, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# def make_empty_transform(self):\n", + "# self.forward_map = [0] * 26\n", + "# self.backward_map = [0] * 26\n", + "\n", + "# setattr(LetterTransformer, \"make_empty_transform\", make_empty_transform) " + ] + }, + { + "cell_type": "code", + "execution_count": 116, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def make_empty_transform(self):\n", + " self.forward_map = list(range(26))\n", + " self.backward_map = list(range(26))\n", + "\n", + "setattr(LetterTransformer, \"make_empty_transform\", make_empty_transform) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Make the transform. Starting from an empty transform, mutate it to include the swaps. Note that the forward and backward swaps are stored separately. " + ] + }, + { + "cell_type": "code", + "execution_count": 117, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def make_transform_map(self, transform):\n", + " self.make_empty_transform()\n", + " for p in transform:\n", + " self.forward_map[pos(p[0])] = pos(p[1])\n", + " self.backward_map[pos(p[1])] = pos(p[0])\n", + " return self.forward_map, self.backward_map\n", + "\n", + "setattr(LetterTransformer, \"make_transform_map\", make_transform_map)" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 118, "metadata": { - "collapsed": false + "collapsed": true }, + "outputs": [], + "source": [ + "def forward(self, letter):\n", + " if letter in string.ascii_lowercase:\n", + " return unpos(self.forward_map[pos(letter)])\n", + " else:\n", + " return ''\n", + "\n", + "def backward(self, letter):\n", + " if letter in string.ascii_lowercase:\n", + " return unpos(self.backward_map[pos(letter)])\n", + " else:\n", + " return ''\n", + "\n", + "setattr(LetterTransformer, \"forward\", forward)\n", + "setattr(LetterTransformer, \"backward\", backward) " + ] + }, + { + "cell_type": "code", + "execution_count": 119, + "metadata": {}, "outputs": [ { "data": { @@ -167,7 +448,7 @@ " ('y', 'z')]" ] }, - "execution_count": 4, + "execution_count": 119, "metadata": {}, "output_type": "execute_result" } @@ -179,10 +460,8 @@ }, { "cell_type": "code", - "execution_count": 5, - "metadata": { - "collapsed": false - }, + "execution_count": 120, + "metadata": {}, "outputs": [ { "data": { @@ -190,7 +469,7 @@ "'zyxwcabdefghijklmnopqrstuv'" ] }, - "execution_count": 5, + "execution_count": 120, "metadata": {}, "output_type": "execute_result" } @@ -201,9 +480,9 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 121, "metadata": { - "collapsed": false, + "collapsed": true, "scrolled": true }, "outputs": [], @@ -213,9 +492,8 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 122, "metadata": { - "collapsed": false, "scrolled": true }, "outputs": [ @@ -276,7 +554,7 @@ " 24])" ] }, - "execution_count": 7, + "execution_count": 122, "metadata": {}, "output_type": "execute_result" } @@ -290,9 +568,8 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 123, "metadata": { - "collapsed": false, "scrolled": true }, "outputs": [ @@ -353,7 +630,7 @@ " 0])" ] }, - "execution_count": 8, + "execution_count": 123, "metadata": {}, "output_type": "execute_result" } @@ -369,10 +646,8 @@ }, { "cell_type": "code", - "execution_count": 9, - "metadata": { - "collapsed": false - }, + "execution_count": 124, + "metadata": {}, "outputs": [ { "data": { @@ -380,7 +655,7 @@ "'zyxwcabdefghijklmnopqrstuv'" ] }, - "execution_count": 9, + "execution_count": 124, "metadata": {}, "output_type": "execute_result" } @@ -391,10 +666,8 @@ }, { "cell_type": "code", - "execution_count": 10, - "metadata": { - "collapsed": false - }, + "execution_count": 125, + "metadata": {}, "outputs": [ { "data": { @@ -402,7 +675,7 @@ "'fgehijklmnopqrstuvwxyzdcba'" ] }, - "execution_count": 10, + "execution_count": 125, "metadata": {}, "output_type": "execute_result" } @@ -411,9 +684,20 @@ "cat(lt.backward(l) for l in string.ascii_lowercase)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## Plugboard\n", + "[Top](#top)\n", + "\n", + "A `Plugboard` is a `LetterTransformer` that swaps some pairs of letters, and does the same swaps forward and backward." + ] + }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 126, "metadata": { "collapsed": true }, @@ -430,9 +714,9 @@ " raise ValueError(\"Not all mappings in transform\"\n", " \"have two elements\")\n", " \n", - " def make_empty_transform(self):\n", - " self.forward_map = list(range(26))\n", - " self.backward_map = list(range(26))\n", + "# def make_empty_transform(self):\n", + "# self.forward_map = list(range(26))\n", + "# self.backward_map = list(range(26))\n", " \n", " def make_transform_map(self, transform):\n", " expanded_transform = transform + [tuple(reversed(p)) for p in transform]\n", @@ -441,9 +725,9 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 127, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -452,10 +736,8 @@ }, { "cell_type": "code", - "execution_count": 13, - "metadata": { - "collapsed": false - }, + "execution_count": 128, + "metadata": {}, "outputs": [ { "data": { @@ -463,7 +745,7 @@ "'zycdefghijklmnopqrstuvwxba'" ] }, - "execution_count": 13, + "execution_count": 128, "metadata": {}, "output_type": "execute_result" } @@ -474,10 +756,8 @@ }, { "cell_type": "code", - "execution_count": 14, - "metadata": { - "collapsed": false - }, + "execution_count": 129, + "metadata": {}, "outputs": [ { "data": { @@ -485,7 +765,7 @@ "'zycdefghijklmnopqrstuvwxba'" ] }, - "execution_count": 14, + "execution_count": 129, "metadata": {}, "output_type": "execute_result" } @@ -496,9 +776,9 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 130, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -507,10 +787,8 @@ }, { "cell_type": "code", - "execution_count": 16, - "metadata": { - "collapsed": false - }, + "execution_count": 131, + "metadata": {}, "outputs": [ { "data": { @@ -518,7 +796,7 @@ "('zycdefghijklmnopqrstuvwxba', 'zycdefghijklmnopqrstuvwxba')" ] }, - "execution_count": 16, + "execution_count": 131, "metadata": {}, "output_type": "execute_result" } @@ -529,10 +807,8 @@ }, { "cell_type": "code", - "execution_count": 17, - "metadata": { - "collapsed": false - }, + "execution_count": 132, + "metadata": {}, "outputs": [ { "data": { @@ -540,7 +816,7 @@ "('ugcdypblnzkhmisfrqoxavwtej', 'ugcdypblnzkhmisfrqoxavwtej')" ] }, - "execution_count": 17, + "execution_count": 132, "metadata": {}, "output_type": "execute_result" } @@ -554,9 +830,20 @@ "cat(pb.forward(l) for l in string.ascii_lowercase), cat(pb.backward(l) for l in string.ascii_lowercase)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## Reflector\n", + "[Top](#top)\n", + "\n", + "A `Reflector` is a `Plugboard` that takes exactly 13 pairs of letters to swap." + ] + }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 133, "metadata": { "collapsed": true }, @@ -578,10 +865,8 @@ }, { "cell_type": "code", - "execution_count": 19, - "metadata": { - "collapsed": false - }, + "execution_count": 134, + "metadata": {}, "outputs": [ { "data": { @@ -601,7 +886,7 @@ " ('v', 'w')]" ] }, - "execution_count": 19, + "execution_count": 134, "metadata": {}, "output_type": "execute_result" } @@ -614,9 +899,9 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 135, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -629,10 +914,8 @@ }, { "cell_type": "code", - "execution_count": 21, - "metadata": { - "collapsed": false - }, + "execution_count": 136, + "metadata": {}, "outputs": [ { "data": { @@ -640,7 +923,7 @@ "'yruhqsldpxngokmiebfzcwvjat'" ] }, - "execution_count": 21, + "execution_count": 136, "metadata": {}, "output_type": "execute_result" } @@ -651,9 +934,9 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 137, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -662,10 +945,8 @@ }, { "cell_type": "code", - "execution_count": 23, - "metadata": { - "collapsed": false - }, + "execution_count": 138, + "metadata": {}, "outputs": [ { "data": { @@ -673,7 +954,7 @@ "'fvpjiaoyedrzxwgctkuqsbnmhl'" ] }, - "execution_count": 23, + "execution_count": 138, "metadata": {}, "output_type": "execute_result" } @@ -683,49 +964,122 @@ ] }, { - "cell_type": "code", - "execution_count": 24, - "metadata": { - "collapsed": true - }, - "outputs": [], + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## SimpleWheel\n", + "[Top](#top)\n", + "\n", + "A `SimpleWheel` has different forward and backward maps, and also a position. The position is set with the `set_position` method (and initially in the creator), and the wheel can advance using the `advance` method. \n", + "\n", + "How the position is used is best explained with an example. The Enigma wheel 1, in the neutral position, transforms `a` to `e` (+4 letters) and `b` to `k` (+10 letters). When the wheel is in position `b` and an `a` in enciphered, it's the _second_ element of the map that's used, so `a` would be advanced 10 letters, to give `j`.\n", + "\n", + "This means that when using the letter transformation maps, you use the element in the map that's offset by the position of the wheel. When enciphering a `c`, you'd normally use transformation at position 2 in the map; if the wheel is in position 7, you'd instead use the transform at position 2 + 7 = 9 in the map.\n", + "\n", + "There are various modulus operators to keep the numbers in the requried range, meaning you can wrap around the map and around the wheel.\n", + "\n", + "Note the use of `__getattribute__` to give a more human-friendly version of the position without making it a method call. That allows you to write `wheel.position` and `wheel.position_l` and get the appropriate answers." + ] + }, + { + "cell_type": "code", + "execution_count": 139, + "metadata": { + "collapsed": true + }, + "outputs": [], "source": [ "class SimpleWheel(LetterTransformer):\n", " def __init__(self, transform, position='a', raw_transform=False):\n", " super(SimpleWheel, self).__init__(transform, raw_transform)\n", " self.set_position(position)\n", " \n", - " def __getattribute__(self,name):\n", + " def __getattribute__(self, name):\n", " if name=='position_l':\n", " return unpos(self.position)\n", " else:\n", - " return object.__getattribute__(self, name)\n", - " \n", - " def set_position(self, position):\n", - " self.position = ord(position) - ord('a')\n", - " \n", - " def forward(self, letter):\n", - " if letter in string.ascii_lowercase:\n", - " return unpos((self.forward_map[(pos(letter) + self.position) % 26] - self.position))\n", - " else:\n", - " return ''\n", - " \n", - " def backward(self, letter):\n", - " if letter in string.ascii_lowercase:\n", - " return unpos((self.backward_map[(pos(letter) + self.position) % 26] - self.position))\n", - " else:\n", - " return ''\n", + " return object.__getattribute__(self, name) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Set the wheel to a new position. Note that it expects a letter, not a number." + ] + }, + { + "cell_type": "code", + "execution_count": 140, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def set_position(self, position):\n", + " self.position = ord(position) - ord('a')\n", + " \n", + "setattr(SimpleWheel, 'set_position', set_position) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Advance the wheel one step. Note that advancing beyond position 25 moves back to 0." + ] + }, + { + "cell_type": "code", + "execution_count": 141, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def advance(self):\n", + " self.position = (self.position + 1) % 26\n", + " return self.position\n", + "\n", + "setattr(SimpleWheel, 'advance', advance) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Do the encipherment forward and backward. Note how the map element to use is affected by the wheel position, and how the modulus wraps that map element around the wheel if needed." + ] + }, + { + "cell_type": "code", + "execution_count": 142, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def forward(self, letter):\n", + " if letter in string.ascii_lowercase:\n", + " return unpos((self.forward_map[(pos(letter) + self.position) % 26] - self.position))\n", + " else:\n", + " return ''\n", + "\n", + "def backward(self, letter):\n", + " if letter in string.ascii_lowercase:\n", + " return unpos((self.backward_map[(pos(letter) + self.position) % 26] - self.position))\n", + " else:\n", + " return ''\n", " \n", - " def advance(self):\n", - " self.position = (self.position + 1) % 26\n", - " return self.position" + "setattr(SimpleWheel, 'forward', forward) \n", + "setattr(SimpleWheel, 'backward', backward) " ] }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 143, "metadata": { - "collapsed": false, "scrolled": true }, "outputs": [ @@ -760,7 +1114,7 @@ " ('z', 'j')]" ] }, - "execution_count": 25, + "execution_count": 143, "metadata": {}, "output_type": "execute_result" } @@ -772,9 +1126,9 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 144, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -786,18 +1140,84 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 145, "metadata": { - "collapsed": false + "scrolled": true }, "outputs": [ { "data": { "text/plain": [ - "('ekmflgdqvzntowyhxuspaibrcj', 'uwygadfpvzbeckmthxslrinqoj')" + "[4,\n", + " 10,\n", + " 12,\n", + " 5,\n", + " 11,\n", + " 6,\n", + " 3,\n", + " 16,\n", + " 21,\n", + " 25,\n", + " 13,\n", + " 19,\n", + " 14,\n", + " 22,\n", + " 24,\n", + " 7,\n", + " 23,\n", + " 20,\n", + " 18,\n", + " 15,\n", + " 0,\n", + " 8,\n", + " 1,\n", + " 17,\n", + " 2,\n", + " 9]" + ] + }, + "execution_count": 145, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "wheel_1.forward_map" + ] + }, + { + "cell_type": "code", + "execution_count": 146, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'j'" + ] + }, + "execution_count": 146, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "wheel_1.advance()\n", + "wheel_1.forward('a')" + ] + }, + { + "cell_type": "code", + "execution_count": 147, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('jlekfcpuymsnvxgwtrozhaqbid', 'vxfzceouyadbjlsgwrkqhmpnit')" ] }, - "execution_count": 27, + "execution_count": 147, "metadata": {}, "output_type": "execute_result" } @@ -808,18 +1228,16 @@ }, { "cell_type": "code", - "execution_count": 28, - "metadata": { - "collapsed": false - }, + "execution_count": 148, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "'a'" + "'b'" ] }, - "execution_count": 28, + "execution_count": 148, "metadata": {}, "output_type": "execute_result" } @@ -830,9 +1248,9 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 149, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ @@ -843,10 +1261,8 @@ }, { "cell_type": "code", - "execution_count": 30, - "metadata": { - "collapsed": false - }, + "execution_count": 150, + "metadata": {}, "outputs": [ { "data": { @@ -854,7 +1270,7 @@ "('ajdksiruxblhwtmcqgznpyfvoe', 'ajpczwrlfbdkotyuqgenhxmivs')" ] }, - "execution_count": 30, + "execution_count": 150, "metadata": {}, "output_type": "execute_result" } @@ -865,10 +1281,8 @@ }, { "cell_type": "code", - "execution_count": 31, - "metadata": { - "collapsed": false - }, + "execution_count": 151, + "metadata": {}, "outputs": [ { "data": { @@ -876,7 +1290,7 @@ "('bdfhjlcprtxvznyeiwgakmusqo', 'tagbpcsdqeufvnzhyixjwlrkom')" ] }, - "execution_count": 31, + "execution_count": 151, "metadata": {}, "output_type": "execute_result" } @@ -905,100 +1319,158 @@ "cat(wheel_3.forward(l) for l in string.ascii_lowercase), cat(wheel_3.backward(l) for l in string.ascii_lowercase)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## Wheel\n", + "[Top](#top)\n", + "\n", + "This is the same as a `SimpleWheel`, but with the addition of a ring.\n", + "\n", + "The ring is moveable around the core of the wheel (with the wiring). This means that moving the ring changes the orientation of the core and wiring for the same setting.\n", + "\n", + "| Wheel with notch | Notch showing peg to hold it in place |\n", + "| ---------------- | ------------------------------------- |\n", + "| \"Enigma | \"Enigma |\n", + "| (From [Crypto museum](http://www.cryptomuseum.com/crypto/enigma/img/300879/035/full.jpg)) | From [Matematik Sider](http://www.matematiksider.dk/enigma/dtu_notch_big.jpg) |\n", + "\n", + "Though it's not very visible in the right hand image, the extra metal below the ring shows a spring-loaded peg on the wheel core which drops into the ring, with one hole per letter. The ring setting is where the peg drops into the ring.\n", + "\n", + "The notch setting is used in the full Enigma to control when the wheels step forward.\n", + "\n", + "Note that the constructor calls the superclass's constructor, then sets the positions properly with a call to `set_position`." + ] + }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 152, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ "class Wheel(SimpleWheel):\n", - " def __init__(self, transform, ring_peg_letters, ring_setting=1, position='a', raw_transform=False):\n", - " self.ring_peg_letters = ring_peg_letters\n", + " def __init__(self, transform, ring_notch_letters, ring_setting=1, position='a', raw_transform=False):\n", + " self.ring_notch_letters = ring_notch_letters\n", " self.ring_setting = ring_setting\n", " super(Wheel, self).__init__(transform, position=position, raw_transform=raw_transform)\n", - " self.set_position(position)\n", - " \n", - " def __getattribute__(self,name):\n", - " if name=='position_l':\n", - " return unpos(self.position + self.ring_setting - 1)\n", - " else:\n", - " return object.__getattribute__(self, name)\n", + " self.set_position(position)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `position` of the wheel is the orientation of the core. It's the same as the ring if the ring setting is 1. The `position_l` attribute is used to report the position of the ring letter, which is what the Enigma operator would see. " + ] + }, + { + "cell_type": "code", + "execution_count": 153, + "metadata": {}, + "outputs": [], + "source": [ + "def __getattribute__(self,name):\n", + " if name=='position_l':\n", + " return unpos(self.position + self.ring_setting - 1)\n", + " else:\n", + " return object.__getattribute__(self, name)\n", "\n", - " def set_position(self, position):\n", + "def set_position(self, position):\n", + "# self.position = (pos(position) - self.ring_setting + 1) % 26\n", + " if isinstance(position, str):\n", " self.position = (pos(position) - self.ring_setting + 1) % 26\n", - " # self.position_l = position\n", - " self.peg_positions = [(pos(p) - pos(position)) % 26 for p in self.ring_peg_letters]\n", + " else:\n", + " self.position = (position - self.ring_setting) % 26\n", + "# self.notch_positions = [(pos(position) - pos(p)) % 26 for p in self.ring_notch_letters]\n", + " self.notch_positions = [(self.position + self.ring_setting - 1 - pos(p)) % 26 for p in self.ring_notch_letters]\n", " \n", - " def advance(self):\n", - " super(Wheel, self).advance()\n", - " self.peg_positions = [(p - 1) % 26 for p in self.peg_positions]\n", - " # self.position_l = unpos(self.position + self.ring_setting - 1)\n", - " return self.position" + "setattr(Wheel, '__getattribute__', __getattribute__) \n", + "setattr(Wheel, 'set_position', set_position) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Advance the wheel. Again, note the superclass call, followed by the update of the notch positions." ] }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 154, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ - "wheel_3 = Wheel(wheel_iii_spec, wheel_iii_pegs, position='b', ring_setting=1)" + "def advance(self):\n", + " super(Wheel, self).advance()\n", + " self.notch_positions = [(p + 1) % 26 for p in self.notch_positions]\n", + " # self.position_l = unpos(self.position + self.ring_setting - 1)\n", + " return self.position\n", + " \n", + "setattr(Wheel, 'advance', advance) " ] }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 155, "metadata": { - "collapsed": false + "collapsed": true }, + "outputs": [], + "source": [ + "wheel_3 = Wheel(wheel_iii_spec, wheel_iii_notches, position='b', ring_setting=1)" + ] + }, + { + "cell_type": "code", + "execution_count": 156, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "(1, [20])" + "(1, [6])" ] }, - "execution_count": 34, + "execution_count": 156, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "wheel_3.position, wheel_3.peg_positions" + "wheel_3.position, wheel_3.notch_positions" ] }, { "cell_type": "code", - "execution_count": 35, - "metadata": { - "collapsed": false - }, + "execution_count": 157, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "(25, [24, 11])" + "(25, [2, 15])" ] }, - "execution_count": 35, + "execution_count": 157, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "wheel_6 = Wheel(wheel_vi_spec, wheel_vi_pegs, position='b', ring_setting=3)\n", - "wheel_6.position, wheel_6.peg_positions" + "wheel_6 = Wheel(wheel_vi_spec, wheel_vi_notches, position='b', ring_setting=3)\n", + "wheel_6.position, wheel_6.notch_positions" ] }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 158, "metadata": { - "collapsed": false, "scrolled": true }, "outputs": [ @@ -1006,166 +1478,252 @@ "name": "stdout", "output_type": "stream", "text": [ - "0 [23, 10]\n", - "1 [22, 9]\n", - "2 [21, 8]\n", - "3 [20, 7]\n", - "4 [19, 6]\n", - "5 [18, 5]\n", - "6 [17, 4]\n", - "7 [16, 3]\n", - "8 [15, 2]\n", - "9 [14, 1]\n", + "0 [3, 16]\n", + "1 [4, 17]\n", + "2 [5, 18]\n", + "3 [6, 19]\n", + "4 [7, 20]\n", + "5 [8, 21]\n", + "6 [9, 22]\n", + "7 [10, 23]\n", + "8 [11, 24]\n", + "9 [12, 25]\n", "10 [13, 0]\n", - "11 [12, 25]\n", - "12 [11, 24]\n", - "13 [10, 23]\n", - "14 [9, 22]\n", - "15 [8, 21]\n", - "16 [7, 20]\n", - "17 [6, 19]\n", - "18 [5, 18]\n", - "19 [4, 17]\n", - "20 [3, 16]\n", - "21 [2, 15]\n", - "22 [1, 14]\n", + "11 [14, 1]\n", + "12 [15, 2]\n", + "13 [16, 3]\n", + "14 [17, 4]\n", + "15 [18, 5]\n", + "16 [19, 6]\n", + "17 [20, 7]\n", + "18 [21, 8]\n", + "19 [22, 9]\n", + "20 [23, 10]\n", + "21 [24, 11]\n", + "22 [25, 12]\n", "23 [0, 13]\n", - "24 [25, 12]\n", - "25 [24, 11]\n", - "0 [23, 10]\n" + "24 [1, 14]\n", + "25 [2, 15]\n", + "0 [3, 16]\n" ] } ], "source": [ "for _ in range(27):\n", " wheel_6.advance()\n", - " print(wheel_6.position, wheel_6.peg_positions)" + " print(wheel_6.position, wheel_6.notch_positions)" + ] + }, + { + "cell_type": "code", + "execution_count": 159, + "metadata": {}, + "outputs": [], + "source": [ + "wheel = Wheel(wheel_iii_spec, wheel_iii_notches, position='b', \n", + " ring_setting=3)\n", + "wheel.set_position(12)\n", + "assert(wheel.position == 9)\n", + "assert(16 in wheel.notch_positions)\n", + "assert(wheel.position_l =='l')" + ] + }, + { + "cell_type": "code", + "execution_count": 160, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[16]" + ] + }, + "execution_count": 160, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "wheel.notch_positions" + ] + }, + { + "cell_type": "code", + "execution_count": 161, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'l'" + ] + }, + "execution_count": 161, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "wheel.position_l" ] }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 162, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ - "wheel_3 = Wheel(wheel_iii_spec, wheel_iii_pegs, position='b', ring_setting=1)\n", + "wheel_3 = Wheel(wheel_iii_spec, wheel_iii_notches, position='b', ring_setting=1)\n", "assert(wheel_3.position == 1)\n", - "assert(wheel_3.peg_positions == [20])\n", + "assert(wheel_3.notch_positions == [6])\n", "assert(wheel_3.position_l == 'b')\n", "wheel_3.advance()\n", "assert(wheel_3.position == 2)\n", - "assert(wheel_3.peg_positions == [19])\n", + "assert(wheel_3.notch_positions == [7])\n", "assert(wheel_3.position_l == 'c')" ] }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 163, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[2, 15]" + ] + }, + "execution_count": 163, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "wheel_6 = Wheel(wheel_vi_spec, wheel_vi_notches, position='b', ring_setting=3)\n", + "wheel_6.notch_positions" + ] + }, + { + "cell_type": "code", + "execution_count": 164, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ - "wheel_6 = Wheel(wheel_vi_spec, wheel_vi_pegs, position='b', ring_setting=3)\n", + "wheel_6 = Wheel(wheel_vi_spec, wheel_vi_notches, position='b', ring_setting=3)\n", "assert(cat(wheel_6.forward(l) for l in string.ascii_lowercase) == 'xkqhwpvngzrcfoiaselbtymjdu')\n", "assert(cat(wheel_6.backward(l) for l in string.ascii_lowercase) == 'ptlyrmidoxbswhnfckquzgeavj')\n", "assert(wheel_6.position == 25)\n", - "assert(11 in wheel_6.peg_positions)\n", - "assert(24 in wheel_6.peg_positions)\n", + "assert(2 in wheel_6.notch_positions)\n", + "assert(15 in wheel_6.notch_positions)\n", "assert(wheel_6.position_l == 'b')\n", "\n", "wheel_6.advance()\n", "assert(cat(wheel_6.forward(l) for l in string.ascii_lowercase) == 'jpgvoumfyqbenhzrdkasxlictw')\n", "assert(cat(wheel_6.backward(l) for l in string.ascii_lowercase) == 'skxqlhcnwarvgmebjptyfdzuio')\n", "assert(wheel_6.position == 0)\n", - "assert(10 in wheel_6.peg_positions)\n", - "assert(23 in wheel_6.peg_positions)\n", + "assert(3 in wheel_6.notch_positions)\n", + "assert(16 in wheel_6.notch_positions)\n", "assert(wheel_6.position_l == 'c')\n", "\n", "for _ in range(22): wheel_6.advance()\n", "assert(cat(wheel_6.forward(l) for l in string.ascii_lowercase) == 'mgxantkzsyqjcufirldvhoewbp')\n", "assert(cat(wheel_6.backward(l) for l in string.ascii_lowercase) == 'dymswobuplgraevzkqifntxcjh')\n", "assert(wheel_6.position == 22)\n", - "assert(1 in wheel_6.peg_positions)\n", - "assert(14 in wheel_6.peg_positions)\n", + "assert(25 in wheel_6.notch_positions)\n", + "assert(12 in wheel_6.notch_positions)\n", "assert(wheel_6.position_l == 'y')\n", "\n", "wheel_6.advance()\n", "assert(cat(wheel_6.forward(l) for l in string.ascii_lowercase) == 'fwzmsjyrxpibtehqkcugndvaol')\n", "assert(cat(wheel_6.backward(l) for l in string.ascii_lowercase) == 'xlrvnatokfqzduyjphemswbigc')\n", "assert(wheel_6.position == 23)\n", - "assert(0 in wheel_6.peg_positions)\n", - "assert(13 in wheel_6.peg_positions)\n", + "assert(0 in wheel_6.notch_positions)\n", + "assert(13 in wheel_6.notch_positions)\n", "assert(wheel_6.position_l == 'z')\n", "\n", "wheel_6.advance()\n", "assert(cat(wheel_6.forward(l) for l in string.ascii_lowercase) == 'vylrixqwohasdgpjbtfmcuznke')\n", "assert(cat(wheel_6.backward(l) for l in string.ascii_lowercase) == 'kqumzsnjepyctxiogdlrvahfbw')\n", "assert(wheel_6.position == 24)\n", - "assert(25 in wheel_6.peg_positions)\n", - "assert(12 in wheel_6.peg_positions)\n", + "assert(1 in wheel_6.notch_positions)\n", + "assert(14 in wheel_6.notch_positions)\n", "assert(wheel_6.position_l == 'a')\n", "\n", "wheel_6.advance()\n", "assert(cat(wheel_6.forward(l) for l in string.ascii_lowercase) == 'xkqhwpvngzrcfoiaselbtymjdu')\n", "assert(cat(wheel_6.backward(l) for l in string.ascii_lowercase) == 'ptlyrmidoxbswhnfckquzgeavj')\n", "assert(wheel_6.position == 25)\n", - "assert(24 in wheel_6.peg_positions)\n", - "assert(11 in wheel_6.peg_positions)\n", + "assert(2 in wheel_6.notch_positions)\n", + "assert(15 in wheel_6.notch_positions)\n", "assert(wheel_6.position_l == 'b')\n", "\n", "wheel_6.advance()\n", "assert(cat(wheel_6.forward(l) for l in string.ascii_lowercase) == 'jpgvoumfyqbenhzrdkasxlictw')\n", "assert(cat(wheel_6.backward(l) for l in string.ascii_lowercase) == 'skxqlhcnwarvgmebjptyfdzuio')\n", "assert(wheel_6.position == 0)\n", - "assert(23 in wheel_6.peg_positions)\n", - "assert(10 in wheel_6.peg_positions)\n", + "assert(3 in wheel_6.notch_positions)\n", + "assert(16 in wheel_6.notch_positions)\n", "assert(wheel_6.position_l == 'c')" ] }, { "cell_type": "code", - "execution_count": 39, - "metadata": { - "collapsed": false - }, + "execution_count": 165, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "(0, 'c', [23, 10])" + "(0, 'c', [3, 16])" ] }, - "execution_count": 39, + "execution_count": 165, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "wheel_6.position, wheel_6.position_l, wheel_6.peg_positions" + "wheel_6.position, wheel_6.position_l, wheel_6.notch_positions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## Enigma\n", + "[Top](#top)\n", + "\n", + "This is the full Enigma machine.\n", + "\n", + "It's a collection of the various components defined above. There are three wheels (left, middle, and right), a plugboard, and a reflector.\n", + "\n", + "The `__getattribute__` method returns the state of the machine in friendly form, generally by asking the components to return the relevant attributes." ] }, { "cell_type": "code", - "execution_count": 40, - "metadata": { - "collapsed": true - }, + "execution_count": 167, + "metadata": {}, "outputs": [], "source": [ "class Enigma(object):\n", " def __init__(self, reflector_spec,\n", - " left_wheel_spec, left_wheel_pegs,\n", - " middle_wheel_spec, middle_wheel_pegs,\n", - " right_wheel_spec, right_wheel_pegs,\n", + " left_wheel_spec, left_wheel_notches,\n", + " middle_wheel_spec, middle_wheel_notches,\n", + " right_wheel_spec, right_wheel_notches,\n", " left_ring_setting, middle_ring_setting, right_ring_setting,\n", " plugboard_setting):\n", " self.reflector = Reflector(reflector_spec)\n", - " self.left_wheel = Wheel(left_wheel_spec, left_wheel_pegs, ring_setting=left_ring_setting)\n", - " self.middle_wheel = Wheel(middle_wheel_spec, middle_wheel_pegs, ring_setting=middle_ring_setting)\n", - " self.right_wheel = Wheel(right_wheel_spec, right_wheel_pegs, ring_setting=right_ring_setting)\n", + " self.left_wheel = Wheel(left_wheel_spec, left_wheel_notches, ring_setting=left_ring_setting)\n", + " self.middle_wheel = Wheel(middle_wheel_spec, middle_wheel_notches, ring_setting=middle_ring_setting)\n", + " self.right_wheel = Wheel(right_wheel_spec, right_wheel_notches, ring_setting=right_ring_setting)\n", " self.plugboard = Plugboard(plugboard_setting)\n", " \n", " def __getattribute__(self,name):\n", @@ -1173,74 +1731,166 @@ " return self.left_wheel.position, self.middle_wheel.position, self.right_wheel.position \n", " elif name=='wheel_positions_l':\n", " return self.left_wheel.position_l, self.middle_wheel.position_l, self.right_wheel.position_l \n", - " elif name=='peg_positions':\n", - " return self.left_wheel.peg_positions, self.middle_wheel.peg_positions, self.right_wheel.peg_positions\n", + " elif name=='notch_positions':\n", + " return (self.left_wheel.notch_positions, \n", + " self.middle_wheel.notch_positions, \n", + " self.right_wheel.notch_positions)\n", " else:\n", - " return object.__getattribute__(self, name)\n", - "\n", - " \n", - " def set_wheels(self, left_wheel_position, middle_wheel_position, right_wheel_position):\n", - " self.left_wheel.set_position(left_wheel_position)\n", - " self.middle_wheel.set_position(middle_wheel_position)\n", - " self.right_wheel.set_position(right_wheel_position)\n", - " \n", - " def lookup(self, letter):\n", - " a = self.plugboard.forward(letter)\n", - " b = self.right_wheel.forward(a)\n", - " c = self.middle_wheel.forward(b)\n", - " d = self.left_wheel.forward(c)\n", - " e = self.reflector.forward(d)\n", - " f = self.left_wheel.backward(e)\n", - " g = self.middle_wheel.backward(f)\n", - " h = self.right_wheel.backward(g)\n", - " i = self.plugboard.backward(h)\n", - " return i\n", - " \n", - " def advance(self):\n", - " advance_middle = False\n", - " advance_left = False\n", - " if 0 in self.right_wheel.peg_positions:\n", - " advance_middle = True\n", - " if 0 in self.middle_wheel.peg_positions:\n", - " advance_left = True\n", - " advance_middle = True\n", - " self.right_wheel.advance()\n", - " if advance_middle: self.middle_wheel.advance()\n", - " if advance_left: self.left_wheel.advance()\n", - " \n", - " def encipher_letter(self, letter):\n", - " self.advance()\n", - " return self.lookup(letter)\n", - " \n", - " def encipher(self, message):\n", - " enciphered = ''\n", - " for letter in clean(message):\n", - " enciphered += self.encipher_letter(letter)\n", - " return enciphered" + " return object.__getattribute__(self, name)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Set the wheels to the initial positions. " + ] + }, + { + "cell_type": "code", + "execution_count": 168, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def set_wheels(self, left_wheel_position, middle_wheel_position, right_wheel_position):\n", + " self.left_wheel.set_position(left_wheel_position)\n", + " self.middle_wheel.set_position(middle_wheel_position)\n", + " self.right_wheel.set_position(right_wheel_position)\n", + "\n", + "setattr(Enigma, 'set_wheels', set_wheels)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`lookup` just follows a path through the machine without changing the positions of any parts. It just follows a signal from the input, thorough all the components, to the reflector, back through all the components, to the output." + ] + }, + { + "cell_type": "code", + "execution_count": 169, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def lookup(self, letter):\n", + " a = self.plugboard.forward(letter)\n", + " b = self.right_wheel.forward(a)\n", + " c = self.middle_wheel.forward(b)\n", + " d = self.left_wheel.forward(c)\n", + " e = self.reflector.forward(d)\n", + " f = self.left_wheel.backward(e)\n", + " g = self.middle_wheel.backward(f)\n", + " h = self.right_wheel.backward(g)\n", + " i = self.plugboard.backward(h)\n", + " return i\n", + "\n", + "setattr(Enigma, 'lookup', lookup)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`advance` moves the wheels on one step. The right wheel always advances. If the notch is in the zero position, the wheel also advances the wheel to the left. \n", + "\n", + "It follows the 'double stepping' behaviour of the engima machines." + ] + }, + { + "cell_type": "code", + "execution_count": 170, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def advance(self):\n", + " advance_middle = False\n", + " advance_left = False\n", + " if 0 in self.right_wheel.notch_positions:\n", + " advance_middle = True\n", + " if 0 in self.middle_wheel.notch_positions:\n", + " advance_left = True\n", + " advance_middle = True\n", + " self.right_wheel.advance()\n", + " if advance_middle: self.middle_wheel.advance()\n", + " if advance_left: self.left_wheel.advance()\n", + "\n", + "setattr(Enigma, 'advance', advance) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finally, encipher letters and messages. \n", + "\n", + "Note that the wheels advance _before_ the letter signal is sent through the machine: in the physical machine, the advancing is done by pressing the key on the keyboard. \n", + "\n", + "Also note that the messages are cleaned before use, so letters are converted to lower case and non-letters are removed." + ] + }, + { + "cell_type": "code", + "execution_count": 220, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def encipher_letter(self, letter):\n", + " self.advance()\n", + " return self.lookup(letter)\n", + "\n", + "def encipher(self, message, debug=False):\n", + " enciphered = ''\n", + " for letter in clean(message):\n", + " enciphered += self.encipher_letter(letter)\n", + " if debug:\n", + " print('Wheels now', list(self.wheel_positions_l), 'enciphering {} -> {}'.format(letter, self.lookup(letter)))\n", + " return enciphered\n", + "\n", + "setattr(Enigma, 'encipher_letter', encipher_letter)\n", + "setattr(Enigma, 'encipher', encipher)\n", + "setattr(Enigma, 'decipher', encipher)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## Testing Enigma\n", + "[Top](#top)\n", + "\n", + "Some tests of the Enigma machine." ] }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 172, "metadata": { - "collapsed": false + "collapsed": true }, "outputs": [], "source": [ "enigma = Enigma(reflector_b_spec, \n", - " wheel_i_spec, wheel_i_pegs,\n", - " wheel_ii_spec, wheel_ii_pegs,\n", - " wheel_iii_spec, wheel_iii_pegs,\n", + " wheel_i_spec, wheel_i_notches,\n", + " wheel_ii_spec, wheel_ii_notches,\n", + " wheel_iii_spec, wheel_iii_notches,\n", " 1, 1, 1,\n", " '')" ] }, { "cell_type": "code", - "execution_count": 42, - "metadata": { - "collapsed": false - }, + "execution_count": 173, + "metadata": {}, "outputs": [ { "data": { @@ -1248,7 +1898,7 @@ "'u'" ] }, - "execution_count": 42, + "execution_count": 173, "metadata": {}, "output_type": "execute_result" } @@ -1259,10 +1909,8 @@ }, { "cell_type": "code", - "execution_count": 43, - "metadata": { - "collapsed": false - }, + "execution_count": 174, + "metadata": {}, "outputs": [ { "data": { @@ -1270,7 +1918,7 @@ "'a'" ] }, - "execution_count": 43, + "execution_count": 174, "metadata": {}, "output_type": "execute_result" } @@ -1281,10 +1929,8 @@ }, { "cell_type": "code", - "execution_count": 44, - "metadata": { - "collapsed": false - }, + "execution_count": 175, + "metadata": {}, "outputs": [ { "data": { @@ -1292,7 +1938,7 @@ "'uejobtpzwcnsrkdgvmlfaqiyxh'" ] }, - "execution_count": 44, + "execution_count": 175, "metadata": {}, "output_type": "execute_result" } @@ -1303,9 +1949,39 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 176, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'abcdefghijklmnopqrstuvwxyz'" + ] + }, + "execution_count": 176, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cat(enigma.lookup(enigma.lookup(l)) for l in string.ascii_lowercase)" + ] + }, + { + "cell_type": "code", + "execution_count": 177, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "assert(cat(enigma.lookup(enigma.lookup(l)) for l in string.ascii_lowercase) == string.ascii_lowercase)" + ] + }, + { + "cell_type": "code", + "execution_count": 178, "metadata": { - "collapsed": false, "scrolled": true }, "outputs": [ @@ -1313,50 +1989,58 @@ "name": "stdout", "output_type": "stream", "text": [ - "0 :: a a a ; [16] [4] [21] uejobtpzwcnsrkdgvmlfaqiyxh\n", - "1 :: a a b ; [16] [4] [20] baqmfexihswpdytlcvjozrkgnu\n", - "2 :: a a c ; [16] [4] [19] djralkwpobfeyqihncxzvugsmt\n", - "3 :: a a d ; [16] [4] [18] zlejcuitgdmbkonsvxphfqyrwa\n", - "4 :: a a e ; [16] [4] [17] gcblwtakqzhdosmxiunfryepvj\n", - "5 :: a a f ; [16] [4] [16] osnirgfmdpvuhcajwebxlkqtzy\n", - "6 :: a a g ; [16] [4] [15] wymvnqzjlhoicekuftxrpdasbg\n", - "7 :: a a h ; [16] [4] [14] cjafkdztpbeuormiwnvhlsqyxg\n", - "8 :: a a i ; [16] [4] [13] xijuyslvbczgnmqwotfrdhpaek\n", - "9 :: a a j ; [16] [4] [12] lfzrwbytjisaovmuxdkhpneqgc\n", - "10 :: a a k ; [16] [4] [11] tkezcqynuwbpvhslfxoaimjrgd\n", - "11 :: a a l ; [16] [4] [10] kiwfnduxbsaotelqpvjmgrchzy\n", - "12 :: a a m ; [16] [4] [9] sfkutbpoxycrnmhgwlaedzqijv\n", - "13 :: a a n ; [16] [4] [8] baqwlkhgrsfextpocijnvudmzy\n", - "14 :: a a o ; [16] [4] [7] teofbdzxqkjyrscvimnawpuhlg\n", - "15 :: a a p ; [16] [4] [6] mhypswrbzxqvaondkgeutlfjci\n", - "16 :: a a q ; [16] [4] [5] cpasnrhgkuixzevbyfdwjotlqm\n", - "17 :: a a r ; [16] [4] [4] dlfatcjwygvbnmzrxpueskhqio\n", - "18 :: a a s ; [16] [4] [3] lxymzjuqtfpadsrkhonigwvbce\n", - "19 :: a a t ; [16] [4] [2] puvioztjdhxmlyeawsrgbcqknf\n", - "20 :: a a u ; [16] [4] [1] baigpldqcowfyzjehvtsxrkumn\n", - "21 :: a a v ; [16] [4] [0] mnvfydiwgzsoablrxpkutchqej\n", - "22 :: a b w ; [16] [3] [25] ulfopcykswhbzvderqixanjtgm\n", - "23 :: a b x ; [16] [3] [24] qmwftdyovursbzhxaklejicpgn\n", - "24 :: a b y ; [16] [3] [23] oljmzxrvucybdqasngpwihtfke\n", - "25 :: a b z ; [16] [3] [22] fwevcalzxutgysrqponkjdbimh\n" + "0 :: a a a ; [10] [22] [5] uejobtpzwcnsrkdgvmlfaqiyxh\n", + "1 :: a a b ; [10] [22] [6] baqmfexihswpdytlcvjozrkgnu\n", + "2 :: a a c ; [10] [22] [7] djralkwpobfeyqihncxzvugsmt\n", + "3 :: a a d ; [10] [22] [8] zlejcuitgdmbkonsvxphfqyrwa\n", + "4 :: a a e ; [10] [22] [9] gcblwtakqzhdosmxiunfryepvj\n", + "5 :: a a f ; [10] [22] [10] osnirgfmdpvuhcajwebxlkqtzy\n", + "6 :: a a g ; [10] [22] [11] wymvnqzjlhoicekuftxrpdasbg\n", + "7 :: a a h ; [10] [22] [12] cjafkdztpbeuormiwnvhlsqyxg\n", + "8 :: a a i ; [10] [22] [13] xijuyslvbczgnmqwotfrdhpaek\n", + "9 :: a a j ; [10] [22] [14] lfzrwbytjisaovmuxdkhpneqgc\n", + "10 :: a a k ; [10] [22] [15] tkezcqynuwbpvhslfxoaimjrgd\n", + "11 :: a a l ; [10] [22] [16] kiwfnduxbsaotelqpvjmgrchzy\n", + "12 :: a a m ; [10] [22] [17] sfkutbpoxycrnmhgwlaedzqijv\n", + "13 :: a a n ; [10] [22] [18] baqwlkhgrsfextpocijnvudmzy\n", + "14 :: a a o ; [10] [22] [19] teofbdzxqkjyrscvimnawpuhlg\n", + "15 :: a a p ; [10] [22] [20] mhypswrbzxqvaondkgeutlfjci\n", + "16 :: a a q ; [10] [22] [21] cpasnrhgkuixzevbyfdwjotlqm\n", + "17 :: a a r ; [10] [22] [22] dlfatcjwygvbnmzrxpueskhqio\n", + "18 :: a a s ; [10] [22] [23] lxymzjuqtfpadsrkhonigwvbce\n", + "19 :: a a t ; [10] [22] [24] puvioztjdhxmlyeawsrgbcqknf\n", + "20 :: a a u ; [10] [22] [25] baigpldqcowfyzjehvtsxrkumn\n", + "21 :: a a v ; [10] [22] [0] mnvfydiwgzsoablrxpkutchqej\n", + "22 :: a b w ; [10] [23] [1] ulfopcykswhbzvderqixanjtgm\n", + "23 :: a b x ; [10] [23] [2] qmwftdyovursbzhxaklejicpgn\n", + "24 :: a b y ; [10] [23] [3] oljmzxrvucybdqasngpwihtfke\n", + "25 :: a b z ; [10] [23] [4] fwevcalzxutgysrqponkjdbimh\n" ] } ], "source": [ + "# check the middle wheel turns over\n", "enigma.set_wheels('a', 'a', 'a')\n", "for i in range(26):\n", " print(i, '::', \n", " enigma.left_wheel.position_l, enigma.middle_wheel.position_l, enigma.right_wheel.position_l, ';',\n", - " enigma.left_wheel.peg_positions, enigma.middle_wheel.peg_positions, enigma.right_wheel.peg_positions, \n", + " enigma.left_wheel.notch_positions, enigma.middle_wheel.notch_positions, enigma.right_wheel.notch_positions, \n", " cat(enigma.lookup(l) for l in string.ascii_lowercase))\n", " enigma.advance()" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Formal test of middle wheel turnover" + ] + }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 179, "metadata": { - "collapsed": false, + "collapsed": true, "scrolled": true }, "outputs": [], @@ -1364,45 +2048,51 @@ "enigma.set_wheels('a', 'a', 't')\n", "assert(enigma.wheel_positions == (0, 0, 19))\n", "assert(cat(enigma.wheel_positions_l) == 'aat')\n", - "assert(enigma.peg_positions == ([16], [4], [2]))\n", + "assert(enigma.notch_positions == ([10], [22], [24]))\n", "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'puvioztjdhxmlyeawsrgbcqknf')\n", "\n", "enigma.advance()\n", "assert(enigma.wheel_positions == (0, 0, 20))\n", "assert(cat(enigma.wheel_positions_l) == 'aau')\n", - "assert(enigma.peg_positions == ([16], [4], [1]))\n", + "assert(enigma.notch_positions == ([10], [22], [25]))\n", "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'baigpldqcowfyzjehvtsxrkumn')\n", "\n", "enigma.advance()\n", "assert(enigma.wheel_positions == (0, 0, 21))\n", "assert(cat(enigma.wheel_positions_l) == 'aav')\n", - "assert(enigma.peg_positions == ([16], [4], [0]))\n", + "assert(enigma.notch_positions == ([10], [22], [0]))\n", "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'mnvfydiwgzsoablrxpkutchqej')\n", "\n", "enigma.advance()\n", "assert(enigma.wheel_positions == (0, 1, 22))\n", "assert(cat(enigma.wheel_positions_l) == 'abw')\n", - "assert(enigma.peg_positions == ([16], [3], [25]))\n", + "assert(enigma.notch_positions == ([10], [23], [1]))\n", "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'ulfopcykswhbzvderqixanjtgm')\n", "\n", "enigma.advance()\n", "assert(enigma.wheel_positions == (0, 1, 23))\n", "assert(cat(enigma.wheel_positions_l) == 'abx')\n", - "assert(enigma.peg_positions == ([16], [3], [24]))\n", + "assert(enigma.notch_positions == ([10], [23], [2]))\n", "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'qmwftdyovursbzhxaklejicpgn')\n", "\n", "enigma.advance()\n", "assert(enigma.wheel_positions == (0, 1, 24))\n", "assert(cat(enigma.wheel_positions_l) == 'aby')\n", - "assert(enigma.peg_positions == ([16], [3], [23]))\n", + "assert(enigma.notch_positions == ([10], [23 ], [3]))\n", "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'oljmzxrvucybdqasngpwihtfke')\n" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Test of middle wheel advancing the left wheel, exhibiting the \"double step\" behaviour." + ] + }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 180, "metadata": { - "collapsed": false, "scrolled": true }, "outputs": [ @@ -1410,7 +2100,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "(1, 5, 24) ('b', 'f', 'y') ([15], [25], [23]) baknstqzrmcxjdvygiefwoulph\n" + "(1, 5, 24) ('b', 'f', 'y') ([11], [1], [3]) baknstqzrmcxjdvygiefwoulph\n" ] } ], @@ -1418,49 +2108,47 @@ "enigma.set_wheels('a', 'd', 't')\n", "assert(enigma.wheel_positions == (0, 3, 19))\n", "assert(cat(enigma.wheel_positions_l) == 'adt')\n", - "assert(enigma.peg_positions == ([16], [1], [2]))\n", + "assert(enigma.notch_positions == ([10], [25], [24]))\n", "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'zcbpqxwsjiuonmldethrkygfva')\n", "\n", "enigma.advance()\n", "assert(enigma.wheel_positions == (0, 3, 20))\n", "assert(cat(enigma.wheel_positions_l) == 'adu')\n", - "assert(enigma.peg_positions == ([16], [1], [1]))\n", + "assert(enigma.notch_positions == ([10], [25], [25]))\n", "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'ehprawjbngotxikcsdqlzyfmvu')\n", "\n", "enigma.advance()\n", "assert(enigma.wheel_positions == (0, 3, 21))\n", "assert(cat(enigma.wheel_positions_l) == 'adv')\n", - "assert(enigma.peg_positions == ([16], [1], [0]))\n", + "assert(enigma.notch_positions == ([10], [25], [0]))\n", "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'eqzxarpihmnvjkwgbfuyslodtc')\n", "\n", "enigma.advance()\n", "assert(enigma.wheel_positions == (0, 4, 22))\n", "assert(cat(enigma.wheel_positions_l) == 'aew')\n", - "assert(enigma.peg_positions == ([16], [0], [25]))\n", + "assert(enigma.notch_positions == ([10], [0], [1]))\n", "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'qedcbtpluzmhkongavwfirsyxj')\n", "\n", "enigma.advance()\n", "assert(enigma.wheel_positions == (1, 5, 23))\n", "assert(cat(enigma.wheel_positions_l) == 'bfx')\n", - "assert(enigma.peg_positions == ([15], [25], [24]))\n", + "assert(enigma.notch_positions == ([11], [1], [2]))\n", "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'iwuedhsfazqxytvrkpgncoblmj')\n", "\n", "enigma.advance()\n", "assert(enigma.wheel_positions == (1, 5, 24))\n", "assert(cat(enigma.wheel_positions_l) == 'bfy')\n", - "assert(enigma.peg_positions == ([15], [25], [23]))\n", + "assert(enigma.notch_positions == ([11], [1], [3]))\n", "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'baknstqzrmcxjdvygiefwoulph')\n", "\n", - "print(enigma.wheel_positions, enigma.wheel_positions_l, enigma.peg_positions, \n", + "print(enigma.wheel_positions, enigma.wheel_positions_l, enigma.notch_positions, \n", " cat(enigma.lookup(l) for l in string.ascii_lowercase))\n" ] }, { "cell_type": "code", - "execution_count": 48, - "metadata": { - "collapsed": false - }, + "execution_count": 181, + "metadata": {}, "outputs": [ { "data": { @@ -1468,7 +2156,7 @@ "'olpfhnvflyn'" ] }, - "execution_count": 48, + "execution_count": 181, "metadata": {}, "output_type": "execute_result" } @@ -1482,10 +2170,8 @@ }, { "cell_type": "code", - "execution_count": 49, - "metadata": { - "collapsed": false - }, + "execution_count": 182, + "metadata": {}, "outputs": [ { "data": { @@ -1493,7 +2179,7 @@ "'lawnjgpwjik'" ] }, - "execution_count": 49, + "execution_count": 182, "metadata": {}, "output_type": "execute_result" } @@ -1507,192 +2193,188 @@ }, { "cell_type": "code", - "execution_count": 50, - "metadata": { - "collapsed": false - }, + "execution_count": 183, + "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ + "enigma.advance()\n", + "assert(enigma.wheel_positions == (0, 3, 20))\n", + "assert(cat(enigma.wheel_positions_l) == 'adu')\n", + "assert(enigma.notch_positions == ([10], [25], [25]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'ehprawjbngotxikcsdqlzyfmvu')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (0, 3, 21))\n", + "assert(cat(enigma.wheel_positions_l) == 'adv')\n", + "assert(enigma.notch_positions == ([10], [25], [0]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'eqzxarpihmnvjkwgbfuyslodtc')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (0, 4, 22))\n", + "assert(cat(enigma.wheel_positions_l) == 'aew')\n", + "assert(enigma.notch_positions == ([10], [0], [1]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'qedcbtpluzmhkongavwfirsyxj')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 5, 23))\n", + "assert(cat(enigma.wheel_positions_l) == 'bfx')\n", + "assert(enigma.notch_positions == ([11], [1], [2]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'iwuedhsfazqxytvrkpgncoblmj')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 5, 24))\n", + "assert(cat(enigma.wheel_positions_l) == 'bfy')\n", + "assert(enigma.notch_positions == ([11], [1], [3]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'baknstqzrmcxjdvygiefwoulph')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 5, 25))\n", + "assert(cat(enigma.wheel_positions_l) == 'bfz')\n", + "assert(enigma.notch_positions == ([11], [1], [4]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'mudcgteyjiwravxzslqfbnkohp')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 5, 0))\n", + "assert(cat(enigma.wheel_positions_l) == 'bfa')\n", + "assert(enigma.notch_positions == ([11], [1], [5]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'gjkuotarmbcziwesvhpfdqnyxl')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 5, 1))\n", + "assert(cat(enigma.wheel_positions_l) == 'bfb')\n", + "assert(enigma.notch_positions == ([11], [1], [6]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'fcbmpaqihxytdrvegnwlzosjku')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 5, 2))\n", + "assert(cat(enigma.wheel_positions_l) == 'bfc')\n", + "assert(enigma.notch_positions == ([11], [1], [7]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'jktrlpmywabegzqfodxcvuishn')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 5, 3))\n", + "assert(cat(enigma.wheel_positions_l) == 'bfd')\n", + "assert(enigma.notch_positions == ([11], [1], [8]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'baetclivgurfzqponkxdjhyswm')\n", + "\n", + "enigma.advance()\n", + "assert(enigma.wheel_positions == (1, 5, 4))\n", + "assert(cat(enigma.wheel_positions_l) == 'bfe')\n", + "assert(enigma.notch_positions == ([11], [1], [9]))\n", + "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'wvjlkpzxtcedqsyfmunirbahog')\n", + "\n", "enigma.advance()\n", "assert(enigma.wheel_positions == (1, 5, 5))\n", "assert(cat(enigma.wheel_positions_l) == 'bff')\n", - "assert(enigma.peg_positions == ([15], [25], [16]))\n", + "assert(enigma.notch_positions == ([11], [1], [10]))\n", "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'zpqiogfsdlmjkyebcvhxwrutna')\n", "\n", "enigma.advance()\n", "assert(enigma.wheel_positions == (1, 5, 6))\n", "assert(cat(enigma.wheel_positions_l) == 'bfg')\n", - "assert(enigma.peg_positions == ([15], [25], [15]))\n", + "assert(enigma.notch_positions == ([11], [1], [11]))\n", "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'fjmnwayslbxicdpouthrqzekgv')\n", "\n", "enigma.advance()\n", "assert(enigma.wheel_positions == (1, 5, 7))\n", "assert(cat(enigma.wheel_positions_l) == 'bfh')\n", - "assert(enigma.peg_positions == ([15], [25], [14]))\n", + "assert(enigma.notch_positions == ([11], [1], [12]))\n", "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'csafzdyloxuhnmitwvbpkrqjge')\n", "\n", "enigma.advance()\n", "assert(enigma.wheel_positions == (1, 5, 8))\n", "assert(cat(enigma.wheel_positions_l) == 'bfi')\n", - "assert(enigma.peg_positions == ([15], [25], [13]))\n", + "assert(enigma.notch_positions == ([11], [1], [13]))\n", "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'kihyvulcbtagwrqzonxjfemsdp')\n", "\n", "enigma.advance()\n", "assert(enigma.wheel_positions == (1, 5, 9))\n", "assert(cat(enigma.wheel_positions_l) == 'bfj')\n", - "assert(enigma.peg_positions == ([15], [25], [12]))\n", + "assert(enigma.notch_positions == ([11], [1], [14]))\n", "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'pgzrytbksqhwxvuajdifonlmec')\n", "\n", "enigma.advance()\n", "assert(enigma.wheel_positions == (1, 5, 10))\n", "assert(cat(enigma.wheel_positions_l) == 'bfk')\n", - "assert(enigma.peg_positions == ([15], [25], [11]))\n", + "assert(enigma.notch_positions == ([11], [1], [15]))\n", "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'fkirsazncwbvyhpoudexqljtmg')\n", "\n", "enigma.advance()\n", "assert(enigma.wheel_positions == (1, 5, 11))\n", "assert(cat(enigma.wheel_positions_l) == 'bfl')\n", - "assert(enigma.peg_positions == ([15], [25], [10]))\n", + "assert(enigma.notch_positions == ([11], [1], [16]))\n", "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'mhkronubsvctafeqpdilgjxwzy')\n", "\n", "enigma.advance()\n", "assert(enigma.wheel_positions == (1, 5, 12))\n", "assert(cat(enigma.wheel_positions_l) == 'bfm')\n", - "assert(enigma.peg_positions == ([15], [25], [9]))\n", + "assert(enigma.notch_positions == ([11], [1], [17]))\n", "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'gnkuoxarzycmlbetvhwpdqsfji')\n", "\n", "enigma.advance()\n", "assert(enigma.wheel_positions == (1, 5, 13))\n", "assert(cat(enigma.wheel_positions_l) == 'bfn')\n", - "assert(enigma.peg_positions == ([15], [25], [8]))\n", + "assert(enigma.notch_positions == ([11], [1], [18]))\n", "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'bainslqkcxhfudpogtermwvjzy')\n", "\n", "enigma.advance()\n", "assert(enigma.wheel_positions == (1, 5, 14))\n", "assert(cat(enigma.wheel_positions_l) == 'bfo')\n", - "assert(enigma.peg_positions == ([15], [25], [7]))\n", + "assert(enigma.notch_positions == ([11], [1], [19]))\n", "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'xemfbdnwjitycgzusvqkprhalo')\n", "\n", "enigma.advance()\n", "assert(enigma.wheel_positions == (1, 5, 15))\n", "assert(cat(enigma.wheel_positions_l) == 'bfp')\n", - "assert(enigma.peg_positions == ([15], [25], [6]))\n", + "assert(enigma.notch_positions == ([11], [1], [20]))\n", "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'qixksmhgbtdvfonrapejwluczy')\n", "\n", "enigma.advance()\n", "assert(enigma.wheel_positions == (1, 5, 16))\n", "assert(cat(enigma.wheel_positions_l) == 'bfq')\n", - "assert(enigma.peg_positions == ([15], [25], [5]))\n", + "assert(enigma.notch_positions == ([11], [1], [21]))\n", "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'cgaulmbskwiefrtzynhodxjvqp')\n", "\n", "enigma.advance()\n", "assert(enigma.wheel_positions == (1, 5, 17))\n", "assert(cat(enigma.wheel_positions_l) == 'bfr')\n", - "assert(enigma.peg_positions == ([15], [25], [4]))\n", + "assert(enigma.notch_positions == ([11], [1], [22]))\n", "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'iwqfldszaxvenmyrcpgutkbjoh')\n", "\n", "enigma.advance()\n", "assert(enigma.wheel_positions == (1, 5, 18))\n", "assert(cat(enigma.wheel_positions_l) == 'bfs')\n", - "assert(enigma.peg_positions == ([15], [25], [3]))\n", + "assert(enigma.notch_positions == ([11], [1], [23]))\n", "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'vxykrjilgfdhqtusmepnoazbcw')\n", "\n", "enigma.advance()\n", "assert(enigma.wheel_positions == (1, 5, 19))\n", "assert(cat(enigma.wheel_positions_l) == 'bft')\n", - "assert(enigma.peg_positions == ([15], [25], [2]))\n", + "assert(enigma.notch_positions == ([11], [1], [24]))\n", "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'ieysbvkjahgmlpxnwtdrzfqocu')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (1, 5, 20))\n", - "assert(cat(enigma.wheel_positions_l) == 'bfu')\n", - "assert(enigma.peg_positions == ([15], [25], [1]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'baihkjvdcfepywsltxoqzgnrmu')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (1, 5, 21))\n", - "assert(cat(enigma.wheel_positions_l) == 'bfv')\n", - "assert(enigma.peg_positions == ([15], [25], [0]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'bayjtrilgdshvzuwxfkeompqcn')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (1, 6, 22))\n", - "assert(cat(enigma.wheel_positions_l) == 'bgw')\n", - "assert(enigma.peg_positions == ([15], [24], [25]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'rszqohpfxyutvwegdablkmnijc')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (1, 6, 23))\n", - "assert(cat(enigma.wheel_positions_l) == 'bgx')\n", - "assert(enigma.peg_positions == ([15], [24], [24]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'nfoxhbzeyrwqpacmljtsvukdig')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (1, 6, 24))\n", - "assert(cat(enigma.wheel_positions_l) == 'bgy')\n", - "assert(enigma.peg_positions == ([15], [24], [23]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'czaogmeihtuqfsdxlwnjkyrpvb')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (1, 6, 25))\n", - "assert(cat(enigma.wheel_positions_l) == 'bgz')\n", - "assert(enigma.peg_positions == ([15], [24], [22]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'omwgysdjkhizbxarupfvqtcnel')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (1, 6, 0))\n", - "assert(cat(enigma.wheel_positions_l) == 'bga')\n", - "assert(enigma.peg_positions == ([15], [24], [21]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'cxafmdrzoqutepinjgvlksybwh')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (1, 6, 1))\n", - "assert(cat(enigma.wheel_positions_l) == 'bgb')\n", - "assert(enigma.peg_positions == ([15], [24], [20]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'jymvnrxkoahwceiuzftspdlgbq')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (1, 6, 2))\n", - "assert(cat(enigma.wheel_positions_l) == 'bgc')\n", - "assert(enigma.peg_positions == ([15], [24], [19]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'uzlyiqwrestcnmxvfhjkapgodb')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (1, 6, 3))\n", - "assert(cat(enigma.wheel_positions_l) == 'bgd')\n", - "assert(enigma.peg_positions == ([15], [24], [18]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'veosbuhgpzqynmcikwdxfartlj')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (1, 6, 4))\n", - "assert(cat(enigma.wheel_positions_l) == 'bge')\n", - "assert(enigma.peg_positions == ([15], [24], [17]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'ydhbmtrclxsiezpougkfqwvjan')\n", "\n" ] } ], "source": [ - "\n", + "enigma.set_wheels('a', 'd', 't')\n", "for i in range(26):\n", " enigma.advance()\n", " print('enigma.advance()')\n", " print(\"assert(enigma.wheel_positions == {})\".format(enigma.wheel_positions))\n", " print(\"assert(cat(enigma.wheel_positions_l) == '{}')\".format(cat(enigma.wheel_positions_l)))\n", - " print(\"assert(enigma.peg_positions == {})\".format(enigma.peg_positions))\n", + " print(\"assert(enigma.notch_positions == {})\".format(enigma.notch_positions))\n", " print(\"assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == '{}')\".format(cat(enigma.lookup(l) for l in string.ascii_lowercase)))\n", " print()" ] }, { "cell_type": "code", - "execution_count": 51, - "metadata": { - "collapsed": false - }, + "execution_count": 184, + "metadata": {}, "outputs": [ { "data": { @@ -1700,7 +2382,7 @@ "'bahxvfrpdc'" ] }, - "execution_count": 51, + "execution_count": 184, "metadata": {}, "output_type": "execute_result" } @@ -1714,10 +2396,8 @@ }, { "cell_type": "code", - "execution_count": 52, - "metadata": { - "collapsed": false - }, + "execution_count": 185, + "metadata": {}, "outputs": [ { "data": { @@ -1725,7 +2405,7 @@ "'kvmmwrlqlqsqpeugjrcxzwpfyiyybwloewrouvkpoztceuwtfjzqwpbqldttsr'" ] }, - "execution_count": 52, + "execution_count": 185, "metadata": {}, "output_type": "execute_result" } @@ -1742,10 +2422,8 @@ }, { "cell_type": "code", - "execution_count": 53, - "metadata": { - "collapsed": false - }, + "execution_count": 186, + "metadata": {}, "outputs": [ { "data": { @@ -1753,7 +2431,7 @@ "'c'" ] }, - "execution_count": 53, + "execution_count": 186, "metadata": {}, "output_type": "execute_result" } @@ -1764,7 +2442,7 @@ }, { "cell_type": "code", - "execution_count": 54, + "execution_count": 187, "metadata": { "collapsed": true }, @@ -1774,455 +2452,1051 @@ "# Enigma simulation settings are \n", "# http://enigma.louisedade.co.uk/enigma.html?m3;b;b153;AFTX;AJFE;AU-BG-EY-FP-HL-IN-JZ-OS-QR-TX\n", "w_enigma = Enigma(reflector_b_spec, \n", - " wheel_i_spec, wheel_i_pegs,\n", - " wheel_v_spec, wheel_v_pegs,\n", - " wheel_iii_spec, wheel_iii_pegs,\n", + " wheel_i_spec, wheel_i_notches,\n", + " wheel_v_spec, wheel_v_notches,\n", + " wheel_iii_spec, wheel_iii_notches,\n", " 6, 20, 24,\n", " 'ua pf rq so ni ey bg hl tx zj')" ] }, { "cell_type": "code", - "execution_count": 55, + "execution_count": 188, "metadata": { "collapsed": true }, "outputs": [], "source": [ - "# Setting sheet line 31 from http://www.codesandciphers.org.uk/enigma/enigma3.htm\n", - "# Enigma simulation settings are \n", - "# http://enigma.louisedade.co.uk/enigma.html?m3;b;b153;AFTX;AJFE;AU-BG-EY-FP-HL-IN-JZ-OS-QR-TX\n", - "enigma = Enigma(reflector_b_spec, \n", - " wheel_i_spec, wheel_i_pegs,\n", - " wheel_v_spec, wheel_v_pegs,\n", - " wheel_iii_spec, wheel_iii_pegs,\n", - " 6, 20, 24,\n", - " 'ua pf rq so ni ey bg hl tx zj')" + "# # Setting sheet line 31 from http://www.codesandciphers.org.uk/enigma/enigma3.htm\n", + "# # Enigma simulation settings are \n", + "# # http://enigma.louisedade.co.uk/enigma.html?m3;b;b153;AFTX;AJFE;AU-BG-EY-FP-HL-IN-JZ-OS-QR-TX\n", + "# enigma = Enigma(reflector_b_spec, \n", + "# wheel_i_spec, wheel_i_notches,\n", + "# wheel_v_spec, wheel_v_notches,\n", + "# wheel_iii_spec, wheel_iii_notches,\n", + "# 6, 20, 24,\n", + "# 'ua pf rq so ni ey bg hl tx zj')" ] }, { "cell_type": "code", - "execution_count": 56, + "execution_count": 189, "metadata": { "collapsed": true }, "outputs": [], "source": [ - "enigma.set_wheels('j', 'e', 'u')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (4, 11, 24))\n", - "assert(cat(enigma.wheel_positions_l) == 'jev')\n", - "assert(enigma.peg_positions == ([7], [21], [0]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'mvqjlyowkdieasgzcunxrbhtfp')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (4, 12, 25))\n", - "assert(cat(enigma.wheel_positions_l) == 'jfw')\n", - "assert(enigma.peg_positions == ([7], [20], [25]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'sjolzuyvrbwdpxcmtiaqfhknge')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (4, 12, 0))\n", - "assert(cat(enigma.wheel_positions_l) == 'jfx')\n", - "assert(enigma.peg_positions == ([7], [20], [24]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'qrxedkoywufmlvgsabpzjnicht')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (4, 12, 1))\n", - "assert(cat(enigma.wheel_positions_l) == 'jfy')\n", - "assert(enigma.peg_positions == ([7], [20], [23]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'hpsukliagqefwvtbjxcodnmrzy')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (4, 12, 2))\n", - "assert(cat(enigma.wheel_positions_l) == 'jfz')\n", - "assert(enigma.peg_positions == ([7], [20], [22]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'zevnbpyqowrtxdifhkulscjmga')\n" + "w_enigma.set_wheels('j', 'e', 'u')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (4, 11, 24))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'jev')\n", + "assert(w_enigma.notch_positions == ([19], [5], [0]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'mvqjlyowkdieasgzcunxrbhtfp')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (4, 12, 25))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'jfw')\n", + "assert(w_enigma.notch_positions == ([19], [6], [1]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'sjolzuyvrbwdpxcmtiaqfhknge')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (4, 12, 0))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'jfx')\n", + "assert(w_enigma.notch_positions == ([19], [6], [2]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'qrxedkoywufmlvgsabpzjnicht')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (4, 12, 1))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'jfy')\n", + "assert(w_enigma.notch_positions == ([19], [6], [3]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'hpsukliagqefwvtbjxcodnmrzy')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (4, 12, 2))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'jfz')\n", + "assert(w_enigma.notch_positions == ([19], [6], [4]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'zevnbpyqowrtxdifhkulscjmga')\n" ] }, { "cell_type": "code", - "execution_count": 57, + "execution_count": 190, "metadata": { "collapsed": true }, "outputs": [], "source": [ - "enigma.set_wheels('i', 'd', 'z')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 3))\n", - "assert(cat(enigma.wheel_positions_l) == 'ida')\n", - "assert(enigma.peg_positions == ([8], [22], [21]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'ikhpqrvcambzjondefwyxgsutl')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 4))\n", - "assert(cat(enigma.wheel_positions_l) == 'idb')\n", - "assert(enigma.peg_positions == ([8], [22], [20]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'cdabskhgzwfmlqvunyexpojtri')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 5))\n", - "assert(cat(enigma.wheel_positions_l) == 'idc')\n", - "assert(enigma.peg_positions == ([8], [22], [19]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'pcbwiqhgemyvjsuaftnroldzkx')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 6))\n", - "assert(cat(enigma.wheel_positions_l) == 'idd')\n", - "assert(enigma.peg_positions == ([8], [22], [18]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'xcbfvdnouptmlghjzwykierasq')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 7))\n", - "assert(cat(enigma.wheel_positions_l) == 'ide')\n", - "assert(enigma.peg_positions == ([8], [22], [17]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'xfvglbdynuseriwqpmkzjcoaht')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 8))\n", - "assert(cat(enigma.wheel_positions_l) == 'idf')\n", - "assert(enigma.peg_positions == ([8], [22], [16]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'tfpqlbouynsewjgcdxkahzmriv')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 9))\n", - "assert(cat(enigma.wheel_positions_l) == 'idg')\n", - "assert(enigma.peg_positions == ([8], [22], [15]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'cjaunvlwtbygzexrspqidfhokm')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 10))\n", - "assert(cat(enigma.wheel_positions_l) == 'idh')\n", - "assert(enigma.peg_positions == ([8], [22], [14]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'yltxkrqvowebzpingfucshjdam')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 11))\n", - "assert(cat(enigma.wheel_positions_l) == 'idi')\n", - "assert(enigma.peg_positions == ([8], [22], [13]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'myktluzrnxceaiqsohpdfwvjbg')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 12))\n", - "assert(cat(enigma.wheel_positions_l) == 'idj')\n", - "assert(enigma.peg_positions == ([8], [22], [12]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'pynjrmiugdqxfcvakewzhoslbt')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 13))\n", - "assert(cat(enigma.wheel_positions_l) == 'idk')\n", - "assert(enigma.peg_positions == ([8], [22], [11]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'mwvedyplnoxhaijgrqtszcbkfu')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 14))\n", - "assert(cat(enigma.wheel_positions_l) == 'idl')\n", - "assert(enigma.peg_positions == ([8], [22], [10]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'qcbrfeutvoxpnmjladzhgiykws')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 15))\n", - "assert(cat(enigma.wheel_positions_l) == 'idm')\n", - "assert(enigma.peg_positions == ([8], [22], [9]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'dnoahryetsmukbcvwfjilpqzgx')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 16))\n", - "assert(cat(enigma.wheel_positions_l) == 'idn')\n", - "assert(enigma.peg_positions == ([8], [22], [8]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'nidcfehgbqsovalyjzkxwmutpr')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 17))\n", - "assert(cat(enigma.wheel_positions_l) == 'ido')\n", - "assert(enigma.peg_positions == ([8], [22], [7]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'joifxdulcarhzpbntkwqgysevm')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 18))\n", - "assert(cat(enigma.wheel_positions_l) == 'idp')\n", - "assert(enigma.peg_positions == ([8], [22], [6]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'ptnlsxvozmwdjchayuebrgkfqi')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 19))\n", - "assert(cat(enigma.wheel_positions_l) == 'idq')\n", - "assert(enigma.peg_positions == ([8], [22], [5]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'slwopzqnmxybihdeguavrtcjkf')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 20))\n", - "assert(cat(enigma.wheel_positions_l) == 'idr')\n", - "assert(enigma.peg_positions == ([8], [22], [4]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'hcbedwlamzogixkytsrqvufnpj')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 21))\n", - "assert(cat(enigma.wheel_positions_l) == 'ids')\n", - "assert(enigma.peg_positions == ([8], [22], [3]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'odxbjwzrmelkisavuhnyqpfctg')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 22))\n", - "assert(cat(enigma.wheel_positions_l) == 'idt')\n", - "assert(enigma.peg_positions == ([8], [22], [2]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'udgbfeclrwnhxksvtioqapjmzy')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 23))\n", - "assert(cat(enigma.wheel_positions_l) == 'idu')\n", - "assert(enigma.peg_positions == ([8], [22], [1]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'nrdczqxmowvshaiufblypkjgte')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 24))\n", - "assert(cat(enigma.wheel_positions_l) == 'idv')\n", - "assert(enigma.peg_positions == ([8], [22], [0]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'hkifjdoacebqtzgulyvmpsxwrn')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 11, 25))\n", - "assert(cat(enigma.wheel_positions_l) == 'iew')\n", - "assert(enigma.peg_positions == ([8], [21], [25]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'yptzuhofqvnmlkgbixwcejsrad')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 11, 0))\n", - "assert(cat(enigma.wheel_positions_l) == 'iex')\n", - "assert(enigma.peg_positions == ([8], [21], [24]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'vkdcwhqfjibzsptngumoraeyxl')\n", - "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 11, 1))\n", - "assert(cat(enigma.wheel_positions_l) == 'iey')\n", - "assert(enigma.peg_positions == ([8], [21], [23]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'wenpbqrouxlkychdfgzvitajms')\n" + "w_enigma.set_wheels('i', 'd', 'z')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 3))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'ida')\n", + "assert(w_enigma.notch_positions == ([18], [4], [5]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'ikhpqrvcambzjondefwyxgsutl')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 4))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idb')\n", + "assert(w_enigma.notch_positions == ([18], [4], [6]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'cdabskhgzwfmlqvunyexpojtri')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 5))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idc')\n", + "assert(w_enigma.notch_positions == ([18], [4], [7]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'pcbwiqhgemyvjsuaftnroldzkx')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 6))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idd')\n", + "assert(w_enigma.notch_positions == ([18], [4], [8]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'xcbfvdnouptmlghjzwykierasq')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 7))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'ide')\n", + "assert(w_enigma.notch_positions == ([18], [4], [9]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'xfvglbdynuseriwqpmkzjcoaht')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 8))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idf')\n", + "assert(w_enigma.notch_positions == ([18], [4], [10]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'tfpqlbouynsewjgcdxkahzmriv')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 9))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idg')\n", + "assert(w_enigma.notch_positions == ([18], [4], [11]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'cjaunvlwtbygzexrspqidfhokm')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 10))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idh')\n", + "assert(w_enigma.notch_positions == ([18], [4], [12]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'yltxkrqvowebzpingfucshjdam')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 11))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idi')\n", + "assert(w_enigma.notch_positions == ([18], [4], [13]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'myktluzrnxceaiqsohpdfwvjbg')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 12))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idj')\n", + "assert(w_enigma.notch_positions == ([18], [4], [14]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'pynjrmiugdqxfcvakewzhoslbt')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 13))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idk')\n", + "assert(w_enigma.notch_positions == ([18], [4], [15]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'mwvedyplnoxhaijgrqtszcbkfu')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 14))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idl')\n", + "assert(w_enigma.notch_positions == ([18], [4], [16]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'qcbrfeutvoxpnmjladzhgiykws')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 15))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idm')\n", + "assert(w_enigma.notch_positions == ([18], [4], [17]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'dnoahryetsmukbcvwfjilpqzgx')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 16))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idn')\n", + "assert(w_enigma.notch_positions == ([18], [4], [18]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'nidcfehgbqsovalyjzkxwmutpr')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 17))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'ido')\n", + "assert(w_enigma.notch_positions == ([18], [4], [19]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'joifxdulcarhzpbntkwqgysevm')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 18))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idp')\n", + "assert(w_enigma.notch_positions == ([18], [4], [20]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'ptnlsxvozmwdjchayuebrgkfqi')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 19))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idq')\n", + "assert(w_enigma.notch_positions == ([18], [4], [21]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'slwopzqnmxybihdeguavrtcjkf')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 20))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idr')\n", + "assert(w_enigma.notch_positions == ([18], [4], [22]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'hcbedwlamzogixkytsrqvufnpj')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 21))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'ids')\n", + "assert(w_enigma.notch_positions == ([18], [4], [23]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'odxbjwzrmelkisavuhnyqpfctg')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 22))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idt')\n", + "assert(w_enigma.notch_positions == ([18], [4], [24]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'udgbfeclrwnhxksvtioqapjmzy')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 23))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idu')\n", + "assert(w_enigma.notch_positions == ([18], [4], [25]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'nrdczqxmowvshaiufblypkjgte')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 24))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idv')\n", + "assert(w_enigma.notch_positions == ([18], [4], [0]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'hkifjdoacebqtzgulyvmpsxwrn')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 11, 25))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'iew')\n", + "assert(w_enigma.notch_positions == ([18], [5], [1]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'yptzuhofqvnmlkgbixwcejsrad')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 11, 0))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'iex')\n", + "assert(w_enigma.notch_positions == ([18], [5], [2]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'vkdcwhqfjibzsptngumoraeyxl')\n", + "\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 11, 1))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'iey')\n", + "assert(w_enigma.notch_positions == ([18], [5], [3]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'wenpbqrouxlkychdfgzvitajms')\n" ] }, { "cell_type": "code", - "execution_count": 58, - "metadata": { - "collapsed": false - }, + "execution_count": 191, + "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "('verylongtestmessagewithanextrabitofmessageforgoodmeasure',\n", - " (3, 12, 6),\n", - " ('i', 'f', 'd'),\n", - " ([8], [20], [18]),\n", - " 'urygzpdmxtwshqvfnbljaokice')" + "([18], [5], [3])" ] }, - "execution_count": 58, + "execution_count": 191, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "enigma.set_wheels('i', 'd', 'z')\n", - "ct = enigma.encipher('verylongtestmessagewithanextrabitofmessageforgoodmeasure')\n", - "assert(ct == 'gstsegeqdrthkfwesljjomfvcqwcfspxpfqqmewvddybarzwubxtpejz')\n", - "assert(enigma.wheel_positions == (3, 12, 6))\n", - "assert(cat(enigma.wheel_positions_l) == 'ifd')\n", - "assert(enigma.peg_positions == ([8], [20], [18]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'urygzpdmxtwshqvfnbljaokice')\n", + "w_enigma.notch_positions" + ] + }, + { + "cell_type": "code", + "execution_count": 192, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('verylongtestmessagewithanextrabitofmessageforgoodmeasure',\n", + " (3, 12, 6),\n", + " ('i', 'f', 'd'),\n", + " ([18], [6], [8]),\n", + " 'urygzpdmxtwshqvfnbljaokice')" + ] + }, + "execution_count": 192, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "w_enigma.set_wheels('i', 'd', 'z')\n", + "ct = w_enigma.encipher('verylongtestmessagewithanextrabitofmessageforgoodmeasure')\n", + "assert(ct == 'gstsegeqdrthkfwesljjomfvcqwcfspxpfqqmewvddybarzwubxtpejz')\n", + "assert(w_enigma.wheel_positions == (3, 12, 6))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'ifd')\n", + "assert(w_enigma.notch_positions == ([18], [6], [8]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'urygzpdmxtwshqvfnbljaokice')\n", "\n", - "enigma.set_wheels('i', 'd', 'z')\n", - "pt = enigma.encipher('gstsegeqdrthkfwesljjomfvcqwcfspxpfqqmewvddybarzwubxtpejz')\n", + "w_enigma.set_wheels('i', 'd', 'z')\n", + "pt = w_enigma.encipher('gstsegeqdrthkfwesljjomfvcqwcfspxpfqqmewvddybarzwubxtpejz')\n", "assert(pt == 'verylongtestmessagewithanextrabitofmessageforgoodmeasure')\n", "\n", - "pt, enigma.wheel_positions, enigma.wheel_positions_l, enigma.peg_positions, cat(enigma.lookup(l) for l in string.ascii_lowercase)" + "pt, w_enigma.wheel_positions, w_enigma.wheel_positions_l, w_enigma.notch_positions, cat(w_enigma.lookup(l) for l in string.ascii_lowercase)" ] }, { "cell_type": "code", - "execution_count": 59, - "metadata": { - "collapsed": false - }, + "execution_count": 193, + "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 3))\n", - "assert(cat(enigma.wheel_positions_l) == 'ida')\n", - "assert(enigma.peg_positions == ([8], [22], [21]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'ikhpqrvcambzjondefwyxgsutl')\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 3))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'ida')\n", + "assert(w_enigma.notch_positions == ([18], [4], [5]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'ikhpqrvcambzjondefwyxgsutl')\n", "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 4))\n", - "assert(cat(enigma.wheel_positions_l) == 'idb')\n", - "assert(enigma.peg_positions == ([8], [22], [20]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'cdabskhgzwfmlqvunyexpojtri')\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 4))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idb')\n", + "assert(w_enigma.notch_positions == ([18], [4], [6]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'cdabskhgzwfmlqvunyexpojtri')\n", "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 5))\n", - "assert(cat(enigma.wheel_positions_l) == 'idc')\n", - "assert(enigma.peg_positions == ([8], [22], [19]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'pcbwiqhgemyvjsuaftnroldzkx')\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 5))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idc')\n", + "assert(w_enigma.notch_positions == ([18], [4], [7]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'pcbwiqhgemyvjsuaftnroldzkx')\n", "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 6))\n", - "assert(cat(enigma.wheel_positions_l) == 'idd')\n", - "assert(enigma.peg_positions == ([8], [22], [18]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'xcbfvdnouptmlghjzwykierasq')\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 6))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idd')\n", + "assert(w_enigma.notch_positions == ([18], [4], [8]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'xcbfvdnouptmlghjzwykierasq')\n", "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 7))\n", - "assert(cat(enigma.wheel_positions_l) == 'ide')\n", - "assert(enigma.peg_positions == ([8], [22], [17]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'xfvglbdynuseriwqpmkzjcoaht')\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 7))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'ide')\n", + "assert(w_enigma.notch_positions == ([18], [4], [9]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'xfvglbdynuseriwqpmkzjcoaht')\n", "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 8))\n", - "assert(cat(enigma.wheel_positions_l) == 'idf')\n", - "assert(enigma.peg_positions == ([8], [22], [16]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'tfpqlbouynsewjgcdxkahzmriv')\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 8))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idf')\n", + "assert(w_enigma.notch_positions == ([18], [4], [10]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'tfpqlbouynsewjgcdxkahzmriv')\n", "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 9))\n", - "assert(cat(enigma.wheel_positions_l) == 'idg')\n", - "assert(enigma.peg_positions == ([8], [22], [15]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'cjaunvlwtbygzexrspqidfhokm')\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 9))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idg')\n", + "assert(w_enigma.notch_positions == ([18], [4], [11]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'cjaunvlwtbygzexrspqidfhokm')\n", "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 10))\n", - "assert(cat(enigma.wheel_positions_l) == 'idh')\n", - "assert(enigma.peg_positions == ([8], [22], [14]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'yltxkrqvowebzpingfucshjdam')\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 10))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idh')\n", + "assert(w_enigma.notch_positions == ([18], [4], [12]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'yltxkrqvowebzpingfucshjdam')\n", "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 11))\n", - "assert(cat(enigma.wheel_positions_l) == 'idi')\n", - "assert(enigma.peg_positions == ([8], [22], [13]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'myktluzrnxceaiqsohpdfwvjbg')\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 11))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idi')\n", + "assert(w_enigma.notch_positions == ([18], [4], [13]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'myktluzrnxceaiqsohpdfwvjbg')\n", "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 12))\n", - "assert(cat(enigma.wheel_positions_l) == 'idj')\n", - "assert(enigma.peg_positions == ([8], [22], [12]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'pynjrmiugdqxfcvakewzhoslbt')\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 12))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idj')\n", + "assert(w_enigma.notch_positions == ([18], [4], [14]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'pynjrmiugdqxfcvakewzhoslbt')\n", "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 13))\n", - "assert(cat(enigma.wheel_positions_l) == 'idk')\n", - "assert(enigma.peg_positions == ([8], [22], [11]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'mwvedyplnoxhaijgrqtszcbkfu')\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 13))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idk')\n", + "assert(w_enigma.notch_positions == ([18], [4], [15]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'mwvedyplnoxhaijgrqtszcbkfu')\n", "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 14))\n", - "assert(cat(enigma.wheel_positions_l) == 'idl')\n", - "assert(enigma.peg_positions == ([8], [22], [10]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'qcbrfeutvoxpnmjladzhgiykws')\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 14))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idl')\n", + "assert(w_enigma.notch_positions == ([18], [4], [16]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'qcbrfeutvoxpnmjladzhgiykws')\n", "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 15))\n", - "assert(cat(enigma.wheel_positions_l) == 'idm')\n", - "assert(enigma.peg_positions == ([8], [22], [9]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'dnoahryetsmukbcvwfjilpqzgx')\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 15))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idm')\n", + "assert(w_enigma.notch_positions == ([18], [4], [17]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'dnoahryetsmukbcvwfjilpqzgx')\n", "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 16))\n", - "assert(cat(enigma.wheel_positions_l) == 'idn')\n", - "assert(enigma.peg_positions == ([8], [22], [8]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'nidcfehgbqsovalyjzkxwmutpr')\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 16))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idn')\n", + "assert(w_enigma.notch_positions == ([18], [4], [18]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'nidcfehgbqsovalyjzkxwmutpr')\n", "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 17))\n", - "assert(cat(enigma.wheel_positions_l) == 'ido')\n", - "assert(enigma.peg_positions == ([8], [22], [7]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'joifxdulcarhzpbntkwqgysevm')\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 17))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'ido')\n", + "assert(w_enigma.notch_positions == ([18], [4], [19]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'joifxdulcarhzpbntkwqgysevm')\n", "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 18))\n", - "assert(cat(enigma.wheel_positions_l) == 'idp')\n", - "assert(enigma.peg_positions == ([8], [22], [6]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'ptnlsxvozmwdjchayuebrgkfqi')\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 18))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idp')\n", + "assert(w_enigma.notch_positions == ([18], [4], [20]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'ptnlsxvozmwdjchayuebrgkfqi')\n", "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 19))\n", - "assert(cat(enigma.wheel_positions_l) == 'idq')\n", - "assert(enigma.peg_positions == ([8], [22], [5]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'slwopzqnmxybihdeguavrtcjkf')\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 19))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idq')\n", + "assert(w_enigma.notch_positions == ([18], [4], [21]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'slwopzqnmxybihdeguavrtcjkf')\n", "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 20))\n", - "assert(cat(enigma.wheel_positions_l) == 'idr')\n", - "assert(enigma.peg_positions == ([8], [22], [4]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'hcbedwlamzogixkytsrqvufnpj')\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 20))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idr')\n", + "assert(w_enigma.notch_positions == ([18], [4], [22]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'hcbedwlamzogixkytsrqvufnpj')\n", "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 21))\n", - "assert(cat(enigma.wheel_positions_l) == 'ids')\n", - "assert(enigma.peg_positions == ([8], [22], [3]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'odxbjwzrmelkisavuhnyqpfctg')\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 21))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'ids')\n", + "assert(w_enigma.notch_positions == ([18], [4], [23]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'odxbjwzrmelkisavuhnyqpfctg')\n", "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 22))\n", - "assert(cat(enigma.wheel_positions_l) == 'idt')\n", - "assert(enigma.peg_positions == ([8], [22], [2]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'udgbfeclrwnhxksvtioqapjmzy')\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 22))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idt')\n", + "assert(w_enigma.notch_positions == ([18], [4], [24]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'udgbfeclrwnhxksvtioqapjmzy')\n", "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 23))\n", - "assert(cat(enigma.wheel_positions_l) == 'idu')\n", - "assert(enigma.peg_positions == ([8], [22], [1]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'nrdczqxmowvshaiufblypkjgte')\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 23))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idu')\n", + "assert(w_enigma.notch_positions == ([18], [4], [25]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'nrdczqxmowvshaiufblypkjgte')\n", "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 10, 24))\n", - "assert(cat(enigma.wheel_positions_l) == 'idv')\n", - "assert(enigma.peg_positions == ([8], [22], [0]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'hkifjdoacebqtzgulyvmpsxwrn')\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 10, 24))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'idv')\n", + "assert(w_enigma.notch_positions == ([18], [4], [0]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'hkifjdoacebqtzgulyvmpsxwrn')\n", "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 11, 25))\n", - "assert(cat(enigma.wheel_positions_l) == 'iew')\n", - "assert(enigma.peg_positions == ([8], [21], [25]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'yptzuhofqvnmlkgbixwcejsrad')\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 11, 25))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'iew')\n", + "assert(w_enigma.notch_positions == ([18], [5], [1]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'yptzuhofqvnmlkgbixwcejsrad')\n", "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 11, 0))\n", - "assert(cat(enigma.wheel_positions_l) == 'iex')\n", - "assert(enigma.peg_positions == ([8], [21], [24]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'vkdcwhqfjibzsptngumoraeyxl')\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 11, 0))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'iex')\n", + "assert(w_enigma.notch_positions == ([18], [5], [2]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'vkdcwhqfjibzsptngumoraeyxl')\n", "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 11, 1))\n", - "assert(cat(enigma.wheel_positions_l) == 'iey')\n", - "assert(enigma.peg_positions == ([8], [21], [23]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'wenpbqrouxlkychdfgzvitajms')\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 11, 1))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'iey')\n", + "assert(w_enigma.notch_positions == ([18], [5], [3]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'wenpbqrouxlkychdfgzvitajms')\n", "\n", - "enigma.advance()\n", - "assert(enigma.wheel_positions == (3, 11, 2))\n", - "assert(cat(enigma.wheel_positions_l) == 'iez')\n", - "assert(enigma.peg_positions == ([8], [21], [22]))\n", - "assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == 'szgyqvclkoihurjwenaxmfptdb')\n", + "w_enigma.advance()\n", + "assert(w_enigma.wheel_positions == (3, 11, 2))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'iez')\n", + "assert(w_enigma.notch_positions == ([18], [5], [4]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'szgyqvclkoihurjwenaxmfptdb')\n", "\n" ] } ], "source": [ - "enigma.set_wheels('i', 'd', 'z')\n", + "w_enigma.set_wheels('i', 'd', 'z')\n", "\n", "for i in range(26):\n", - " enigma.advance()\n", - " print('enigma.advance()')\n", - " print(\"assert(enigma.wheel_positions == {})\".format(enigma.wheel_positions))\n", - " print(\"assert(cat(enigma.wheel_positions_l) == '{}')\".format(cat(enigma.wheel_positions_l)))\n", - " print(\"assert(enigma.peg_positions == {})\".format(enigma.peg_positions))\n", - " print(\"assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == '{}')\".format(cat(enigma.lookup(l) for l in string.ascii_lowercase)))\n", + " w_enigma.advance()\n", + " print('w_enigma.advance()')\n", + " print(\"assert(w_enigma.wheel_positions == {})\".format(w_enigma.wheel_positions))\n", + " print(\"assert(cat(w_enigma.wheel_positions_l) == '{}')\".format(cat(w_enigma.wheel_positions_l)))\n", + " print(\"assert(w_enigma.notch_positions == {})\".format(w_enigma.notch_positions))\n", + " print(\"assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == '{}')\".format(cat(w_enigma.lookup(l) for l in string.ascii_lowercase)))\n", + " print()" + ] + }, + { + "cell_type": "code", + "execution_count": 215, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.assertEqual(self.enigma31.wheel_positions, (21, 5, 22))\n", + "self.assertEqual(cat(self.enigma31.wheel_positions_l), 'ayt')\n", + "self.assertEqual(self.enigma31.notch_positions, ([10], [25], [24]))\n", + "assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'izhrgtecaslkywvqpdjfxonumb')\n", + "\n", + "self.enigma31.advance()\n", + "self.assertEqual(self.enigma31.wheel_positions, (21, 5, 23))\n", + "self.assertEqual(cat(self.enigma31.wheel_positions_l), 'ayu')\n", + "self.assertEqual(self.enigma31.notch_positions, ([10], [25], [25]))\n", + "assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'dtoavihgflwjnmcsrqpbzekyxu')\n", + "\n", + "self.enigma31.advance()\n", + "self.assertEqual(self.enigma31.wheel_positions, (21, 5, 24))\n", + "self.assertEqual(cat(self.enigma31.wheel_positions_l), 'ayv')\n", + "self.assertEqual(self.enigma31.notch_positions, ([10], [25], [0]))\n", + "assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'xquhtpsdwkjonmlfbvgecriazy')\n", + "\n", + "self.enigma31.advance()\n", + "self.assertEqual(self.enigma31.wheel_positions, (21, 6, 25))\n", + "self.assertEqual(cat(self.enigma31.wheel_positions_l), 'azw')\n", + "self.assertEqual(self.enigma31.notch_positions, ([10], [0], [1]))\n", + "assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'dofapcluvmngjkbezyxwhitsrq')\n", + "\n", + "self.enigma31.advance()\n", + "self.assertEqual(self.enigma31.wheel_positions, (22, 7, 0))\n", + "self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bax')\n", + "self.assertEqual(self.enigma31.notch_positions, ([11], [1], [2]))\n", + "assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'jdlbmswztapcexrkuofiqygnvh')\n", + "\n", + "self.enigma31.advance()\n", + "self.assertEqual(self.enigma31.wheel_positions, (22, 7, 1))\n", + "self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bay')\n", + "self.assertEqual(self.enigma31.notch_positions, ([11], [1], [3]))\n", + "assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'iydcnuhgawsoxelztvkqfrjmbp')\n", + "\n" + ] + } + ], + "source": [ + "w_enigma.set_wheels('a', 'y', 't')\n", + "\n", + "print(\"self.assertEqual(self.enigma31.wheel_positions, {})\".format(w_enigma.wheel_positions))\n", + "print(\"self.assertEqual(cat(self.enigma31.wheel_positions_l), '{}')\".format(cat(w_enigma.wheel_positions_l)))\n", + "print(\"self.assertEqual(self.enigma31.notch_positions, {})\".format(w_enigma.notch_positions))\n", + "print(\"assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == '{}')\".format(cat(w_enigma.lookup(l) for l in string.ascii_lowercase)))\n", + "print()\n", + "\n", + "for i in range(5):\n", + " w_enigma.advance()\n", + " print('self.enigma31.advance()')\n", + " print(\"self.assertEqual(self.enigma31.wheel_positions, {})\".format(w_enigma.wheel_positions))\n", + " print(\"self.assertEqual(cat(self.enigma31.wheel_positions_l), '{}')\".format(cat(w_enigma.wheel_positions_l)))\n", + " print(\"self.assertEqual(self.enigma31.notch_positions, {})\".format(w_enigma.notch_positions))\n", + " print(\"assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == '{}')\".format(cat(w_enigma.lookup(l) for l in string.ascii_lowercase)))\n", " print()" ] }, + { + "cell_type": "code", + "execution_count": 216, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.assertEqual(self.enigma31.wheel_positions, (21, 6, 22))\n", + "self.assertEqual(cat(self.enigma31.wheel_positions_l), 'azt')\n", + "self.assertEqual(self.enigma31.notch_positions, ([10], [0], [24]))\n", + "assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'idjbptqwacsvnmregokfzlhyxu')\n", + "\n", + "self.enigma31.advance()\n", + "self.assertEqual(self.enigma31.wheel_positions, (22, 7, 23))\n", + "self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bau')\n", + "self.assertEqual(self.enigma31.notch_positions, ([11], [1], [25]))\n", + "assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'rniszouwcxtvqbfymadkglhjpe')\n", + "\n", + "self.enigma31.advance()\n", + "self.assertEqual(self.enigma31.wheel_positions, (22, 7, 24))\n", + "self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bav')\n", + "self.assertEqual(self.enigma31.notch_positions, ([11], [1], [0]))\n", + "assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'qijfsdmkbchugxtwazeolypnvr')\n", + "\n", + "self.enigma31.advance()\n", + "self.assertEqual(self.enigma31.wheel_positions, (22, 8, 25))\n", + "self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bbw')\n", + "self.assertEqual(self.enigma31.notch_positions, ([11], [2], [1]))\n", + "assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'xprtlozyskjewqfbncidvumahg')\n", + "\n", + "self.enigma31.advance()\n", + "self.assertEqual(self.enigma31.wheel_positions, (22, 8, 0))\n", + "self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bbx')\n", + "self.assertEqual(self.enigma31.notch_positions, ([11], [2], [2]))\n", + "assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'vtfuyczoqxmpkwhlisrbdanjeg')\n", + "\n", + "self.enigma31.advance()\n", + "self.assertEqual(self.enigma31.wheel_positions, (22, 8, 1))\n", + "self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bby')\n", + "self.assertEqual(self.enigma31.notch_positions, ([11], [2], [3]))\n", + "assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'tjrhzpqdobwxyuifgcvansklme')\n", + "\n" + ] + } + ], + "source": [ + "w_enigma.set_wheels('a', 'z', 't')\n", + "\n", + "print(\"self.assertEqual(self.enigma31.wheel_positions, {})\".format(w_enigma.wheel_positions))\n", + "print(\"self.assertEqual(cat(self.enigma31.wheel_positions_l), '{}')\".format(cat(w_enigma.wheel_positions_l)))\n", + "print(\"self.assertEqual(self.enigma31.notch_positions, {})\".format(w_enigma.notch_positions))\n", + "print(\"assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == '{}')\".format(cat(w_enigma.lookup(l) for l in string.ascii_lowercase)))\n", + "print()\n", + "\n", + "for i in range(5):\n", + " w_enigma.advance()\n", + " print('self.enigma31.advance()')\n", + " print(\"self.assertEqual(self.enigma31.wheel_positions, {})\".format(w_enigma.wheel_positions))\n", + " print(\"self.assertEqual(cat(self.enigma31.wheel_positions_l), '{}')\".format(cat(w_enigma.wheel_positions_l)))\n", + " print(\"self.assertEqual(self.enigma31.notch_positions, {})\".format(w_enigma.notch_positions))\n", + " print(\"assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == '{}')\".format(cat(w_enigma.lookup(l) for l in string.ascii_lowercase)))\n", + " print()" + ] + }, + { + "cell_type": "code", + "execution_count": 221, + "metadata": {}, + "outputs": [], + "source": [ + "w_enigma.set_wheels('i', 'z', 'd')\n", + "ct = w_enigma.encipher('verylongtestmessagewithanextrabitofmessageforgoodmeasure')\n", + "assert(ct == 'apocwtjuikurcfivlozvhffkoacxufcekthcvodfqpxdjqyckdozlqki')\n", + "assert(w_enigma.wheel_positions == (4, 9, 10))\n", + "assert(cat(w_enigma.wheel_positions_l) == 'jch')\n", + "assert(w_enigma.notch_positions == ([19], [3], [12]))\n", + "assert(cat(w_enigma.lookup(l) for l in string.ascii_lowercase) == 'mopnigfuesqwadbcktjrhylzvx')\n", + "\n", + "w_enigma.set_wheels('i', 'z', 'd')\n", + "pt = w_enigma.decipher('apocwtjuikurcfivlozvhffkoacxufcekthcvodfqpxdjqyckdozlqki')\n", + "assert(pt == 'verylongtestmessagewithanextrabitofmessageforgoodmeasure')" + ] + }, + { + "cell_type": "code", + "execution_count": 218, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "([19], [3], [12])" + ] + }, + "execution_count": 218, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "w_enigma.notch_positions" + ] + }, + { + "cell_type": "code", + "execution_count": 194, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Reflector B\n", + "# Rotors III, I, II with rings 17, 11, 19\n", + "# Plugboard pairs GU FZ BD LK TC PS HV WN JE AM\n", + "\n", + "tbt_enigma = Enigma(reflector_b_spec, \n", + " wheel_iii_spec, wheel_iii_notches,\n", + " wheel_i_spec, wheel_i_notches,\n", + " wheel_ii_spec, wheel_ii_notches,\n", + " 17, 11, 19,\n", + " 'GU FZ BD LK TC PS HV WN JE AM'.lower())" + ] + }, + { + "cell_type": "code", + "execution_count": 195, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'jbvbwwzfslhxnhzzccsngebmrnswgjonwbjnzcfgadeuoyameylmpvny'" + ] + }, + "execution_count": 195, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tbt_enigma.set_wheels('a', 'q', 'v')\n", + "ct = tbt_enigma.encipher('very long test message with an extra bit of message for good measure')\n", + "ct" + ] + }, + { + "cell_type": "code", + "execution_count": 196, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'SLGNC SZXLT KZEBG HSTGY WDMPR'" + ] + }, + "execution_count": 196, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "target_ct = 'SLGNC SZXLT KZEBG HSTGY WDMPR'\n", + "target_ct" + ] + }, + { + "cell_type": "code", + "execution_count": 197, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Theyw erede tecte d byBri tishs hipsi nclud'" + ] + }, + "execution_count": 197, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "target_pt = 'Theyw erede tecte d byBri tishs hipsi nclud'\n", + "target_pt" + ] + }, + { + "cell_type": "code", + "execution_count": 198, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(29, 43)" + ] + }, + "execution_count": 198, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(target_ct), len(target_pt)" + ] + }, + { + "cell_type": "code", + "execution_count": 199, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "SLGNC SZXLT KZEBG HSTGY WDMPR\n", + "Theyw erede tecte d byBri tishs hipsi nclud\n" + ] + } + ], + "source": [ + "print('{}\\n{}'.format(target_ct, target_pt))" + ] + }, + { + "cell_type": "code", + "execution_count": 200, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Theyw erede tecte d byBri tishs hipsi nclud\n", + "SLGNC SZXLT KZEBG HSTGY WDMPR\n", + "slgncszxltkzebghstgywdmprucuzqdqzpve\n", + "theyweredetectedbybritish\n" + ] + } + ], + "source": [ + "tbt_enigma.set_wheels('a', 'a', 'a')\n", + "this_pt = tbt_enigma.encipher(target_ct)\n", + "\n", + "tbt_enigma.set_wheels('a', 'a', 'a')\n", + "this_ct = tbt_enigma.encipher(target_pt)\n", + "\n", + "\n", + "print('{}\\n{}\\n{}\\n{}'.format(target_pt, target_ct, this_ct, this_pt))" + ] + }, + { + "cell_type": "code", + "execution_count": 201, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import itertools" + ] + }, + { + "cell_type": "code", + "execution_count": 202, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def str_ham(s1, s2):\n", + " \"\"\"Hamming distance for strings\"\"\"\n", + " return sum(1 for c1, c2 in zip(s1, s2) if c1 != c2)" + ] + }, + { + "cell_type": "code", + "execution_count": 203, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0" + ] + }, + "execution_count": 203, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "str_ham('hello', 'hello')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A brute-force check of all message settings, looking for the one that generates the target text." + ] + }, + { + "cell_type": "code", + "execution_count": 204, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "best ('a', 'a', 'a') 29\n", + "best ('a', 'a', 'a') 29\n", + "best ('a', 'a', 'a') 29\n", + "best ('a', 'a', 'a') 29\n", + "1 loop, best of 3: 20.6 s per loop\n" + ] + } + ], + "source": [ + "%%timeit\n", + "best = ('a', 'a', 'a')\n", + "best_hd = 10000\n", + "for w1, w2, w3 in itertools.product(string.ascii_lowercase, repeat=3):\n", + " tbt_enigma.set_wheels(w1, w2, w3)\n", + " this_ct = tbt_enigma.encipher(target_pt)\n", + " if this_ct == target_ct:\n", + " print(w1, w2, w3)\n", + " if str_ham(this_ct, target_ct) < best_hd:\n", + " best = (w1, w2, w3)\n", + " best_hd = str_ham(this_ct, target_ct)\n", + "print('best', best, best_hd)" + ] + }, + { + "cell_type": "code", + "execution_count": 205, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Wheels now ['a', 'a', 'b'] enciphering t -> s\n", + "Wheels now ['a', 'a', 'c'] enciphering h -> l\n", + "Wheels now ['a', 'a', 'd'] enciphering e -> g\n", + "Wheels now ['a', 'a', 'e'] enciphering y -> n\n", + "Wheels now ['a', 'b', 'f'] enciphering w -> c\n", + "Wheels now ['a', 'b', 'g'] enciphering e -> s\n", + "Wheels now ['a', 'b', 'h'] enciphering r -> z\n", + "Wheels now ['a', 'b', 'i'] enciphering e -> x\n", + "Wheels now ['a', 'b', 'j'] enciphering d -> l\n", + "Wheels now ['a', 'b', 'k'] enciphering e -> t\n", + "Wheels now ['a', 'b', 'l'] enciphering t -> k\n", + "Wheels now ['a', 'b', 'm'] enciphering e -> z\n", + "Wheels now ['a', 'b', 'n'] enciphering c -> e\n", + "Wheels now ['a', 'b', 'o'] enciphering t -> b\n", + "Wheels now ['a', 'b', 'p'] enciphering e -> g\n", + "Wheels now ['a', 'b', 'q'] enciphering d -> h\n", + "Wheels now ['a', 'b', 'r'] enciphering b -> s\n", + "Wheels now ['a', 'b', 's'] enciphering y -> t\n", + "Wheels now ['a', 'b', 't'] enciphering b -> g\n", + "Wheels now ['a', 'b', 'u'] enciphering r -> y\n", + "Wheels now ['a', 'b', 'v'] enciphering i -> w\n", + "Wheels now ['a', 'b', 'w'] enciphering t -> d\n", + "Wheels now ['a', 'b', 'x'] enciphering i -> m\n", + "Wheels now ['a', 'b', 'y'] enciphering s -> p\n", + "Wheels now ['a', 'b', 'z'] enciphering h -> r\n", + "Wheels now ['a', 'b', 'a'] enciphering s -> u\n", + "Wheels now ['a', 'b', 'b'] enciphering h -> c\n", + "Wheels now ['a', 'b', 'c'] enciphering i -> u\n", + "Wheels now ['a', 'b', 'd'] enciphering p -> z\n", + "Wheels now ['a', 'b', 'e'] enciphering s -> q\n", + "Wheels now ['a', 'c', 'f'] enciphering i -> d\n", + "Wheels now ['a', 'c', 'g'] enciphering n -> q\n", + "Wheels now ['a', 'c', 'h'] enciphering c -> z\n", + "Wheels now ['a', 'c', 'i'] enciphering l -> p\n", + "Wheels now ['a', 'c', 'j'] enciphering u -> v\n", + "Wheels now ['a', 'c', 'k'] enciphering d -> e\n" + ] + }, + { + "data": { + "text/plain": [ + "('slgncszxltkzebghstgywdmprucuzqdqzpve', 'SLGNC SZXLT KZEBG HSTGY WDMPR')" + ] + }, + "execution_count": 205, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tbt_enigma.set_wheels('a', 'a', 'a')\n", + "tbt_enigma.encipher(target_pt, debug=True), target_ct" + ] + }, + { + "cell_type": "code", + "execution_count": 206, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Wheels now ['a', 'a', 'b'] enciphering s -> t\n", + "Wheels now ['a', 'a', 'c'] enciphering l -> h\n", + "Wheels now ['a', 'a', 'd'] enciphering g -> e\n", + "Wheels now ['a', 'a', 'e'] enciphering n -> y\n", + "Wheels now ['a', 'b', 'f'] enciphering c -> w\n", + "Wheels now ['a', 'b', 'g'] enciphering s -> e\n", + "Wheels now ['a', 'b', 'h'] enciphering z -> r\n", + "Wheels now ['a', 'b', 'i'] enciphering x -> e\n", + "Wheels now ['a', 'b', 'j'] enciphering l -> d\n", + "Wheels now ['a', 'b', 'k'] enciphering t -> e\n", + "Wheels now ['a', 'b', 'l'] enciphering k -> t\n", + "Wheels now ['a', 'b', 'm'] enciphering z -> e\n", + "Wheels now ['a', 'b', 'n'] enciphering e -> c\n", + "Wheels now ['a', 'b', 'o'] enciphering b -> t\n", + "Wheels now ['a', 'b', 'p'] enciphering g -> e\n", + "Wheels now ['a', 'b', 'q'] enciphering h -> d\n", + "Wheels now ['a', 'b', 'r'] enciphering s -> b\n", + "Wheels now ['a', 'b', 's'] enciphering t -> y\n", + "Wheels now ['a', 'b', 't'] enciphering g -> b\n", + "Wheels now ['a', 'b', 'u'] enciphering y -> r\n", + "Wheels now ['a', 'b', 'v'] enciphering w -> i\n", + "Wheels now ['a', 'b', 'w'] enciphering d -> t\n", + "Wheels now ['a', 'b', 'x'] enciphering m -> i\n", + "Wheels now ['a', 'b', 'y'] enciphering p -> s\n", + "Wheels now ['a', 'b', 'z'] enciphering r -> h\n" + ] + }, + { + "data": { + "text/plain": [ + "('theyweredetectedbybritish', 'Theyw erede tecte d byBri tishs hipsi nclud')" + ] + }, + "execution_count": 206, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tbt_enigma.set_wheels('a', 'a', 'a')\n", + "tbt_enigma.encipher(target_ct, debug=True), target_pt" + ] + }, + { + "cell_type": "code", + "execution_count": 207, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('theyweredetectedbybritish', 'Theyw erede tecte d byBri tishs hipsi nclud')" + ] + }, + "execution_count": 207, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tbt_enigma.set_wheels('a', 'a', 'a')\n", + "tbt_enigma.encipher(target_ct), target_pt" + ] + }, + { + "cell_type": "code", + "execution_count": 208, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'mdtbjzuvielkawosqrpcghnxyf'" + ] + }, + "execution_count": 208, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cat(tbt_enigma.plugboard.forward(l) for l in string.ascii_lowercase)" + ] + }, + { + "cell_type": "code", + "execution_count": 209, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10" + ] + }, + "execution_count": 209, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tbt_enigma.set_wheels('a', 'a', 'a')\n", + "tbt_enigma.left_wheel.position" + ] + }, { "cell_type": "code", "execution_count": null, @@ -2249,9 +3523,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.4.3+" + "version": "3.5.3" } }, "nbformat": 4, - "nbformat_minor": 0 + "nbformat_minor": 1 } diff --git a/enigma.py b/enigma.py index a26d1d3..89758f5 100644 --- a/enigma.py +++ b/enigma.py @@ -60,14 +60,14 @@ wheel_viii_spec = 'fkqhtlxocbjspdzramewniuygv' beta_wheel_spec = 'leyjvcnixwpbqmdrtakzgfuhos' gamma_wheel_spec = 'fsokanuerhmbtiycwlqpzxvgjd' -wheel_i_pegs = ['q'] -wheel_ii_pegs = ['e'] -wheel_iii_pegs = ['v'] -wheel_iv_pegs = ['j'] -wheel_v_pegs = ['z'] -wheel_vi_pegs = ['z', 'm'] -wheel_vii_pegs = ['z', 'm'] -wheel_viii_pegs = ['z', 'm'] +wheel_i_notches = ['q'] +wheel_ii_notches = ['e'] +wheel_iii_notches = ['v'] +wheel_iv_notches = ['j'] +wheel_v_notches = ['z'] +wheel_vi_notches = ['z', 'm'] +wheel_vii_notches = ['z', 'm'] +wheel_viii_notches = ['z', 'm'] reflector_b_spec = 'ay br cu dh eq fs gl ip jx kn mo tz vw' reflector_c_spec = 'af bv cp dj ei go hy kr lz mx nw tq su' @@ -223,7 +223,7 @@ class SimpleWheel(LetterTransformer): class Wheel(SimpleWheel): """A wheel with a movable ring. - The ring holds the letters and the pegs that turn other wheels. The core + The ring holds the letters and the notches that turn other wheels. The core holds the wiring that does the transformation. The ring position is how many steps the core is turned relative to the ring. @@ -236,12 +236,12 @@ class Wheel(SimpleWheel): The position_l is the position of the ring, or what would be observed by the user of the Enigma machine. - The peg_positions are the number of advances of this wheel before it will + The notch_positions are the number of advances of this wheel before it will advance the next wheel. """ - def __init__(self, transform, ring_peg_letters, ring_setting=1, position='a', raw_transform=False): - self.ring_peg_letters = ring_peg_letters + def __init__(self, transform, ring_notch_letters, ring_setting=1, position='a', raw_transform=False): + self.ring_notch_letters = ring_notch_letters self.ring_setting = ring_setting super(Wheel, self).__init__(transform, position=position, raw_transform=raw_transform) self.set_position(position) @@ -257,12 +257,14 @@ class Wheel(SimpleWheel): self.position = (pos(position) - self.ring_setting + 1) % 26 else: self.position = (position - self.ring_setting) % 26 - # self.peg_positions = [(pos(p) - pos(position)) % 26 for p in self.ring_peg_letters] - self.peg_positions = [(pos(p) - (self.position + self.ring_setting - 1)) % 26 for p in self.ring_peg_letters] + # # self.notch_positions = [(pos(p) - pos(position)) % 26 for p in self.ring_notch_letters] + # self.notch_positions = [(pos(p) - (self.position + self.ring_setting - 1)) % 26 for p in self.ring_notch_letters] + self.notch_positions = [(self.position + self.ring_setting - 1 - pos(p)) % 26 for p in self.ring_notch_letters] def advance(self): super(Wheel, self).advance() - self.peg_positions = [(p - 1) % 26 for p in self.peg_positions] + self.notch_positions = [(p + 1) % 26 for p in self.notch_positions] + return self.position class Enigma(object): @@ -271,15 +273,15 @@ class Enigma(object): """ def __init__(self, reflector_spec, - left_wheel_spec, left_wheel_pegs, - middle_wheel_spec, middle_wheel_pegs, - right_wheel_spec, right_wheel_pegs, + left_wheel_spec, left_wheel_notches, + middle_wheel_spec, middle_wheel_notches, + right_wheel_spec, right_wheel_notches, left_ring_setting, middle_ring_setting, right_ring_setting, plugboard_setting): self.reflector = Reflector(reflector_spec) - self.left_wheel = Wheel(left_wheel_spec, left_wheel_pegs, ring_setting=left_ring_setting) - self.middle_wheel = Wheel(middle_wheel_spec, middle_wheel_pegs, ring_setting=middle_ring_setting) - self.right_wheel = Wheel(right_wheel_spec, right_wheel_pegs, ring_setting=right_ring_setting) + self.left_wheel = Wheel(left_wheel_spec, left_wheel_notches, ring_setting=left_ring_setting) + self.middle_wheel = Wheel(middle_wheel_spec, middle_wheel_notches, ring_setting=middle_ring_setting) + self.right_wheel = Wheel(right_wheel_spec, right_wheel_notches, ring_setting=right_ring_setting) self.plugboard = Plugboard(plugboard_setting) def __getattribute__(self,name): @@ -287,8 +289,8 @@ class Enigma(object): return self.left_wheel.position, self.middle_wheel.position, self.right_wheel.position elif name=='wheel_positions_l': return self.left_wheel.position_l, self.middle_wheel.position_l, self.right_wheel.position_l - elif name=='peg_positions': - return self.left_wheel.peg_positions, self.middle_wheel.peg_positions, self.right_wheel.peg_positions + elif name=='notch_positions': + return self.left_wheel.notch_positions, self.middle_wheel.notch_positions, self.right_wheel.notch_positions else: return object.__getattribute__(self, name) @@ -312,9 +314,9 @@ class Enigma(object): def advance(self): advance_middle = False advance_left = False - if 0 in self.right_wheel.peg_positions: + if 0 in self.right_wheel.notch_positions: advance_middle = True - if 0 in self.middle_wheel.peg_positions: + if 0 in self.middle_wheel.notch_positions: advance_left = True advance_middle = True self.right_wheel.advance() @@ -339,7 +341,7 @@ class Enigma(object): # print('enigma.advance()') # print("assert(enigma.wheel_positions == {})".format(enigma.wheel_positions)) # print("assert(cat(enigma.wheel_positions_l) == '{}')".format(cat(enigma.wheel_positions_l))) -# print("assert(enigma.peg_positions == {})".format(enigma.peg_positions)) +# print("assert(enigma.notch_positions == {})".format(enigma.notch_positions)) # print("assert(cat(enigma.lookup(l) for l in string.ascii_lowercase) == '{}')".format(cat(enigma.lookup(l) for l in string.ascii_lowercase))) # print() diff --git a/test_enigma.py b/test_enigma.py index b30be76..5ff8d9f 100644 --- a/test_enigma.py +++ b/test_enigma.py @@ -157,23 +157,23 @@ class SimpleWheelTest(unittest.TestCase): class WheelTest(unittest.TestCase): def test_init1(self): - wheel = Wheel(wheel_iii_spec, wheel_iii_pegs, position='b', + wheel = Wheel(wheel_iii_spec, wheel_iii_notches, position='b', ring_setting=1) self.assertEqual(wheel.position, 1) - self.assertEqual(wheel.peg_positions, [20]) + self.assertEqual(wheel.notch_positions, [6]) self.assertEqual(wheel.position_l, 'b') wheel.advance() self.assertEqual(wheel.position, 2) - self.assertEqual(wheel.peg_positions, [19]) + self.assertEqual(wheel.notch_positions, [7]) self.assertEqual(wheel.position_l, 'c') def test_init2(self): - wheel = Wheel(wheel_vi_spec, wheel_vi_pegs, position='b', + wheel = Wheel(wheel_vi_spec, wheel_vi_notches, position='b', ring_setting=3) self.assertEqual(wheel.position, 25) - self.assertIn(11, wheel.peg_positions) - self.assertIn(24, wheel.peg_positions) + self.assertIn(2, wheel.notch_positions) + self.assertIn(15, wheel.notch_positions) self.assertEqual(wheel.position_l, 'b') self.assertEqual(cat(wheel.forward(l) for l in string.ascii_lowercase), @@ -183,13 +183,13 @@ class WheelTest(unittest.TestCase): 'ptlyrmidoxbswhnfckquzgeavj') def test_advance(self): - wheel = Wheel(wheel_vi_spec, wheel_vi_pegs, position='b', + wheel = Wheel(wheel_vi_spec, wheel_vi_notches, position='b', ring_setting=3) wheel.advance() self.assertEqual(wheel.position, 0) - self.assertIn(10, wheel.peg_positions) - self.assertIn(23, wheel.peg_positions) + self.assertIn(3, wheel.notch_positions) + self.assertIn(16, wheel.notch_positions) self.assertEqual(wheel.position_l, 'c') self.assertEqual(cat(wheel.forward(l) for l in string.ascii_lowercase), @@ -199,14 +199,14 @@ class WheelTest(unittest.TestCase): 'skxqlhcnwarvgmebjptyfdzuio') def test_advance_23(self): - wheel = Wheel(wheel_vi_spec, wheel_vi_pegs, position='b', + wheel = Wheel(wheel_vi_spec, wheel_vi_notches, position='b', ring_setting=3) for _ in range(23): wheel.advance() self.assertEqual(wheel.position, 22) - self.assertIn(1, wheel.peg_positions) - self.assertIn(14, wheel.peg_positions) + self.assertIn(12, wheel.notch_positions) + self.assertIn(25, wheel.notch_positions) self.assertEqual(wheel.position_l, 'y') self.assertEqual(cat(wheel.forward(l) for l in string.ascii_lowercase), @@ -216,14 +216,14 @@ class WheelTest(unittest.TestCase): 'dymswobuplgraevzkqifntxcjh') def test_advance_24(self): - wheel = Wheel(wheel_vi_spec, wheel_vi_pegs, position='b', + wheel = Wheel(wheel_vi_spec, wheel_vi_notches, position='b', ring_setting=3) for _ in range(24): wheel.advance() self.assertEqual(wheel.position, 23) - self.assertIn(0, wheel.peg_positions) - self.assertIn(13, wheel.peg_positions) + self.assertIn(0, wheel.notch_positions) + self.assertIn(13, wheel.notch_positions) self.assertEqual(wheel.position_l, 'z') self.assertEqual(cat(wheel.forward(l) for l in string.ascii_lowercase), @@ -233,14 +233,14 @@ class WheelTest(unittest.TestCase): 'xlrvnatokfqzduyjphemswbigc') def test_advance_25(self): - wheel = Wheel(wheel_vi_spec, wheel_vi_pegs, position='b', + wheel = Wheel(wheel_vi_spec, wheel_vi_notches, position='b', ring_setting=3) for _ in range(25): wheel.advance() self.assertEqual(wheel.position, 24) - self.assertIn(25, wheel.peg_positions) - self.assertIn(12, wheel.peg_positions) + self.assertIn(1, wheel.notch_positions) + self.assertIn(14, wheel.notch_positions) self.assertEqual(wheel.position_l, 'a') self.assertEqual(cat(wheel.forward(l) for l in string.ascii_lowercase), @@ -250,14 +250,14 @@ class WheelTest(unittest.TestCase): 'kqumzsnjepyctxiogdlrvahfbw') def test_advance_26(self): - wheel = Wheel(wheel_vi_spec, wheel_vi_pegs, position='b', + wheel = Wheel(wheel_vi_spec, wheel_vi_notches, position='b', ring_setting=3) for _ in range(26): wheel.advance() self.assertEqual(wheel.position, 25) - self.assertIn(24, wheel.peg_positions) - self.assertIn(11, wheel.peg_positions) + self.assertIn(2, wheel.notch_positions) + self.assertIn(15, wheel.notch_positions) self.assertEqual(wheel.position_l, 'b') self.assertEqual(cat(wheel.forward(l) for l in string.ascii_lowercase), @@ -267,14 +267,14 @@ class WheelTest(unittest.TestCase): 'ptlyrmidoxbswhnfckquzgeavj') def test_advance_27(self): - wheel = Wheel(wheel_vi_spec, wheel_vi_pegs, position='b', + wheel = Wheel(wheel_vi_spec, wheel_vi_notches, position='b', ring_setting=3) for _ in range(27): wheel.advance() self.assertEqual(wheel.position, 0) - self.assertIn(23, wheel.peg_positions) - self.assertIn(10, wheel.peg_positions) + self.assertIn(3, wheel.notch_positions) + self.assertIn(16, wheel.notch_positions) self.assertEqual(wheel.position_l, 'c') self.assertEqual(cat(wheel.forward(l) for l in string.ascii_lowercase), @@ -284,60 +284,60 @@ class WheelTest(unittest.TestCase): 'skxqlhcnwarvgmebjptyfdzuio') def test_set_position(self): - wheel_3 = Wheel(wheel_iii_spec, wheel_iii_pegs, ring_setting=3) + wheel_3 = Wheel(wheel_iii_spec, wheel_iii_notches, ring_setting=3) wheel_3.set_position('a') self.assertEqual(wheel_3.position, 24) self.assertEqual(wheel_3.position_l, 'a') - self.assertEqual(wheel_3.peg_positions, [21]) + self.assertEqual(wheel_3.notch_positions, [5]) wheel_3.set_position('z') self.assertEqual(wheel_3.position, 23) self.assertEqual(wheel_3.position_l, 'z') - self.assertEqual(wheel_3.peg_positions, [22]) + self.assertEqual(wheel_3.notch_positions, [4]) wheel_3.set_position(26) self.assertEqual(wheel_3.position, 23) self.assertEqual(wheel_3.position_l, 'z') - self.assertEqual(wheel_3.peg_positions, [22]) + self.assertEqual(wheel_3.notch_positions, [4]) wheel_3.set_position(27) self.assertEqual(wheel_3.position, 24) self.assertEqual(wheel_3.position_l, 'a') - self.assertEqual(wheel_3.peg_positions, [21]) + self.assertEqual(wheel_3.notch_positions, [5]) wheel_3.set_position('f') self.assertEqual(wheel_3.position, 3) self.assertEqual(wheel_3.position_l, 'f') - self.assertEqual(wheel_3.peg_positions, [16]) + self.assertEqual(wheel_3.notch_positions, [10]) wheel_3.set_position(6) self.assertEqual(wheel_3.position, 3) self.assertEqual(wheel_3.position_l, 'f') - self.assertEqual(wheel_3.peg_positions, [16]) + self.assertEqual(wheel_3.notch_positions, [10]) wheel_3.advance() self.assertEqual(wheel_3.position, 4) self.assertEqual(wheel_3.position_l, 'g') - self.assertEqual(wheel_3.peg_positions, [15]) + self.assertEqual(wheel_3.notch_positions, [11]) wheel_3.set_position(12) self.assertEqual(wheel_3.position, 9) self.assertEqual(wheel_3.position_l, 'l') - self.assertEqual(wheel_3.peg_positions, [10]) + self.assertEqual(wheel_3.notch_positions, [16]) wheel_3.advance() self.assertEqual(wheel_3.position, 10) self.assertEqual(wheel_3.position_l, 'm') - self.assertEqual(wheel_3.peg_positions, [9]) + self.assertEqual(wheel_3.notch_positions, [17]) class EnigmaTest(unittest.TestCase): def setUp(self): self.enigma = Enigma(reflector_b_spec, - wheel_i_spec, wheel_i_pegs, - wheel_ii_spec, wheel_ii_pegs, - wheel_iii_spec, wheel_iii_pegs, + wheel_i_spec, wheel_i_notches, + wheel_ii_spec, wheel_ii_notches, + wheel_iii_spec, wheel_iii_notches, 1, 1, 1, '') @@ -345,17 +345,17 @@ class EnigmaTest(unittest.TestCase): # Enigma simulation settings are # http://enigma.louisedade.co.uk/enigma.html?m3;b;b153;AFTX;AJEU;AU-BG-EY-FP-HL-IN-JZ-OS-QR-TX self.enigma31 = Enigma(reflector_b_spec, - wheel_i_spec, wheel_i_pegs, - wheel_v_spec, wheel_v_pegs, - wheel_iii_spec, wheel_iii_pegs, + wheel_i_spec, wheel_i_notches, + wheel_v_spec, wheel_v_notches, + wheel_iii_spec, wheel_iii_notches, 6, 20, 24, 'ua pf rq so ni ey bg hl tx zj') # Settings for Bletchley Park outreach department's Enigma self.enigma_bp = Enigma(reflector_b_spec, - wheel_i_spec, wheel_i_pegs, - wheel_iii_spec, wheel_iii_pegs, - wheel_ii_spec, wheel_ii_pegs, + wheel_i_spec, wheel_i_notches, + wheel_iii_spec, wheel_iii_notches, + wheel_ii_spec, wheel_ii_notches, 1, 26, 26, 'qm we ro tu zj ps dl fg') @@ -364,42 +364,42 @@ class EnigmaTest(unittest.TestCase): self.enigma.set_wheels('a', 'a', 't') self.assertEqual(self.enigma.wheel_positions, (0, 0, 19)) self.assertEqual(cat(self.enigma.wheel_positions_l), 'aat') - self.assertEqual(self.enigma.peg_positions, ([16], [4], [2])) + self.assertEqual(self.enigma.notch_positions, ([10], [22], [24])) self.assertEqual(cat(self.enigma.lookup(l) for l in string.ascii_lowercase), 'puvioztjdhxmlyeawsrgbcqknf') self.enigma.advance() self.assertEqual(self.enigma.wheel_positions, (0, 0, 20)) self.assertEqual(cat(self.enigma.wheel_positions_l), 'aau') - self.assertEqual(self.enigma.peg_positions, ([16], [4], [1])) + self.assertEqual(self.enigma.notch_positions, ([10], [22], [25])) self.assertEqual(cat(self.enigma.lookup(l) for l in string.ascii_lowercase), 'baigpldqcowfyzjehvtsxrkumn') self.enigma.advance() self.assertEqual(self.enigma.wheel_positions, (0, 0, 21)) self.assertEqual(cat(self.enigma.wheel_positions_l), 'aav') - self.assertEqual(self.enigma.peg_positions, ([16], [4], [0])) + self.assertEqual(self.enigma.notch_positions, ([10], [22], [0])) self.assertEqual(cat(self.enigma.lookup(l) for l in string.ascii_lowercase), 'mnvfydiwgzsoablrxpkutchqej') self.enigma.advance() self.assertEqual(self.enigma.wheel_positions, (0, 1, 22)) self.assertEqual(cat(self.enigma.wheel_positions_l), 'abw') - self.assertEqual(self.enigma.peg_positions, ([16], [3], [25])) + self.assertEqual(self.enigma.notch_positions, ([10], [23], [1])) self.assertEqual(cat(self.enigma.lookup(l) for l in string.ascii_lowercase), 'ulfopcykswhbzvderqixanjtgm') self.enigma.advance() self.assertEqual(self.enigma.wheel_positions, (0, 1, 23)) self.assertEqual(cat(self.enigma.wheel_positions_l), 'abx') - self.assertEqual(self.enigma.peg_positions, ([16], [3], [24])) + self.assertEqual(self.enigma.notch_positions, ([10], [23], [2])) self.assertEqual(cat(self.enigma.lookup(l) for l in string.ascii_lowercase), 'qmwftdyovursbzhxaklejicpgn') self.enigma.advance() self.assertEqual(self.enigma.wheel_positions, (0, 1, 24)) self.assertEqual(cat(self.enigma.wheel_positions_l), 'aby') - self.assertEqual(self.enigma.peg_positions, ([16], [3], [23])) + self.assertEqual(self.enigma.notch_positions, ([10], [23], [3])) self.assertEqual(cat(self.enigma.lookup(l) for l in string.ascii_lowercase), 'oljmzxrvucybdqasngpwihtfke') @@ -408,42 +408,42 @@ class EnigmaTest(unittest.TestCase): self.enigma.set_wheels('a', 'd', 't') self.assertEqual(self.enigma.wheel_positions, (0, 3, 19)) self.assertEqual(cat(self.enigma.wheel_positions_l), 'adt') - self.assertEqual(self.enigma.peg_positions, ([16], [1], [2])) + self.assertEqual(self.enigma.notch_positions, ([10], [25], [24])) self.assertEqual(cat(self.enigma.lookup(l) for l in string.ascii_lowercase), 'zcbpqxwsjiuonmldethrkygfva') self.enigma.advance() self.assertEqual(self.enigma.wheel_positions, (0, 3, 20)) self.assertEqual(cat(self.enigma.wheel_positions_l), 'adu') - self.assertEqual(self.enigma.peg_positions, ([16], [1], [1])) + self.assertEqual(self.enigma.notch_positions, ([10], [25], [25])) self.assertEqual(cat(self.enigma.lookup(l) for l in string.ascii_lowercase), 'ehprawjbngotxikcsdqlzyfmvu') self.enigma.advance() self.assertEqual(self.enigma.wheel_positions, (0, 3, 21)) self.assertEqual(cat(self.enigma.wheel_positions_l), 'adv') - self.assertEqual(self.enigma.peg_positions, ([16], [1], [0])) + self.assertEqual(self.enigma.notch_positions, ([10], [25], [0])) self.assertEqual(cat(self.enigma.lookup(l) for l in string.ascii_lowercase), 'eqzxarpihmnvjkwgbfuyslodtc') self.enigma.advance() self.assertEqual(self.enigma.wheel_positions, (0, 4, 22)) self.assertEqual(cat(self.enigma.wheel_positions_l), 'aew') - self.assertEqual(self.enigma.peg_positions, ([16], [0], [25])) + self.assertEqual(self.enigma.notch_positions, ([10], [0], [1])) self.assertEqual(cat(self.enigma.lookup(l) for l in string.ascii_lowercase), 'qedcbtpluzmhkongavwfirsyxj') self.enigma.advance() self.assertEqual(self.enigma.wheel_positions, (1, 5, 23)) self.assertEqual(cat(self.enigma.wheel_positions_l), 'bfx') - self.assertEqual(self.enigma.peg_positions, ([15], [25], [24])) + self.assertEqual(self.enigma.notch_positions, ([11], [1], [2])) self.assertEqual(cat(self.enigma.lookup(l) for l in string.ascii_lowercase), 'iwuedhsfazqxytvrkpgncoblmj') self.enigma.advance() self.assertEqual(self.enigma.wheel_positions, (1, 5, 24)) self.assertEqual(cat(self.enigma.wheel_positions_l), 'bfy') - self.assertEqual(self.enigma.peg_positions, ([15], [25], [23])) + self.assertEqual(self.enigma.notch_positions, ([11], [1], [3])) self.assertEqual(cat(self.enigma.lookup(l) for l in string.ascii_lowercase), 'baknstqzrmcxjdvygiefwoulph') @@ -470,35 +470,35 @@ class EnigmaTest(unittest.TestCase): self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (4, 11, 24)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'jev') - self.assertEqual(self.enigma31.peg_positions, ([7], [21], [0])) + self.assertEqual(self.enigma31.notch_positions, ([19], [5], [0])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'mvqjlyowkdieasgzcunxrbhtfp') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (4, 12, 25)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'jfw') - self.assertEqual(self.enigma31.peg_positions, ([7], [20], [25])) + self.assertEqual(self.enigma31.notch_positions, ([19], [6], [1])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'sjolzuyvrbwdpxcmtiaqfhknge') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (4, 12, 0)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'jfx') - self.assertEqual(self.enigma31.peg_positions, ([7], [20], [24])) + self.assertEqual(self.enigma31.notch_positions, ([19], [6], [2])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'qrxedkoywufmlvgsabpzjnicht') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (4, 12, 1)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'jfy') - self.assertEqual(self.enigma31.peg_positions, ([7], [20], [23])) + self.assertEqual(self.enigma31.notch_positions, ([19], [6], [3])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'hpsukliagqefwvtbjxcodnmrzy') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (4, 12, 2)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'jfz') - self.assertEqual(self.enigma31.peg_positions, ([7], [20], [22])) + self.assertEqual(self.enigma31.notch_positions, ([19], [6], [4])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'zevnbpyqowrtxdifhkulscjmga') @@ -509,238 +509,309 @@ class EnigmaTest(unittest.TestCase): self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (3, 10, 3)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'ida') - self.assertEqual(self.enigma31.peg_positions, ([8], [22], [21])) + self.assertEqual(self.enigma31.notch_positions, ([18], [4], [5])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'ikhpqrvcambzjondefwyxgsutl') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (3, 10, 4)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idb') - self.assertEqual(self.enigma31.peg_positions, ([8], [22], [20])) + self.assertEqual(self.enigma31.notch_positions, ([18], [4], [6])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'cdabskhgzwfmlqvunyexpojtri') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (3, 10, 5)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idc') - self.assertEqual(self.enigma31.peg_positions, ([8], [22], [19])) + self.assertEqual(self.enigma31.notch_positions, ([18], [4], [7])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'pcbwiqhgemyvjsuaftnroldzkx') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (3, 10, 6)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idd') - self.assertEqual(self.enigma31.peg_positions, ([8], [22], [18])) + self.assertEqual(self.enigma31.notch_positions, ([18], [4], [8])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'xcbfvdnouptmlghjzwykierasq') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (3, 10, 7)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'ide') - self.assertEqual(self.enigma31.peg_positions, ([8], [22], [17])) + self.assertEqual(self.enigma31.notch_positions, ([18], [4], [9])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'xfvglbdynuseriwqpmkzjcoaht') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (3, 10, 8)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idf') - self.assertEqual(self.enigma31.peg_positions, ([8], [22], [16])) + self.assertEqual(self.enigma31.notch_positions, ([18], [4], [10])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'tfpqlbouynsewjgcdxkahzmriv') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (3, 10, 9)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idg') - self.assertEqual(self.enigma31.peg_positions, ([8], [22], [15])) + self.assertEqual(self.enigma31.notch_positions, ([18], [4], [11])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'cjaunvlwtbygzexrspqidfhokm') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (3, 10, 10)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idh') - self.assertEqual(self.enigma31.peg_positions, ([8], [22], [14])) + self.assertEqual(self.enigma31.notch_positions, ([18], [4], [12])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'yltxkrqvowebzpingfucshjdam') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (3, 10, 11)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idi') - self.assertEqual(self.enigma31.peg_positions, ([8], [22], [13])) + self.assertEqual(self.enigma31.notch_positions, ([18], [4], [13])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'myktluzrnxceaiqsohpdfwvjbg') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (3, 10, 12)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idj') - self.assertEqual(self.enigma31.peg_positions, ([8], [22], [12])) + self.assertEqual(self.enigma31.notch_positions, ([18], [4], [14])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'pynjrmiugdqxfcvakewzhoslbt') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (3, 10, 13)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idk') - self.assertEqual(self.enigma31.peg_positions, ([8], [22], [11])) + self.assertEqual(self.enigma31.notch_positions, ([18], [4], [15])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'mwvedyplnoxhaijgrqtszcbkfu') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (3, 10, 14)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idl') - self.assertEqual(self.enigma31.peg_positions, ([8], [22], [10])) + self.assertEqual(self.enigma31.notch_positions, ([18], [4], [16])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'qcbrfeutvoxpnmjladzhgiykws') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (3, 10, 15)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idm') - self.assertEqual(self.enigma31.peg_positions, ([8], [22], [9])) + self.assertEqual(self.enigma31.notch_positions, ([18], [4], [17])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'dnoahryetsmukbcvwfjilpqzgx') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (3, 10, 16)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idn') - self.assertEqual(self.enigma31.peg_positions, ([8], [22], [8])) + self.assertEqual(self.enigma31.notch_positions, ([18], [4], [18])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'nidcfehgbqsovalyjzkxwmutpr') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (3, 10, 17)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'ido') - self.assertEqual(self.enigma31.peg_positions, ([8], [22], [7])) + self.assertEqual(self.enigma31.notch_positions, ([18], [4], [19])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'joifxdulcarhzpbntkwqgysevm') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (3, 10, 18)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idp') - self.assertEqual(self.enigma31.peg_positions, ([8], [22], [6])) + self.assertEqual(self.enigma31.notch_positions, ([18], [4], [20])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'ptnlsxvozmwdjchayuebrgkfqi') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (3, 10, 19)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idq') - self.assertEqual(self.enigma31.peg_positions, ([8], [22], [5])) + self.assertEqual(self.enigma31.notch_positions, ([18], [4], [21])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'slwopzqnmxybihdeguavrtcjkf') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (3, 10, 20)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idr') - self.assertEqual(self.enigma31.peg_positions, ([8], [22], [4])) + self.assertEqual(self.enigma31.notch_positions, ([18], [4], [22])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'hcbedwlamzogixkytsrqvufnpj') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (3, 10, 21)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'ids') - self.assertEqual(self.enigma31.peg_positions, ([8], [22], [3])) + self.assertEqual(self.enigma31.notch_positions, ([18], [4], [23])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'odxbjwzrmelkisavuhnyqpfctg') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (3, 10, 22)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idt') - self.assertEqual(self.enigma31.peg_positions, ([8], [22], [2])) + self.assertEqual(self.enigma31.notch_positions, ([18], [4], [24])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'udgbfeclrwnhxksvtioqapjmzy') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (3, 10, 23)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idu') - self.assertEqual(self.enigma31.peg_positions, ([8], [22], [1])) + self.assertEqual(self.enigma31.notch_positions, ([18], [4], [25])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'nrdczqxmowvshaiufblypkjgte') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (3, 10, 24)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'idv') - self.assertEqual(self.enigma31.peg_positions, ([8], [22], [0])) + self.assertEqual(self.enigma31.notch_positions, ([18], [4], [0])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'hkifjdoacebqtzgulyvmpsxwrn') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (3, 11, 25)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'iew') - self.assertEqual(self.enigma31.peg_positions, ([8], [21], [25])) + self.assertEqual(self.enigma31.notch_positions, ([18], [5], [1])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'yptzuhofqvnmlkgbixwcejsrad') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (3, 11, 0)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'iex') - self.assertEqual(self.enigma31.peg_positions, ([8], [21], [24])) + self.assertEqual(self.enigma31.notch_positions, ([18], [5], [2])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'vkdcwhqfjibzsptngumoraeyxl') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (3, 11, 1)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'iey') - self.assertEqual(self.enigma31.peg_positions, ([8], [21], [23])) + self.assertEqual(self.enigma31.notch_positions, ([18], [5], [3])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'wenpbqrouxlkychdfgzvitajms') def test_double_advance_with_ring_settings_2(self): self.enigma31.set_wheels('a', 'y', 't') + # self.assertEqual(self.enigma31.wheel_positions, (21, 5, 22)) + # self.assertEqual(cat(self.enigma31.wheel_positions_l), 'ayt') + # self.assertEqual(self.enigma31.notch_positions, ([16], [1], [2])) + + # self.enigma31.advance() + # self.assertEqual(self.enigma31.wheel_positions, (21, 5, 23)) + # self.assertEqual(cat(self.enigma31.wheel_positions_l), 'ayu') + # self.assertEqual(self.enigma31.notch_positions, ([16], [1], [1])) + + # self.enigma31.advance() + # self.assertEqual(self.enigma31.wheel_positions, (21, 5, 24)) + # self.assertEqual(cat(self.enigma31.wheel_positions_l), 'ayv') + # self.assertEqual(self.enigma31.notch_positions, ([16], [1], [0])) + + # self.enigma31.advance() + # self.assertEqual(self.enigma31.wheel_positions, (21, 6, 25)) + # self.assertEqual(cat(self.enigma31.wheel_positions_l), 'azw') + # self.assertEqual(self.enigma31.notch_positions, ([16], [0], [25])) + + # self.enigma31.advance() + # self.assertEqual(self.enigma31.wheel_positions, (22, 7, 0)) + # self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bax') + # self.assertEqual(self.enigma31.notch_positions, ([15], [25], [24])) + + # self.enigma31.advance() + # self.assertEqual(self.enigma31.wheel_positions, (22, 7, 1)) + # self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bay') + # self.assertEqual(self.enigma31.notch_positions, ([15], [25], [23])) + self.assertEqual(self.enigma31.wheel_positions, (21, 5, 22)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'ayt') - self.assertEqual(self.enigma31.peg_positions, ([16], [1], [2])) + self.assertEqual(self.enigma31.notch_positions, ([10], [25], [24])) + assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'izhrgtecaslkywvqpdjfxonumb') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (21, 5, 23)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'ayu') - self.assertEqual(self.enigma31.peg_positions, ([16], [1], [1])) + self.assertEqual(self.enigma31.notch_positions, ([10], [25], [25])) + assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'dtoavihgflwjnmcsrqpbzekyxu') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (21, 5, 24)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'ayv') - self.assertEqual(self.enigma31.peg_positions, ([16], [1], [0])) + self.assertEqual(self.enigma31.notch_positions, ([10], [25], [0])) + assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'xquhtpsdwkjonmlfbvgecriazy') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (21, 6, 25)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'azw') - self.assertEqual(self.enigma31.peg_positions, ([16], [0], [25])) + self.assertEqual(self.enigma31.notch_positions, ([10], [0], [1])) + assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'dofapcluvmngjkbezyxwhitsrq') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (22, 7, 0)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bax') - self.assertEqual(self.enigma31.peg_positions, ([15], [25], [24])) + self.assertEqual(self.enigma31.notch_positions, ([11], [1], [2])) + assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'jdlbmswztapcexrkuofiqygnvh') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (22, 7, 1)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bay') - self.assertEqual(self.enigma31.peg_positions, ([15], [25], [23])) + self.assertEqual(self.enigma31.notch_positions, ([11], [1], [3])) + assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'iydcnuhgawsoxelztvkqfrjmbp') + self.enigma31.set_wheels('a', 'z', 't') + # self.assertEqual(self.enigma31.wheel_positions, (21, 6, 22)) + # self.assertEqual(cat(self.enigma31.wheel_positions_l), 'azt') + # self.assertEqual(self.enigma31.notch_positions, ([16], [0], [2])) + + # self.enigma31.advance() + # self.assertEqual(self.enigma31.wheel_positions, (22, 7, 23)) + # self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bau') + # self.assertEqual(self.enigma31.notch_positions, ([15], [25], [1])) + + # self.enigma31.advance() + # self.assertEqual(self.enigma31.wheel_positions, (22, 7, 24)) + # self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bav') + # self.assertEqual(self.enigma31.notch_positions, ([15], [25], [0])) + + # self.enigma31.advance() + # self.assertEqual(self.enigma31.wheel_positions, (22, 8, 25)) + # self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bbw') + # self.assertEqual(self.enigma31.notch_positions, ([15], [24], [25])) + + # self.enigma31.advance() + # self.assertEqual(self.enigma31.wheel_positions, (22, 8, 0)) + # self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bbx') + # self.assertEqual(self.enigma31.notch_positions, ([15], [24], [24])) + + # self.enigma31.advance() + # self.assertEqual(self.enigma31.wheel_positions, (22, 8, 1)) + # self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bby') + # self.assertEqual(self.enigma31.notch_positions, ([15], [24], [23])) + self.assertEqual(self.enigma31.wheel_positions, (21, 6, 22)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'azt') - self.assertEqual(self.enigma31.peg_positions, ([16], [0], [2])) + self.assertEqual(self.enigma31.notch_positions, ([10], [0], [24])) + assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'idjbptqwacsvnmregokfzlhyxu') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (22, 7, 23)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bau') - self.assertEqual(self.enigma31.peg_positions, ([15], [25], [1])) + self.assertEqual(self.enigma31.notch_positions, ([11], [1], [25])) + assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'rniszouwcxtvqbfymadkglhjpe') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (22, 7, 24)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bav') - self.assertEqual(self.enigma31.peg_positions, ([15], [25], [0])) + self.assertEqual(self.enigma31.notch_positions, ([11], [1], [0])) + assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'qijfsdmkbchugxtwazeolypnvr') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (22, 8, 25)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bbw') - self.assertEqual(self.enigma31.peg_positions, ([15], [24], [25])) + self.assertEqual(self.enigma31.notch_positions, ([11], [2], [1])) + assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'xprtlozyskjewqfbncidvumahg') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (22, 8, 0)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bbx') - self.assertEqual(self.enigma31.peg_positions, ([15], [24], [24])) + self.assertEqual(self.enigma31.notch_positions, ([11], [2], [2])) + assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'vtfuyczoqxmpkwhlisrbdanjeg') self.enigma31.advance() self.assertEqual(self.enigma31.wheel_positions, (22, 8, 1)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'bby') - self.assertEqual(self.enigma31.peg_positions, ([15], [24], [23])) + self.assertEqual(self.enigma31.notch_positions, ([11], [2], [3])) + assert(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase) == 'tjrhzpqdobwxyuifgcvansklme') def test_encipher_with_ring(self): @@ -751,7 +822,7 @@ class EnigmaTest(unittest.TestCase): 'apocwtjuikurcfivlozvhffkoacxufcekthcvodfqpxdjqyckdozlqki') self.assertEqual(self.enigma31.wheel_positions, (4, 9, 10)) self.assertEqual(cat(self.enigma31.wheel_positions_l), 'jch') - self.assertEqual(self.enigma31.peg_positions, ([7], [23], [14])) + self.assertEqual(self.enigma31.notch_positions, ([19], [3], [12])) self.assertEqual(cat(self.enigma31.lookup(l) for l in string.ascii_lowercase), 'mopnigfuesqwadbcktjrhylzvx') -- 2.34.1