{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import string\n", "import collections\n", "import multiprocessing\n", "import itertools\n", "from enigma import *" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true }, "outputs": [], "source": [ "Signal = collections.namedtuple('Signal', ['bank', 'wire'])\n", "Connection = collections.namedtuple('Connection', ['banks', 'scrambler'])\n", "MenuItem = collections.namedtuple('MenuIem', ['before', 'after', 'number'])" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class Scrambler(object):\n", " def __init__(self, wheel1_spec, wheel2_spec, wheel3_spec, reflector_spec,\n", " wheel1_pos='a', wheel2_pos='a', wheel3_pos='a'):\n", " self.wheel1 = SimpleWheel(wheel1_spec, position=wheel1_pos)\n", " self.wheel2 = SimpleWheel(wheel2_spec, position=wheel2_pos)\n", " self.wheel3 = SimpleWheel(wheel3_spec, position=wheel3_pos)\n", " self.reflector = Reflector(reflector_spec)\n", " \n", " def __getattribute__(self, name):\n", " if name=='wheel_positions':\n", " return self.wheel1.position, self.wheel2.position, self.wheel3.position \n", " elif name=='wheel_positions_l':\n", " return self.wheel1.position_l, self.wheel2.position_l, self.wheel3.position_l \n", " else:\n", " return object.__getattribute__(self, name)\n", " \n", " def advance(self, wheel1=False, wheel2=False, wheel3=True):\n", " if wheel1: self.wheel1.advance()\n", " if wheel2: self.wheel2.advance()\n", " if wheel3: self.wheel3.advance()\n", " \n", " def lookup(self, letter):\n", " a = self.wheel3.forward(letter)\n", " b = self.wheel2.forward(a)\n", " c = self.wheel1.forward(b)\n", " d = self.reflector.forward(c)\n", " e = self.wheel1.backward(d)\n", " f = self.wheel2.backward(e)\n", " g = self.wheel3.backward(f)\n", " return g\n", " \n", " def set_positions(self, wheel1_pos, wheel2_pos, wheel3_pos):\n", " self.wheel1.set_position(wheel1_pos)\n", " self.wheel2.set_position(wheel2_pos)\n", " self.wheel3.set_position(wheel3_pos) " ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class Bombe(object):\n", " \n", " def __init__(self, wheel1_spec, wheel2_spec, wheel3_spec, reflector_spec,\n", " menu=None, start_signal=None, use_diagonal_board=True, \n", " verify_plugboard=True):\n", " self.connections = []\n", " self.wheel1_spec = wheel1_spec\n", " self.wheel2_spec = wheel2_spec\n", " self.wheel3_spec = wheel3_spec\n", " self.reflector_spec = reflector_spec\n", " if menu:\n", " self.read_menu(menu)\n", " if start_signal:\n", " self.test_start = start_signal\n", " self.use_diagonal_board = use_diagonal_board\n", " self.verify_plugboard = verify_plugboard\n", " \n", " def __getattribute__(self, name):\n", " if name=='wheel_positions':\n", " return self.connections[0].scrambler.wheel_positions\n", " elif name=='wheel_positions_l':\n", " return self.connections[0].scrambler.wheel_positions_l\n", " else:\n", " return object.__getattribute__(self, name)\n", " \n", " def __call__(self, start_positions):\n", " return start_positions, self.test(initial_signal=self.test_start,\n", " start_positions=start_positions, \n", " use_diagonal_board=self.use_diagonal_board,\n", " verify_plugboard=self.verify_plugboard)\n", " \n", " def add_connection(self, bank_before, bank_after, scrambler):\n", " self.connections += [Connection([bank_before, bank_after], scrambler)]\n", " \n", " def read_menu(self, menu):\n", " self.connections = []\n", " for item in menu:\n", " scrambler = Scrambler(self.wheel1_spec, self.wheel2_spec, self.wheel3_spec,\n", " self.reflector_spec,\n", " wheel3_pos=unpos(item.number - 1))\n", " self.add_connection(item.before, item.after, scrambler)\n", " most_common_letter = (collections.Counter(m.before for m in menu) + \\\n", " collections.Counter(m.after for m in menu)).most_common(1)[0][0]\n", " self.test_start = Signal(most_common_letter, most_common_letter)\n", " \n", " def set_positions(self, wheel1_pos, wheel2_pos, wheel3_pos):\n", " for i, c in enumerate(self.connections):\n", " c.scrambler.set_positions(wheel1_pos, wheel2_pos, unpos(pos(wheel3_pos) + i))\n", " \n", " def test(self, initial_signal=None, start_positions=None, use_diagonal_board=True,\n", " verify_plugboard=True):\n", " self.banks = {label: \n", " dict(zip(string.ascii_lowercase, [False]*len(string.ascii_lowercase)))\n", " for label in string.ascii_lowercase}\n", " if start_positions:\n", " self.set_positions(*start_positions)\n", " if not initial_signal:\n", " initial_signal = self.test_start\n", " self.pending = [initial_signal]\n", " self.propagate(use_diagonal_board)\n", " live_wire_count = len([self.banks[self.test_start.bank][w] \n", " for w in self.banks[self.test_start.bank] \n", " if self.banks[self.test_start.bank][w]])\n", " if live_wire_count < 26:\n", " if verify_plugboard:\n", " possibles = self.possible_plugboards()\n", " return all(s0.isdisjoint(s1) for s0 in possibles for s1 in possibles if s0 != s1)\n", " else:\n", " return True\n", " else:\n", " return False\n", " \n", " def propagate(self, use_diagonal_board):\n", " while self.pending:\n", " current = self.pending[0]\n", " # print(\"processing\", current)\n", " self.pending = self.pending[1:]\n", " if not self.banks[current.bank][current.wire]:\n", " self.banks[current.bank][current.wire] = True\n", " if use_diagonal_board:\n", " self.pending += [Signal(current.wire, current.bank)]\n", " for c in self.connections:\n", " if current.bank in c.banks:\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", " \n", " def run(self, run_start=None, wheel1_pos='a', wheel2_pos='a', wheel3_pos='a', use_diagonal_board=True):\n", " if not run_start:\n", " run_start = self.test_start\n", " self.solutions = []\n", " self.set_positions(wheel1_pos, wheel2_pos, wheel3_pos)\n", " for run_index in range(26*26*26):\n", " if self.test(initial_signal=run_start, use_diagonal_board=use_diagonal_board):\n", " self.solutions += [self.connections[0].scrambler.wheel_positions_l]\n", " advance3 = True\n", " advance2 = False\n", " advance1 = False\n", " if (run_index + 1) % 26 == 0: advance2 = True\n", " if (run_index + 1) % (26*26) == 0: advance1 = True\n", " for c in self.connections:\n", " c.scrambler.advance(advance1, advance2, advance3)\n", " return self.solutions\n", " \n", " def possible_plugboards(self):\n", " possibles = set()\n", " for b in self.banks:\n", " active = [w for w in self.banks[b] if self.banks[b][w]]\n", " inactive = [w for w in self.banks[b] if not self.banks[b][w]]\n", " if len(active) == 1:\n", " possibles = possibles.union({frozenset((b, active[0]))})\n", " if len(inactive) == 1:\n", " possibles = possibles.union({frozenset((b, inactive[0]))})\n", " return possibles\n" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": true }, "outputs": [], "source": [ "bombe = Bombe(wheel_i_spec, wheel_ii_spec, wheel_iii_spec, reflector_b_spec)\n", "# len(bombe.banks), bombe.banks['a'] == bombe.banks['b']" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": true }, "outputs": [], "source": [ "test_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": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'opgndxcrwomnlnecjz'" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "test_enigma.set_wheels('a', 'a', 'a')\n", "pt = 'thisisatestmessage'\n", "ct = test_enigma.encipher(pt)\n", "ct" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'aas'" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cat(test_enigma.wheel_positions_l)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[MenuIem(before='t', after='o', number=1),\n", " MenuIem(before='h', after='p', number=2),\n", " MenuIem(before='i', after='g', number=3),\n", " MenuIem(before='s', after='n', number=4),\n", " MenuIem(before='i', after='d', number=5),\n", " MenuIem(before='s', after='x', number=6),\n", " MenuIem(before='a', after='c', number=7),\n", " MenuIem(before='t', after='r', number=8),\n", " MenuIem(before='e', after='w', number=9),\n", " MenuIem(before='s', after='o', number=10),\n", " MenuIem(before='t', after='m', number=11),\n", " MenuIem(before='m', after='n', number=12),\n", " MenuIem(before='e', after='l', number=13),\n", " MenuIem(before='s', after='n', number=14),\n", " MenuIem(before='s', after='e', number=15),\n", " MenuIem(before='a', after='c', number=16),\n", " MenuIem(before='g', after='j', number=17),\n", " MenuIem(before='e', after='z', number=18)]" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "menu = [MenuItem(p, c, i+1) for i, (p, c) in enumerate(zip(pt, ct))]\n", "menu" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def make_menu(plaintext, ciphertext):\n", " return [MenuItem(p, c, i+1) \n", " for i, (p, c) in enumerate(zip(plaintext, ciphertext))]" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[MenuIem(before='t', after='o', number=1),\n", " MenuIem(before='h', after='p', number=2),\n", " MenuIem(before='i', after='g', number=3),\n", " MenuIem(before='s', after='n', number=4),\n", " MenuIem(before='i', after='d', number=5),\n", " MenuIem(before='s', after='x', number=6),\n", " MenuIem(before='a', after='c', number=7),\n", " MenuIem(before='t', after='r', number=8),\n", " MenuIem(before='e', after='w', number=9),\n", " MenuIem(before='s', after='o', number=10),\n", " MenuIem(before='t', after='m', number=11),\n", " MenuIem(before='m', after='n', number=12),\n", " MenuIem(before='e', after='l', number=13),\n", " MenuIem(before='s', after='n', number=14),\n", " MenuIem(before='s', after='e', number=15),\n", " MenuIem(before='a', after='c', number=16),\n", " MenuIem(before='g', after='j', number=17),\n", " MenuIem(before='e', after='z', number=18)]" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "make_menu(pt, ct)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'s'" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(collections.Counter(m.before for m in menu) + collections.Counter(m.after for m in menu)).most_common(1)[0][0]" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": true }, "outputs": [], "source": [ "bombe.read_menu(menu)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "18" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(bombe.connections)" ] }, { "cell_type": "code", "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" ] } ], "source": [ "for c in bombe.connections:\n", " print(c.banks, cat(c.scrambler.wheel_positions_l))" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'ot:hp:gi:ns:di:sx:ac:rt:ew:os:mt:mn:el:ns:es:ac:gj:ez'" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "':'.join(cat(sorted(c.banks)) for c in bombe.connections)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'aaa:aab:aac:aad:aae:aaf:aag:aah:aai:aaj:aak:aal:aam:aan:aao:aap:aaq:aar'" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "':'.join(cat(c.scrambler.wheel_positions_l) for c in bombe.connections)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bombe.test(Signal('t', 't'))" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'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': True,\n", " 'v': True,\n", " 'w': True,\n", " 'x': True,\n", " 'y': True,\n", " 'z': True}" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bombe.banks['t']" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n", "b : AbCDEfGHIJkLMNOPqRSTuvWXyZ\n", "c : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n", "d : ABCDEFGHIJKLMNOPQRSTUVWXyZ\n", "e : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n", "f : AbCDEfGHIJkLMNOPqRSTuvWXyZ\n", "g : ABCDEFGHIJKLMNOPQRSTuVWXYZ\n", "h : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n", "i : ABCDEFGHIJKLMNOPQRSTUvWXYZ\n", "j : ABCDEFGHIjKLMNOPQRSTUVWXYZ\n", "k : AbCDEfGHIJkLMNOPqRSTuvWXyZ\n", "l : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n", "m : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n", "n : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n", "o : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n", "p : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n", "q : AbCDEfGHIJkLMNOPqRSTuvWXyZ\n", "r : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n", "s : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n", "t : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n", "u : AbCDEfgHIJkLMNOPqRSTuvWXyZ\n", "v : AbCDEfGHiJkLMNOPqRSTuvWXyZ\n", "w : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n", "x : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n", "y : AbCdEfGHIJkLMNOPqRSTuvWXyZ\n", "z : ABCDEFGHIJKLMNOPQRSTUVWXYZ\n" ] } ], "source": [ "for b in sorted(bombe.banks):\n", " print(b, ': ', end='')\n", " for w in sorted(bombe.banks[b]):\n", " if bombe.banks[b][w]:\n", " print(w.upper(), end='')\n", " else:\n", " print(w, end='')\n", " print('')" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a : abcdefghijklmnopqrstuvwxyz\n", "b : a.cde.ghij.lmnop.rst..wx.z\n", "c : abcdefghijklmnopqrstuvwxyz\n", "d : abcdefghijklmnopqrstuvwx.z\n", "e : abcdefghijklmnopqrstuvwxyz\n", "f : a.cde.ghij.lmnop.rst..wx.z\n", "g : abcdefghijklmnopqrst.vwxyz\n", "h : abcdefghijklmnopqrstuvwxyz\n", "i : abcdefghijklmnopqrstu.wxyz\n", "j : abcdefghi.klmnopqrstuvwxyz\n", "k : a.cde.ghij.lmnop.rst..wx.z\n", "l : abcdefghijklmnopqrstuvwxyz\n", "m : abcdefghijklmnopqrstuvwxyz\n", "n : abcdefghijklmnopqrstuvwxyz\n", "o : abcdefghijklmnopqrstuvwxyz\n", "p : abcdefghijklmnopqrstuvwxyz\n", "q : a.cde.ghij.lmnop.rst..wx.z\n", "r : abcdefghijklmnopqrstuvwxyz\n", "s : abcdefghijklmnopqrstuvwxyz\n", "t : abcdefghijklmnopqrstuvwxyz\n", "u : a.cde..hij.lmnop.rst..wx.z\n", "v : a.cde.gh.j.lmnop.rst..wx.z\n", "w : abcdefghijklmnopqrstuvwxyz\n", "x : abcdefghijklmnopqrstuvwxyz\n", "y : a.c.e.ghij.lmnop.rst..wx.z\n", "z : abcdefghijklmnopqrstuvwxyz\n" ] } ], "source": [ "for b in sorted(bombe.banks):\n", " print(b, ': ', end='')\n", " for w in sorted(bombe.banks[b]):\n", " if bombe.banks[b][w]:\n", " print(w, end='')\n", " else:\n", " print('.', end='')\n", " print('')" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('a', 'a', 'a')" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bombe.wheel_positions_l" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['t', 'o'] pqr\n", "['h', 'p'] pqs\n", "['i', 'g'] pqt\n", "['s', 'n'] pqu\n", "['i', 'd'] pqv\n", "['s', 'x'] pqw\n", "['a', 'c'] pqx\n", "['t', 'r'] pqy\n", "['e', 'w'] pqz\n", "['s', 'o'] pqa\n", "['t', 'm'] pqb\n", "['m', 'n'] pqc\n", "['e', 'l'] pqd\n", "['s', 'n'] pqe\n", "['s', 'e'] pqf\n", "['a', 'c'] pqg\n", "['g', 'j'] pqh\n", "['e', 'z'] pqi\n" ] } ], "source": [ "bombe.set_positions('p', 'q', 'r')\n", "for c in bombe.connections:\n", " print(c.banks, cat(c.scrambler.wheel_positions_l))" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# bombe.run()\n", "# print('x')" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a : .b.defghijklmnopqrstuvwxyz\n", "b : a.cde.ghij.lmnop.rst..wx.z\n", "c : .b.defghijklmnopqrstuvwxyz\n", "d : abc.e.gh.jklmnopqrstuvwxyz\n", "e : abcd.fghijklmnopqrstuvwxyz\n", "f : a.c.e.g.ij.lmno..rst..wx.z\n", "g : abcdef.h..klmnopqrstuvwxyz\n", "h : abcde.g.ij.lmno.qrst..wxyz\n", "i : abc.ef.h.jklmnopqrstuvwxyz\n", "j : abcdef.hi.klmnopqrstuvwx.z\n", "k : a.cde.g.ij.lmno..rst..wx.z\n", "l : abcdefghijk.mnopqrstuvwxyz\n", "m : abcdefghijkl.nopqrstuvwxyz\n", "n : abcdefghijklm.opqrstuvwxyz\n", "o : abcdefghijklmn.pqrstuvwxyz\n", "p : abcde.g.ij.lmno.qrst..wxyz\n", "q : a.cde.ghij.lmnop.rst..wx.z\n", "r : abcdefghijklmnopq.stuvwxyz\n", "s : abcdefghijklmnopqr.tuvwxyz\n", "t : abcdefghijklmnopqrs.uvwxyz\n", "u : a.cde.g.ij.lmno..rst..wx.z\n", "v : a.cde.g.ij.lmno..rst..wx.z\n", "w : abcdefghijklmnopqrstuv.xyz\n", "x : abcdefghijklmnopqrstuvw.yz\n", "y : a.cde.ghi..lmnop.rst..wx.z\n", "z : abcdefghijklmnopqrstuvwxy.\n" ] } ], "source": [ "bombe.set_positions('a', 'a', 'b')\n", "bombe.test(Signal('s', 'a'))\n", "\n", "for b in sorted(bombe.banks):\n", " print(b, ': ', end='')\n", " for w in sorted(bombe.banks[b]):\n", " if bombe.banks[b][w]:\n", " print(w, end='')\n", " else:\n", " print('.', end='')\n", " print('')" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a : ..........................\n", "b : ..........................\n", "c : ..........................\n", "d : ..........................\n", "e : ....e.....................\n", "f : ..........................\n", "g : ..........................\n", "h : ..........................\n", "i : ..........................\n", "j : ..........................\n", "k : ..........................\n", "l : ...........l..............\n", "m : ............m.............\n", "n : .............n............\n", "o : ..............o...........\n", "p : ..........................\n", "q : ..........................\n", "r : .................r........\n", "s : ..................s.......\n", "t : ...................t......\n", "u : ..........................\n", "v : ..........................\n", "w : ......................w...\n", "x : .......................x..\n", "y : ..........................\n", "z : .........................z\n" ] } ], "source": [ "bombe.set_positions('a', 'a', 'b')\n", "bombe.test()\n", "\n", "for b in sorted(bombe.banks):\n", " print(b, ': ', end='')\n", " for w in sorted(bombe.banks[b]):\n", " if bombe.banks[b][w]:\n", " print(w, end='')\n", " else:\n", " print('.', end='')\n", " print('')" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len([bombe.banks['t'][w] for w in bombe.banks['t'] if bombe.banks['t'][w]])" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# %%timeit\n", "# results = bombe.run()\n", "# print(len(results), ('a', 'a', 'b') in results)" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# %%timeit\n", "# results = bombe.run(use_diagonal_board=False)\n", "# print(len(results), ('a', 'a', 'b') in results)" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('a', 'a', 'b')" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bombe.wheel_positions_l" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bombe.test(Signal('t', 't'), ('p', 'p', 'p'))" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('p', 'p', 'p')" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bombe.wheel_positions_l" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a : abcdefghijklmnop.rst.vwxyz\n", "b : a.cde.g.ij.lmno..rst..wx.z\n", "c : abcdefghijklmnop.rst.vwxyz\n", "d : abcdefghijklmnopqrstuvwxyz\n", "e : abcdefghijklmnopqrstuvwxyz\n", "f : a.cde.g.ij.lmno..rst..wx.z\n", "g : abcdefghijklmnopqrstuvwxyz\n", "h : a.cde.ghijklmnop.rst.vwxyz\n", "i : abcdefghijklmnopqrstuvwxyz\n", "j : abcdefghijklmnopqrstuvwxyz\n", "k : a.cde.ghij.lmnop.rst..wx.z\n", "l : abcdefghijklmnopqrstuvwxyz\n", "m : abcdefghijklmnopqrstuvwxyz\n", "n : abcdefghijklmnopqrstuvwxyz\n", "o : abcdefghijklmnopqrstuvwxyz\n", "p : a.cde.ghijklmnop.rst.vwxyz\n", "q : ...de.g.ij.lmno..rst..wx.z\n", "r : abcdefghijklmnopqrstuvwxyz\n", "s : abcdefghijklmnopqrstuvwxyz\n", "t : abcdefghijklmnopqrstuvwxyz\n", "u : ...de.g.ij.lmno..rst..wx.z\n", "v : a.cde.ghij.lmnop.rst..wx.z\n", "w : abcdefghijklmnopqrstuvwxyz\n", "x : abcdefghijklmnopqrstuvwxyz\n", "y : a.cde.ghij.lmnop.rst..wx.z\n", "z : abcdefghijklmnopqrstuvwxyz\n" ] } ], "source": [ "for b in sorted(bombe.banks):\n", " print(b, ': ', end='')\n", " for w in sorted(bombe.banks[b]):\n", " if bombe.banks[b][w]:\n", " print(w, end='')\n", " else:\n", " print('.', end='')\n", " print('')" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "17576" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "allwheels = itertools.product(string.ascii_lowercase, repeat=3)\n", "len(list(allwheels))" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(('a', 'a', 'b'), True)" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "b = Bombe(wheel_i_spec, wheel_ii_spec, wheel_iii_spec, reflector_b_spec, menu=menu)\n", "b(('a', 'a', 'b'))" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "collapsed": true }, "outputs": [], "source": [ "b = Bombe(wheel_i_spec, wheel_ii_spec, wheel_iii_spec, reflector_b_spec, menu=menu)(('a', 'a', 'b'))" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[('a', 'a', 'b')]" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "allwheels = itertools.product(string.ascii_lowercase, repeat=3)\n", "\n", "with multiprocessing.Pool() as pool:\n", " res = pool.map(Bombe(wheel_i_spec, wheel_ii_spec, wheel_iii_spec, reflector_b_spec, menu=menu),\n", " allwheels)\n", "[r[0] for r in res if r[1]]" ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def run_multi_bombe(wheel1_spec, wheel2_spec, wheel3_spec, reflector_spec, menu,\n", " start_signal=None, use_diagonal_board=True, \n", " verify_plugboard=True):\n", " allwheels = itertools.product(string.ascii_lowercase, repeat=3)\n", "\n", " with multiprocessing.Pool() as pool:\n", " res = pool.map(Bombe(wheel1_spec, wheel2_spec, wheel3_spec, \n", " reflector_spec, menu=menu, start_signal=start_signal, \n", " use_diagonal_board=use_diagonal_board, \n", " verify_plugboard=verify_plugboard),\n", " allwheels)\n", " return [r[0] for r in res if r[1]]" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[('a', 'a', 'b')]" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[r[0] for r in res if r[1]]" ] }, { "cell_type": "code", "execution_count": 40, "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": 41, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('e', 'l', 'e')" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "w_enigma.set_wheels('j', 'e', 'b')\n", "tuple(unpos(p) for p in w_enigma.wheel_positions)" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'dhnpforeeimgg'" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "w_enigma.set_wheels('j', 'e', 'b')\n", "pt = 'someplaintext'\n", "ct = w_enigma.encipher(pt)\n", "ct" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('j', 'e', 'o')" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "w_enigma.wheel_positions_l" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[MenuIem(before='s', after='d', number=1),\n", " MenuIem(before='o', after='h', number=2),\n", " MenuIem(before='m', after='n', number=3),\n", " MenuIem(before='e', after='p', number=4),\n", " MenuIem(before='p', after='f', number=5),\n", " MenuIem(before='l', after='o', number=6),\n", " MenuIem(before='a', after='r', number=7),\n", " MenuIem(before='i', after='e', number=8),\n", " MenuIem(before='n', after='e', number=9),\n", " MenuIem(before='t', after='i', number=10),\n", " MenuIem(before='e', after='m', number=11),\n", " MenuIem(before='x', after='g', number=12),\n", " MenuIem(before='t', after='g', number=13)]" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "w_menu = [MenuItem(p, c, i+1) for i, (p, c) in enumerate(zip(pt, ct))]\n", "w_menu" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "[('a', 'y', 'm'),\n", " ('c', 'p', 'v'),\n", " ('c', 's', 'f'),\n", " ('c', 'w', 'j'),\n", " ('d', 'r', 'k'),\n", " ('e', 'l', 'f'),\n", " ('e', 's', 'v'),\n", " ('e', 'y', 'd'),\n", " ('e', 'y', 'o'),\n", " ('f', 'z', 'x'),\n", " ('g', 'b', 'l'),\n", " ('g', 'c', 'd'),\n", " ('g', 'c', 'f'),\n", " ('g', 'j', 'p'),\n", " ('h', 'c', 'i'),\n", " ('h', 'm', 'w'),\n", " ('h', 'o', 'd'),\n", " ('h', 'p', 'b'),\n", " ('h', 's', 't'),\n", " ('i', 'b', 's'),\n", " ('i', 'v', 'b'),\n", " ('j', 'y', 'u'),\n", " ('k', 'b', 'x'),\n", " ('k', 'f', 't'),\n", " ('k', 'l', 'e'),\n", " ('k', 'l', 'm'),\n", " ('k', 'r', 'z'),\n", " ('k', 's', 'p'),\n", " ('l', 'd', 'z'),\n", " ('l', 'i', 'y'),\n", " ('l', 'y', 'f'),\n", " ('m', 'b', 'h'),\n", " ('m', 'p', 'l'),\n", " ('n', 'l', 'r'),\n", " ('o', 'k', 'x'),\n", " ('p', 'a', 'g'),\n", " ('p', 'c', 'v'),\n", " ('p', 'f', 'o'),\n", " ('p', 'm', 'i'),\n", " ('p', 'x', 'n'),\n", " ('p', 'x', 'p'),\n", " ('q', 'q', 'n'),\n", " ('q', 'r', 'w'),\n", " ('q', 'v', 'l'),\n", " ('q', 'x', 't'),\n", " ('s', 'a', 'h'),\n", " ('s', 'h', 'v'),\n", " ('s', 'l', 'p'),\n", " ('s', 'l', 's'),\n", " ('u', 'r', 'h'),\n", " ('v', 'v', 'v'),\n", " ('v', 'x', 'a'),\n", " ('w', 'j', 'z'),\n", " ('w', 'k', 'u'),\n", " ('x', 'f', 'p'),\n", " ('x', 'j', 'n'),\n", " ('x', 'o', 'q'),\n", " ('x', 'x', 'x'),\n", " ('y', 'n', 'c'),\n", " ('y', 'r', 'f'),\n", " ('z', 't', 'y'),\n", " ('z', 'z', 'k')]" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "allwheels = itertools.product(string.ascii_lowercase, repeat=3)\n", "\n", "with multiprocessing.Pool() as pool:\n", " res = pool.map(Bombe(wheel_i_spec, wheel_v_spec, wheel_iii_spec, reflector_b_spec, \n", " menu=w_menu, verify_plugboard=False),\n", " allwheels)\n", "[r[0] for r in res if r[1]]" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "62" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len([r[0] for r in res if r[1]])" ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "[('c', 'p', 'v'),\n", " ('c', 's', 'f'),\n", " ('e', 'l', 'f'),\n", " ('g', 'c', 'f'),\n", " ('j', 'y', 'u'),\n", " ('o', 'k', 'x'),\n", " ('p', 'a', 'g'),\n", " ('q', 'q', 'n'),\n", " ('q', 'v', 'l'),\n", " ('q', 'x', 't'),\n", " ('s', 'l', 'p'),\n", " ('u', 'r', 'h'),\n", " ('y', 'n', 'c')]" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "allwheels = itertools.product(string.ascii_lowercase, repeat=3)\n", "\n", "with multiprocessing.Pool() as pool:\n", " res = pool.map(Bombe(wheel_i_spec, wheel_v_spec, wheel_iii_spec, reflector_b_spec, \n", " menu=w_menu, verify_plugboard=True),\n", " allwheels)\n", "[r[0] for r in res if r[1]]" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[('c', 'p', 'v'),\n", " ('c', 's', 'f'),\n", " ('e', 'l', 'f'),\n", " ('g', 'c', 'f'),\n", " ('j', 'y', 'u'),\n", " ('o', 'k', 'x'),\n", " ('p', 'a', 'g'),\n", " ('q', 'q', 'n'),\n", " ('q', 'v', 'l'),\n", " ('q', 'x', 't'),\n", " ('s', 'l', 'p'),\n", " ('u', 'r', 'h'),\n", " ('y', 'n', 'c')]" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "run_multi_bombe(wheel_i_spec, wheel_v_spec, wheel_iii_spec, reflector_b_spec, w_menu)" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# allwheels = itertools.product(string.ascii_lowercase, repeat=3)\n", "\n", "# with multiprocessing.Pool() as pool:\n", "# res = pool.map(Bombe(wheel_i_spec, wheel_v_spec, wheel_iii_spec, reflector_b_spec, \n", "# menu=w_menu, start_signal=Signal('t', 'x')),\n", "# allwheels)\n", "# [r[0] for r in res if r[1]]" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "13" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len([r[0] for r in res if r[1]])" ] }, { "cell_type": "code", "execution_count": 51, "metadata": { "collapsed": true }, "outputs": [], "source": [ "w_bombe = Bombe(wheel_i_spec, wheel_v_spec, wheel_iii_spec, reflector_b_spec, \n", " menu=w_menu)" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Signal(bank='e', wire='e')" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "w_bombe.test_start" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "w_bombe.test(start_positions=('e', 'l', 'f'))" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "w_bombe.test(Signal('t', 'x'), ('e', 'l', 'f'))" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n", "a : a.cdefghi..l.nopqrst.vwx..\n", "b : ....efghi...mnop.......x..\n", "c : a....fg.i..lmn.p.r.t...x..\n", "d : a...efghij.lmn...rstu..xyz\n", "e : ab.defghijklmnopqrstuvwxyz\n", "f : abcde.ghijklmnopqrstuvwxyz\n", "g : abcdef.hijklmnopqrstuvwxyz\n", "h : ab.defghi...mnopq.stuvwx..\n", "i : abcdefgh.jklmnopqrstuvwxyz\n", "j : ...defg.i...mn.p...t...x..\n", "k : ....efg.i..lmnop.r.t...x..\n", "l : a.cdefg.i.k.mnopqr.t..wxyz\n", "m : .bcdefghijklmnopqrstuvwxyz\n", "n : abcdefghijklmnopqr.tuvwxyz\n", "o : ab..efghi.klmnopqr.t...xyz\n", "p : abc.efghijklmnopqrstuvwxyz\n", "q : a...efghi..lmnop.r.t...x..\n", "r : a.cdefg.i.klmnopqrst..w..z\n", "s : a..defghi...m..p.rstuv.xyz\n", "t : a.cdefghijklmnopqrstuvwxyz\n", "u : ...defghi...mn.p..st...x..\n", "v : a...efghi...mn.p..st...x..\n", "w : a...efghi..lmn.p.r.t...x..\n", "x : abcdefghijklmnopq.stuvwxyz\n", "y : ...defg.i..lmnop..st...x..\n", "z : ...defg.i..lmnop.rst...x..\n" ] } ], "source": [ "r = w_bombe.test(start_positions=('c', 'p', 'v'))\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('')" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\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 = w_bombe.test(start_positions=('e', 'l', 'f'))\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('')" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{frozenset({'t', 'x'}),\n", " frozenset({'i', 'n'}),\n", " frozenset({'m'}),\n", " frozenset({'e', 'y'}),\n", " frozenset({'f', 'p'}),\n", " frozenset({'b', 'g'})}" ] }, "execution_count": 57, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ps = w_bombe.possible_plugboards()\n", "ps" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" } ], "source": [ "all(s0.isdisjoint(s1) for s0 in ps for s1 in ps if s0 != s1)" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "({frozenset({1, 2}), frozenset({2, 3}), frozenset({3, 4})},\n", " frozenset({1, 2}),\n", " frozenset({3, 4}),\n", " frozenset({2, 3}))" ] }, "execution_count": 59, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s = set()\n", "f1 = frozenset((1, 2))\n", "f2 = frozenset((3, 4))\n", "f3 = frozenset((2, 3))\n", "s = s.union({f1})\n", "s = s.union({f2})\n", "s = s.union({f1})\n", "s = s.union({f3})\n", "s, f1, f2, f3" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 60, "metadata": {}, "output_type": "execute_result" } ], "source": [ "all(s0.isdisjoint(s1) for s0 in s for s1 in s if s0 != s1)" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "{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, "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 }