{ "cells": [ { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import os,sys,inspect, collections\n", "currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))\n", "parentdir = os.path.dirname(currentdir)\n", "sys.path.insert(0,parentdir) \n", "\n", "import matplotlib.pyplot as plt\n", "%matplotlib inline\n", "\n", "from cipherbreak import *\n", "\n", "ca = open('3a.ciphertext').read()\n", "cb = open('3b.ciphertext').read()" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'MHALEATASTIFETHOTSFETNRAFSSETFWTHEYAROLPOTTLEMATHPNFDAUUOOTMOTLARGSTIEETHEHODREATHEITHETINNWSRNITHETOUTAUOLOPALATBTNNVEIUNCETHEHFGERFCEIAUOLDASODVORTOGEYOUEDPBHASOICBMATHNFTTHESFWWNITNYOGIAUNLOORDHASTOLERTEDSUNFTSDEYEOTMNFLDHOVEPEERAREVATOPLEORDMATHATTHELNSSNYPIATORRAOHOVARGIEOLASEDTHOTTHEAUERAMEIEIEODARGHASUNCCFRAUOTANRSOGIAUNLOOIIORGEDTNWLORTYOLSEARYNICOTANROPNFTTHEWLORREDDASWNSATANRNYTINNWSSETTARGOTIOWARTNMHAUHTHEAUERAYELLATASSTALLFRULEOIHNMTHESOVOGETIAPESHODLEOIREDTNDEUAWHEINFIOICBSUNCCFRAUOTANRSOSTHEBHODRNMIATARGNYTHEAINMRHNMEVEIEVEIBOICBHOSATSTIOATNISORDATSEECSLAKELBTNCETHOTNRENICNIENYTHELNUOLTIAPESWENWLETFIREDSNCENRESHEODLNVENICNREBATASOLLTIEOUHEIBPFTTHASOUTTHIEOTEREDTNFRDEICARETHEECWAIESERTAIESBSTECNYSEUFIEUNCCFRAUOTANRTHEUOESOIUAWHEIWEIHOWSCNIETHORINODSHODEROPLEDTHEECWAIETNYFRUTANRSEUFIELBORDATSLNSSMOSODASOSTEITFIRARGTHOTLNSSARTNOVAUTNIBNRTHEPOTTLEYAELDDESEIVEDCNIEIEUNGRATANRTHORATIEUEAVEDWEIHOWSSFETNRAFSREVEIKREMNIWEIHOWSHEYOALEDTNFRDEISTORDTHEUFRRARGNYTHEWLORPFTEATHEIMOBDESWATETHEVAUTNIBOGIAUNLOORDTHERARTHLEGANRIECOAREDARDASGIOUENRHEOIARGTHASREMSULOFDAFSUOESOIOFGFSTFSGEICORAUFSREINECWEINIASSFEDOSEUIETWINULOCOTANRESTOPLASHARGOUAWHEISUHNNLTNDEVELNWOREMSBSTECNYACWEIAOLUAWHEISATMNIKEDARSEUIETYNINVEITMERTBBEOISDEVELNWARGREMCETHNDSTNSEUFIEUNCCFRAUOTANRSOUINSSTHEECWAIESTFDBARGTHEMNIKSNYTHEGIEEKSOGESEFULADORDHBWOTAOORDEVERNLDEIMNIKSYINCORUAERTPOPBLNRTHESUHNNLDEVELNWEDREMMOBSTNSOYEGFOIDUNCCFRAUOTANRSYINCINCESERECAESTHESEREMSBSTECSMEIEMIATTERDNMRORDDASTIAPFTEDARTHEUNDEXNUUFLTNIFCWEIHOWSTHECNSTSTIAUTLBGFOIDEDDNUFCERTAROLLHASTNIBMHERATMOSYAROLLBUNCWLETEDCORBBEOISLOTEITHEECWEINIDNCATAORASSFEDOREXEUFTAVENIDEIMHAUHWIEYOUEDEVEIBUNWBNYTHEUNDEXTHOTATMOSTNPEGFOIDEDPBEVEIBLEGANRTNTHELOSTCORTHEDEYEOTNYTHEAUERAORDTHESFAUADENYPNFDAUUOWEIHOWSWINTEUTEDTHERARTHLEGANRYINCDASSNLFTANROGIAUNLOMOSLOIGELBLEYTTNHASNMRDEVAUESARTHEWINVARUETHNFGHATMOSCODEULEOITNHACTHOTTNIETFIRMNFLDCEOROTPESTDASGIOUEORDOTMNISTDEOTHAROPIEOKMATHTIODATANRTHERARTHIOASEDOREMSTORDOIDTHELEGANRMOSEXALEDARDASGIOUETNERDFIETHEHOIDORDDORGEINFSMNIKNYSFPDFARGTHEUOLEDNRAAARTHEPLEOKMALDEIRESSESNYUOLEDNRAOSFETNRAFSNIDEIEDTHERARTHTNCOIUHTNEPNIOUFCMHAUHTHEBMEIETNCOKETHEAIPOSEYNIIOADSARTNUOLEDNRAOTHEFRSWNKERIEOSNRYNITHEAIEXALEMOSTHOTARTELLAGERUEIEWNITSSFGGESTEDTHOTTHASMOSMHEIETHEBCAGHTYARDTHEAILNSTOQFALOTHNSEMHNMNFLDIEODNRCFSTYNLLNMCBYOATHYFLSLOVETAINMHNYOUESOGIOVETOSKWEIHOWSTHELOIGESTTNDOTEOSHETIOVELSTNUNRUEOLTHEYNFITHUHOWTEINYTHASTIOGAUTOLE'" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "scb = sanitise(cb)\n", "scbp = chunks(scb, 2)\n", "order = 'xlcdm'\n", "ltrs = 'etoanisrhdlufcmwgybpvkxqz'\n", "prs = [p[0] for p in collections.Counter(chunks(sanitise(cb), 2)).most_common()]\n", "trans = {pr[1]: pr[0].upper() for pr in zip(ltrs, prs)}\n", "scbpt = cat(trans[p] for p in scbp)\n", "scbpt" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'MHALEATASTIFETHOTSFETNRAFSSETFWTHEYAROLPOTTLEMATHPNFDAUUOOTMOTLARGSTIEETHEHODREATHEITHETINNWSRNITHETOUTAUOLOPALATBTNNVEIUNCETHEHFGERFCEIAUOLDASODVORTOGEYOUEDPBHASOICBMATHNFTTHESFWWNITNYOGIAUNLOORDHASTOLERTEDSUNFTSDEYEOTMNFLDHOVEPEERAREVATOPLEORDMATHATTHELNSSNYPIATORRAOHOVARGIEOLASEDTHOTTHEAUERAMEIEIEODARGHASUNCCFRAUOTANRSOGIAUNLOOIIORGEDTNWLORTYOLSEARYNICOTANROPNFTTHEWLORREDDASWNSATANRNYTINNWSSETTARGOTIOWARTNMHAUHTHEAUERAYELLATASSTALLFRULEOIHNMTHESOVOGETIAPESHODLEOIREDTNDEUAWHEINFIOICBSUNCCFRAUOTANRSOSTHEBHODRNMIATARGNYTHEAINMRHNMEVEIEVEIBOICBHOSATSTIOATNISORDATSEECSLAKELBTNCETHOTNRENICNIENYTHELNUOLTIAPESWENWLETFIREDSNCENRESHEODLNVENICNREBATASOLLTIEOUHEIBPFTTHASOUTTHIEOTEREDTNFRDEICARETHEECWAIESERTAIESBSTECNYSEUFIEUNCCFRAUOTANRTHEUOESOIUAWHEIWEIHOWSCNIETHORINODSHODEROPLEDTHEECWAIETNYFRUTANRSEUFIELBORDATSLNSSMOSODASOSTEITFIRARGTHOTLNSSARTNOVAUTNIBNRTHEPOTTLEYAELDDESEIVEDCNIEIEUNGRATANRTHORATIEUEAVEDWEIHOWSSFETNRAFSREVEIKREMNIWEIHOWSHEYOALEDTNFRDEISTORDTHEUFRRARGNYTHEWLORPFTEATHEIMOBDESWATETHEVAUTNIBOGIAUNLOORDTHERARTHLEGANRIECOAREDARDASGIOUENRHEOIARGTHASREMSULOFDAFSUOESOIOFGFSTFSGEICORAUFSREINECWEINIASSFEDOSEUIETWINULOCOTANRESTOPLASHARGOUAWHEISUHNNLTNDEVELNWOREMSBSTECNYACWEIAOLUAWHEISATMNIKEDARSEUIETYNINVEITMERTBBEOISDEVELNWARGREMCETHNDSTNSEUFIEUNCCFRAUOTANRSOUINSSTHEECWAIESTFDBARGTHEMNIKSNYTHEGIEEKSOGESEFULADORDHBWOTAOORDEVERNLDEIMNIKSYINCORUAERTPOPBLNRTHESUHNNLDEVELNWEDREMMOBSTNSOYEGFOIDUNCCFRAUOTANRSYINCINCESERECAESTHESEREMSBSTECSMEIEMIATTERDNMRORDDASTIAPFTEDARTHEUNDEXNUUFLTNIFCWEIHOWSTHECNSTSTIAUTLBGFOIDEDDNUFCERTAROLLHASTNIBMHERATMOSYAROLLBUNCWLETEDCORBBEOISLOTEITHEECWEINIDNCATAORASSFEDOREXEUFTAVENIDEIMHAUHWIEYOUEDEVEIBUNWBNYTHEUNDEXTHOTATMOSTNPEGFOIDEDPBEVEIBLEGANRTNTHELOSTCORTHEDEYEOTNYTHEAUERAORDTHESFAUADENYPNFDAUUOWEIHOWSWINTEUTEDTHERARTHLEGANRYINCDASSNLFTANROGIAUNLOMOSLOIGELBLEYTTNHASNMRDEVAUESARTHEWINVARUETHNFGHATMOSCODEULEOITNHACTHOTTNIETFIRMNFLDCEOROTPESTDASGIOUEORDOTMNISTDEOTHAROPIEOKMATHTIODATANRTHERARTHIOASEDOREMSTORDOIDTHELEGANRMOSEXALEDARDASGIOUETNERDFIETHEHOIDORDDORGEINFSMNIKNYSFPDFARGTHEUOLEDNRAAARTHEPLEOKMALDEIRESSESNYUOLEDNRAOSFETNRAFSNIDEIEDTHERARTHTNCOIUHTNEPNIOUFCMHAUHTHEBMEIETNCOKETHEAIPOSEYNIIOADSARTNUOLEDNRAOTHEFRSWNKERIEOSNRYNITHEAIEXALEMOSTHOTARTELLAGERUEIEWNITSSFGGESTEDTHOTTHASMOSMHEIETHEBCAGHTYARDTHEAILNSTOQFALOTHNSEMHNMNFLDIEODNRCFSTYNLLNMCBYOATHYFLSLOVETAINMHNYOUESOGIOVETOSKWEIHOWSTHELOIGESTTNDOTEOSHETIOVELSTNUNRUEOLTHEYNFITHUHOWTEINYTHASTIOGAUTOLE'" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "trhc = ''.maketrans('abmdefghijklcnopqrstuvwxyz', string.ascii_lowercase)\n", "scbpt.translate(trhc)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "def polybius_grid(keyword, column_order, row_order, letters_to_merge=None,\n", " wrap_alphabet=KeywordWrapAlphabet.from_a):\n", " alphabet = keyword_cipher_alphabet_of(keyword, wrap_alphabet=wrap_alphabet)\n", " if letters_to_merge is None: \n", " letters_to_merge = {'j': 'i'}\n", " grid = {l: k \n", " for k, l in zip([(c, r) for c in column_order for r in row_order],\n", " [l for l in alphabet if l not in letters_to_merge])}\n", " for l in letters_to_merge:\n", " grid[l] = grid[letters_to_merge[l]]\n", " return grid " ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'a': ('x', 'x'),\n", " 'b': ('x', 'l'),\n", " 'c': ('x', 'c'),\n", " 'd': ('x', 'd'),\n", " 'e': ('x', 'm'),\n", " 'f': ('l', 'x'),\n", " 'g': ('l', 'l'),\n", " 'h': ('l', 'c'),\n", " 'i': ('l', 'd'),\n", " 'j': ('l', 'd'),\n", " 'k': ('l', 'm'),\n", " 'l': ('c', 'x'),\n", " 'm': ('c', 'l'),\n", " 'n': ('c', 'c'),\n", " 'o': ('c', 'd'),\n", " 'p': ('c', 'm'),\n", " 'q': ('d', 'x'),\n", " 'r': ('d', 'l'),\n", " 's': ('d', 'c'),\n", " 't': ('d', 'd'),\n", " 'u': ('d', 'm'),\n", " 'v': ('m', 'x'),\n", " 'w': ('m', 'l'),\n", " 'x': ('m', 'c'),\n", " 'y': ('m', 'd'),\n", " 'z': ('m', 'm')}" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_grid('', order, order)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'a': ('a', 'a'),\n", " 'b': ('a', 'b'),\n", " 'c': ('a', 'c'),\n", " 'd': ('a', 'd'),\n", " 'e': ('a', 'e'),\n", " 'f': ('b', 'a'),\n", " 'g': ('b', 'b'),\n", " 'h': ('b', 'c'),\n", " 'i': ('b', 'd'),\n", " 'j': ('b', 'd'),\n", " 'k': ('b', 'e'),\n", " 'l': ('c', 'a'),\n", " 'm': ('c', 'b'),\n", " 'n': ('c', 'c'),\n", " 'o': ('c', 'd'),\n", " 'p': ('c', 'e'),\n", " 'q': ('d', 'a'),\n", " 'r': ('d', 'b'),\n", " 's': ('d', 'c'),\n", " 't': ('d', 'd'),\n", " 'u': ('d', 'e'),\n", " 'v': ('e', 'a'),\n", " 'w': ('e', 'b'),\n", " 'x': ('e', 'c'),\n", " 'y': ('e', 'd'),\n", " 'z': ('e', 'e')}" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_grid('a', 'abcde', 'abcde')" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_grid('elephant', 'abcde', 'abcde')['b'] == ('b', 'c')" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_grid('elephant', 'abcde', 'abcde')['e'] == ('a', 'a')" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "def polybius_reverse_grid(keyword, column_order, row_order, letters_to_merge=None,\n", " wrap_alphabet=KeywordWrapAlphabet.from_a):\n", " alphabet = keyword_cipher_alphabet_of(keyword, wrap_alphabet=wrap_alphabet)\n", " if letters_to_merge is None: \n", " letters_to_merge = {'j': 'i'}\n", " grid = {k: l \n", " for k, l in zip([(c, r) for c in column_order for r in row_order],\n", " [l for l in alphabet if l not in letters_to_merge])}\n", "# for l in letters_to_merge:\n", "# for r, c in grid:\n", "# if grid[r, c] == letters_to_merge[l]:\n", "# grid[l] = grid[r, c]\n", " return grid " ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{('c', 'c'): 'n',\n", " ('c', 'd'): 'o',\n", " ('c', 'l'): 'm',\n", " ('c', 'm'): 'p',\n", " ('c', 'x'): 'l',\n", " ('d', 'c'): 's',\n", " ('d', 'd'): 't',\n", " ('d', 'l'): 'r',\n", " ('d', 'm'): 'u',\n", " ('d', 'x'): 'q',\n", " ('l', 'c'): 'h',\n", " ('l', 'd'): 'i',\n", " ('l', 'l'): 'g',\n", " ('l', 'm'): 'k',\n", " ('l', 'x'): 'f',\n", " ('m', 'c'): 'x',\n", " ('m', 'd'): 'y',\n", " ('m', 'l'): 'w',\n", " ('m', 'm'): 'z',\n", " ('m', 'x'): 'v',\n", " ('x', 'c'): 'c',\n", " ('x', 'd'): 'd',\n", " ('x', 'l'): 'b',\n", " ('x', 'm'): 'e',\n", " ('x', 'x'): 'a'}" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_reverse_grid('', order, order)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "def polybius_flatten(pair, column_first):\n", " if column_first:\n", " return str(pair[1]) + str(pair[0])\n", " else:\n", " return str(pair[0]) + str(pair[1])" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "def polybius_encipher(message, keyword, column_order, row_order, \n", " column_first=False,\n", " letters_to_merge=None, wrap_alphabet=KeywordWrapAlphabet.from_a): \n", " grid = polybius_grid(keyword, column_order, row_order, letters_to_merge, wrap_alphabet)\n", " return cat(polybius_flatten(grid[l], column_first)\n", " for l in message\n", " if l in grid)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'mllcldcxxmldddlddcdddldmxm'" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_encipher('while it is true', '', order, order)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'mllcldcxxmldddlddcdddldmxmddlcxxdddcdmxmddcdcclddmdcdcxmdddmcmddlcxmlxldccxxcxxlxxdd'" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sanitise(cb[:100])" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "def polybius_decipher(message, keyword, column_order, row_order, \n", " column_first=False,\n", " letters_to_merge=None, wrap_alphabet=KeywordWrapAlphabet.from_a): \n", " grid = polybius_reverse_grid(keyword, column_order, row_order, letters_to_merge, wrap_alphabet)\n", " column_index_type = type(column_order[0])\n", " row_index_type = type(row_order[0])\n", " if column_first:\n", " pairs = [(column_index_type(p[1]), row_index_type(p[0])) for p in chunks(message, 2)]\n", " else:\n", " pairs = [(row_index_type(p[0]), column_index_type(p[1])) for p in chunks(message, 2)]\n", " return cat(grid[p] for p in pairs if p in grid)" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'whileitistrue'" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_decipher('mllcldcxxmldddlddcdddldmxm', '', order, order)" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'lmcldlxcmxdldddlcdddldmdmx'" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_encipher('whileitistrue', '', order, order, column_first=True)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'kmrcvrtrotiyv'" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_decipher('lmcldlxcmxdldddlcdddldmdmx', '', order, order)" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'whileitistrue'" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_decipher('lmcldlxcmxdldddlcdddldmdmx', '', order, order, column_first=True)" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'52232431152444244344424515'" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_encipher('while it is true', '', '12345', '12345')" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'52232431152444244344424515'" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_encipher('while it is true', '', [1, 2, 3, 4, 5], [1, 2, 3, 4, 5])" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'whileitistrue'" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_decipher('52232431152444244344424515', '', [1, 2, 3, 4, 5], [1, 2, 3, 4, 5])" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [], "source": [ "from multiprocessing import Pool\n", "\n", "def polybius_break_mp(message, column_labels, row_labels,\n", " letters_to_merge=None,\n", " wordlist=keywords, fitness=Pletters,\n", " number_of_solutions=1, chunksize=500):\n", " \"\"\"Breaks a Polybius substitution cipher using a dictionary and\n", " frequency analysis\n", "\n", " >>> polybius_break_mp(polybius_encipher('this is a test message for the ' \\\n", " 'polybius decipherment', 'elephant', 'abcde', 'abcde'), \\\n", " 'abcde', 'abcde', \\\n", " wordlist=['cat', 'elephant', 'kangaroo']) # doctest: +ELLIPSIS\n", " (('elephant', , 'abcde', 'abcde', False), \\\n", " -54.5397...)\n", " >>> polybius_break_mp(polybius_encipher('this is a test message for the ' \\\n", " 'polybius decipherment', 'elephant', 'abcde', 'abcde', column_first=True), \\\n", " 'abcde', 'abcde', \\\n", " wordlist=['cat', 'elephant', 'kangaroo']) # doctest: +ELLIPSIS\n", " (('elephant', , 'abcde', 'abcde', True), \\\n", " -54.5397...)\n", " >>> polybius_break_mp(polybius_encipher('this is a test message for the ' \\\n", " 'polybius decipherment', 'elephant', 'abcde', 'abcde', column_first=False), \\\n", " 'abcde', 'abcde', \\\n", " wordlist=['cat', 'elephant', 'kangaroo']) # doctest: +ELLIPSIS\n", " (('elephant', , 'abcde', 'abcde', False), \\\n", " -54.5397...)\n", " >>> polybius_break_mp(polybius_encipher('this is a test message for the ' \\\n", " 'polybius decipherment', 'elephant', 'abcde', 'pqrst', column_first=True), \\\n", " 'abcde', 'pqrst', \\\n", " wordlist=['cat', 'elephant', 'kangaroo']) # doctest: +ELLIPSIS\n", " (('elephant', , 'abcde', 'pqrst', True), \\\n", " -54.5397...)\n", " \"\"\"\n", " if letters_to_merge is None: \n", " letters_to_m53880erge = {'j': 'i'}\n", " with Pool() as pool:\n", " helper_args = [(message, word, wrap, \n", " column_labels, row_labels, column_first, \n", " letters_to_merge, \n", " fitness)\n", " for word in wordlist\n", " for wrap in KeywordWrapAlphabet\n", " for column_first in [False, True]]\n", " # Gotcha: the helper function here needs to be defined at the top level\n", " # (limitation of Pool.starmap)\n", " breaks = pool.starmap(polybius_break_worker, helper_args, chunksize)\n", " if number_of_solutions == 1:\n", " return max(breaks, key=lambda k: k[1])\n", " else:\n", " return sorted(breaks, key=lambda k: k[1], reverse=True)[:number_of_solutions]\n", "\n", "def polybius_break_worker(message, keyword, wrap_alphabet, \n", " column_order, row_order, column_first, \n", " letters_to_merge, \n", " fitness):\n", " plaintext = polybius_decipher(message, keyword, \n", " column_order, row_order, \n", " column_first=column_first,\n", " letters_to_merge=letters_to_merge, \n", " wrap_alphabet=wrap_alphabet)\n", " if plaintext:\n", " fit = fitness(plaintext)\n", " else:\n", " fit = float('-inf')\n", " logger.debug('Polybius break attempt using key {0} (wrap={1}, merging {2}), '\n", " 'columns as {3}, rows as {4} (column_first={5}) '\n", " 'gives fit of {6} and decrypt starting: '\n", " '{7}'.format(keyword, wrap_alphabet, letters_to_merge,\n", " column_order, row_order, column_first,\n", " fit, sanitise(plaintext)[:50]))\n", " return (keyword, wrap_alphabet, column_order, row_order, column_first), fit" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 2.67 s, sys: 308 ms, total: 2.98 s\n", "Wall time: 3min 58s\n" ] }, { "data": { "text/plain": [ "(('a', , 'xlcdm', 'xlcdm', False),\n", " -3018.8648333417113)" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%time polybius_break_mp(sanitise(cb), order, order)" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(('elephant',\n", " ,\n", " [1, 2, 3, 4, 5],\n", " [1, 2, 3, 4, 5],\n", " True),\n", " -54.53880323982303)" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_break_mp(polybius_encipher('this is a test message for the ' \\\n", " 'polybius decipherment', 'elephant', \\\n", " [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], \\\n", " KeywordWrapAlphabet.from_last), \\\n", " [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], \\\n", " wordlist=['cat', 'elephant', 'kangaroo'])" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'2214445544551522115522511155551543114252542214111352123234442355411135441314115451112122'" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_encipher('this is a test message for the ' \\\n", " 'polybius decipherment', 'elephant', \\\n", " [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], \\\n", " wrap_alphabet=KeywordWrapAlphabet.from_last)" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(('elephant',\n", " ,\n", " [1, 2, 3, 4, 5],\n", " [1, 2, 3, 4, 5],\n", " False),\n", " -54.53880323982303)" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_break_mp('2214445544551522115522511155551543114252542214111352123234442355411135441314115451112122', \\\n", " [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], \\\n", " wordlist=['cat', 'elephant', 'kangaroo'])" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'thisisatestmessageforthepolybiusdecipherment'" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_decipher('2214445544551522115522511155551543114252542214111352123234442355411135441314115451112122', \\\n", " 'elephant',\n", " [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], \\\n", " wrap_alphabet=KeywordWrapAlphabet.from_last)" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{(1, 1): 'e',\n", " (1, 2): 'l',\n", " (1, 3): 'p',\n", " (1, 4): 'h',\n", " (1, 5): 'a',\n", " (2, 1): 'n',\n", " (2, 2): 't',\n", " (2, 3): 'b',\n", " (2, 4): 'c',\n", " (2, 5): 'd',\n", " (3, 1): 'f',\n", " (3, 2): 'g',\n", " (3, 3): 'i',\n", " (3, 4): 'k',\n", " (3, 5): 'm',\n", " (4, 1): 'o',\n", " (4, 2): 'q',\n", " (4, 3): 'r',\n", " (4, 4): 's',\n", " (4, 5): 'u',\n", " (5, 1): 'v',\n", " (5, 2): 'w',\n", " (5, 3): 'x',\n", " (5, 4): 'y',\n", " (5, 5): 'z'}" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_reverse_grid('elephant', [1, 2, 3, 4, 5], [1, 2, 3, 4, 5] )" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(2)('4')" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'bbadccddccddaebbaaddbbceaaddddaecbaacadadcbbadaaacdaabedbcccdeddbeaabdccacadaadcceaababb'" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_encipher('this is a test message for the ' \\\n", " 'polybius decipherment', 'elephant', 'abcde', 'abcde', column_first=False)" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'bbdaccddccddeabbaaddbbecaaddddeabcaaacadcdbbdaaacaadbadecbccedddebaadbcccadaaacdecaaabbb'" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_encipher('this is a test message for the ' \\\n", " 'polybius decipherment', 'elephant', 'abcde', 'abcde', column_first=True)" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'toisisvtestxessvbephktoefhnugiysweqifoekxelt'" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_decipher('bbdaccddccddeabbaaddbbecaaddddeabcaaacadcdbbdaaacaadbadecbccedddebaadbcccadaaacdecaaabbb', 'elephant', 'abcde', 'abcde', column_first=False)" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'thisisatestmessageforthepolybiusdecipherment'" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_decipher('bbdaccddccddeabbaaddbbecaaddddeabcaaacadcdbbdaaacaadbadecbccedddebaadbcccadaaacdecaaabbb', 'elephant', 'abcde', 'abcde', column_first=True)" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "(('elephant', , 'abcde', 'abcde', False),\n", " -54.53880323982303)" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_break_mp(polybius_encipher('this is a test message for the ' \\\n", " 'polybius decipherment', 'elephant', 'abcde', 'abcde'), \\\n", " 'abcde', 'abcde',\n", " wordlist=['cat', 'elephant', 'kangaroo'])" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "(('elephant', , 'abcde', 'abcde', True),\n", " -54.53880323982303)" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_break_mp(polybius_encipher('this is a test message for the ' \\\n", " 'polybius decipherment', 'elephant', 'abcde', 'abcde', column_first=True), \\\n", " 'abcde', 'abcde',\n", " wordlist=['cat', 'elephant', 'kangaroo'])" ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "(('elephant', , 'abcde', 'abcde', False),\n", " -54.53880323982303)" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_break_mp(polybius_encipher('this is a test message for the ' \\\n", " 'polybius decipherment', 'elephant', 'abcde', 'abcde', column_first=False), \\\n", " 'abcde', 'abcde',\n", " wordlist=['cat', 'elephant', 'kangaroo'])" ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "(('elephant', , 'abcde', 'pqrst', True),\n", " -54.53880323982303)" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_break_mp(polybius_encipher('this is a test message for the ' \\\n", " 'polybius decipherment', 'elephant', 'abcde', 'pqrst', column_first=True), \\\n", " 'abcde', 'pqrst',\n", " wordlist=['cat', 'elephant', 'kangaroo'])" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'bwaycxdycxdyazbwavdybwczavdydyazcwavcvdvdxbwayavaxdvaweybxcxdzdybzavbycxaxayavdxczavbvbw'" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_encipher('this is a test message for the ' \\\n", " 'polybius decipherment', 'elephant', 'abcde', 'vwxyz')" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'thisisatestmessageforthepolybiusdecipherment'" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_decipher('bwaycxdycxdyazbwavdybwczavdydyazcwavcvdvdxbwayavaxdvaweybxcxdzdybzavbycxaxayavdxczavbvbw', \n", " 'elephant', 'abcde', 'vwxyz')" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [], "source": [ "logger.setLevel(logging.DEBUG)" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(('elephant', , 'abcde', 'vwxyz', False),\n", " -54.53880323982303)" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "polybius_break_mp('bwaycxdycxdyazbwavdybwczavdydyazcwavcvdvdxbwayavaxdvaweybxcxdzdybzavbycxaxayavdxczavbvbw', \\\n", " 'abcde', 'vwxyz',\n", " wordlist=['cat', 'elephant', 'kangaroo'])" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [], "source": [ "logger.debug('test')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "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": 2 }