11 "import matplotlib.pyplot as plt\n",
12 "import pandas as pd\n",
13 "import collections\n",
15 "import numpy as np\n",
16 "from numpy import matrix\n",
17 "from numpy import linalg\n",
18 "%matplotlib inline\n",
20 "from multiprocessing import Pool\n",
23 "from cipher import *\n",
24 "from cipherbreak import *\n",
26 "c7b = open('2016/7b.ciphertext').read()"
31 "execution_count": 108,
37 "c7bs = sanitise(c7b)\n",
38 "c7br = cat(reversed(c7bs))"
49 "def bifid_grid(keyword, wrap_alphabet, letter_mapping):\n",
50 " cipher_alphabet = keyword_cipher_alphabet_of(keyword, wrap_alphabet)\n",
51 " if letter_mapping is None:\n",
52 " letter_mapping = {'j': 'i'}\n",
53 " translation = ''.maketrans(letter_mapping)\n",
54 " cipher_alphabet = cat(collections.OrderedDict.fromkeys(cipher_alphabet.translate(translation)))\n",
55 " f_grid = {k: ((i // 5) + 1, (i % 5) + 1) \n",
56 " for i, k in enumerate(cipher_alphabet)}\n",
57 " r_grid = {((i // 5) + 1, (i % 5) + 1): k \n",
58 " for i, k in enumerate(cipher_alphabet)}\n",
59 " return translation, f_grid, r_grid"
64 "execution_count": 156,
75 "execution_count": 157,
83 "output_type": "stream",
140 "pprint.pprint(bifid_grid('iguana', KeywordWrapAlphabet.from_a, None))"
145 "execution_count": 158,
153 "output_type": "stream",
210 "pprint.pprint(bifid_grid('z', KeywordWrapAlphabet.from_a, None))"
215 "execution_count": 159,
223 "output_type": "stream",
280 "pprint.pprint(bifid_grid('iguana', KeywordWrapAlphabet.from_a, {'q': 'p'}))"
285 "execution_count": 87,
291 "# def bifid_decipher(message, keyword, wrap_alphabet=KeywordWrapAlphabet.from_a, \n",
292 "# letter_mapping=None, period=None):\n",
293 "# translation, f_grid, r_grid = bifid_grid(keyword, wrap_alphabet, letter_mapping)\n",
295 "# t_message = message.translate(translation)\n",
296 "# pairs0 = [f_grid[l] for l in t_message]\n",
297 "# items = sum([list(p) for p in pairs0], [])\n",
298 "# gap = len(message)\n",
299 "# pairs1 = [(items[i//2], items[i//2+gap]) for i in range(0, len(items), 2)]\n",
300 "# return cat(r_grid[p] for p in pairs1)\n",
306 "execution_count": 162,
312 "def bifid_encipher(message, keyword, wrap_alphabet=KeywordWrapAlphabet.from_a, \n",
313 " letter_mapping=None, period=None, fillvalue=None):\n",
314 " translation, f_grid, r_grid = bifid_grid(keyword, wrap_alphabet, letter_mapping)\n",
316 " t_message = message.translate(translation)\n",
317 " pairs0 = [f_grid[l] for l in sanitise(t_message)]\n",
319 " chunked_pairs = [pairs0[i:i+period] for i in range(0, len(pairs0), period)]\n",
320 " if len(chunked_pairs[-1]) < period and fillvalue:\n",
321 " chunked_pairs[-1] += [f_grid[fillvalue]] * (period - len(chunked_pairs[-1]))\n",
323 " chunked_pairs = [pairs0]\n",
326 " for c in chunked_pairs:\n",
327 " items = sum(list(list(i) for i in zip(*c)), [])\n",
328 " p = [(items[i], items[i+1]) for i in range(0, len(items), 2)]\n",
331 " return cat(r_grid[p] for p in pairs1)\n",
337 "execution_count": 163,
345 "'nkklawamdkoedysipdesltirsnoesqlvvaloderbhel'"
348 "execution_count": 163,
350 "output_type": "execute_result"
354 "bifid_encipher('this is a test message for the keyword decipherment', 'elephant', wrap_alphabet=KeywordWrapAlphabet.from_last)"
359 "execution_count": 83,
366 "ot, ofg, org = bifid_grid('iguana', KeywordWrapAlphabet.from_a, None)"
371 "execution_count": 85,
391 "execution_count": 85,
393 "output_type": "execute_result"
397 "op0 = [ofg[l] for l in \"indiacurry\"]\n",
403 "execution_count": 86,
411 "[[(1, 1), (1, 5), (2, 3), (1, 1)],\n",
412 " [(1, 4), (2, 2), (1, 3), (4, 3)],\n",
413 " [(4, 3), (5, 4), (1, 4), (1, 4)]]"
416 "execution_count": 86,
418 "output_type": "execute_result"
422 "ocp = chunks(op0, 4, fillvalue=[[ofg['a']]])\n",
429 "execution_count": 87,
451 "execution_count": 87,
453 "output_type": "execute_result"
459 " items = sum(list(list(i) for i in zip(*c)), [])\n",
460 " p = [(items[i], items[i+1]) for i in range(0, len(items), 2)]\n",
467 "execution_count": 88,
478 "execution_count": 88,
480 "output_type": "execute_result"
484 "cat(org[p] for p in acc)"
489 "execution_count": null,
498 "execution_count": 164,
504 "def bifid_decipher(message, keyword, wrap_alphabet=KeywordWrapAlphabet.from_a, \n",
505 " letter_mapping=None, period=None, fillvalue=None):\n",
506 " translation, f_grid, r_grid = bifid_grid(keyword, wrap_alphabet, letter_mapping)\n",
508 " t_message = message.translate(translation)\n",
509 " pairs0 = [f_grid[l] for l in sanitise(t_message)]\n",
511 " chunked_pairs = [pairs0[i:i+period] for i in range(0, len(pairs0), period)]\n",
512 " if len(chunked_pairs[-1]) < period and fillvalue:\n",
513 " chunked_pairs[-1] += [f_grid[fillvalue]] * (period - len(chunked_pairs[-1]))\n",
515 " chunked_pairs = [pairs0]\n",
518 " for c in chunked_pairs:\n",
519 " items = [j for i in c for j in i]\n",
521 " p = [(items[i], items[i+gap]) for i in range(gap)]\n",
524 " return cat(r_grid[p] for p in pairs1) "
529 "execution_count": 5,
591 "execution_count": 5,
593 "output_type": "execute_result"
597 "bifid_grid('iguana', KeywordWrapAlphabet.from_a, None)"
602 "execution_count": 139,
613 "execution_count": 139,
615 "output_type": "execute_result"
619 "bifid_encipher(\"indiajelly\", 'iguana')"
624 "execution_count": 166,
635 "execution_count": 166,
637 "output_type": "execute_result"
641 "bifid_encipher(\"indiajelly\", 'iguana', period=0)"
646 "execution_count": 140,
657 "execution_count": 140,
659 "output_type": "execute_result"
663 "bifid_decipher('ibidonhprm', 'iguana')"
668 "execution_count": 137,
679 "execution_count": 137,
681 "output_type": "execute_result"
685 "bifid_encipher(\"indiacurry\", 'iguana', period=4)"
690 "execution_count": 138,
701 "execution_count": 138,
703 "output_type": "execute_result"
707 "bifid_decipher(\"ibnhgaqltm\", 'iguana', period=4)"
712 "execution_count": 144,
723 "execution_count": 144,
725 "output_type": "execute_result"
729 "bifid_encipher(\"indiacurry\", 'iguana', period=4, fillvalue='x')"
734 "execution_count": 146,
745 "execution_count": 146,
747 "output_type": "execute_result"
751 "bifid_decipher(\"ibnhgaqltzml\", 'iguana', period=4)"
756 "execution_count": 101,
762 "p0 = [(1, 1), (2, 1), (1, 5), (3, 1)]"
767 "execution_count": 103,
776 "[1, 1, 2, 1, 1, 5, 3, 1]"
779 "execution_count": 103,
781 "output_type": "execute_result"
785 "t0 = [j for i in p0 for j in i]\n",
791 "execution_count": 104,
799 "[(1, 1), (1, 5), (2, 3), (1, 1)]"
802 "execution_count": 104,
804 "output_type": "execute_result"
808 "[(t0[i], t0[i+4]) for i in range(4)]"
813 "execution_count": 130,
821 "'martinwehavemadeadreadfulmistakeandihavebeentooslowtoadmitthattomyselfihavehadavisitfromthewomanfromthesyndicateandiconfrontedheraboutthesourceofthetemplatessheconfirmedmyworstfearsandnowiwanttocrawlawayanddiewhathavewedoneoursoftwarehasledtosomuchsufferingwhenitwasdesignedtodotheoppositeiaskedherhowthecabinetofficecouldpossiblyhaveauthorisedthisandshelaughedandexplainedthatthesyndicatenolongerworkedforthebritishgovernmentcallitprivateenterpriseshesaidwehavealwaysbeengoodatthatmyhorrormusthavebeenwrittenallovermyfaceshedidntseemsurprisedatmyreactionbutequallyshedidnttakeitwellandcivilitywasabandonediaskedherhowitcouldbelegalletalonemoraltodowhattheyproposedandheranswerwasthatitwasnecessaryisaidwewouldnthelpthemandshesaiditwasnecessarythatwedidisaidiwouldntbeabletofacemyfamilyandfriendsifwecooperatedandshesaidiwouldnthavetoworryaboutthatforlongonewayoranotherthepdssyndicateweregoingtomakesurewebothdisappearedlookingbackicanseethatfromthestartthiswholethinghasactedtodrawusintoitscentreandnowiamattheeventhorizonalmostunabletoescapeitspullbutithinkwehaveonelastchanceiamsureshewillbevisitingyouaswellshethinkswehavenochoicebutithinkachoiceisallwehavewhateveryoudoholdoutforbettertermsshehastobelievethatyouareonsideandmotivatedbygreedsothatshewontworryaboutanyqualmsyoumighthaveconvinceherthatyouwillconvincemetocooperatetellherthatyouthinkyoushouldworkfromthecollectiveinosloandthatyouwantpaymentviathebankinswitzerlandigottheimpressionthatmoneyisnotaproblemwithmoneyinaswissbankandtheexpertiseandconnectivityaffordedbythecollectiveithinkwehaveachancetoescapeandtotrytostopthemperhapswewillsurvivethisperhapswecanbringthemdown'"
824 "execution_count": 130,
826 "output_type": "execute_result"
830 "bifid_decipher(c7bs, 'ligo', KeywordWrapAlphabet.from_a, period=4, fillvalue=None)"
835 "execution_count": 147,
843 "'martin we have made a dreadful mistake and i have been too slow to admit that to myself i have had a visit from the woman from the syndicate and i confronted her about the source of the templates she confirmed my worst fears and now i want to crawl away and die what have we done our software has led to so much suffering when it was designed to do the opposite i asked her how the cabinet office could possibly have authorised this and she laughed and explained that the syndicate no longer worked for the british government call it private enterprises he said we have always been good at that my horror must have been written all over myfaces he didnt seem surprised at my reaction but equally she didnt take it well and civility was abandoned i asked her how it could be legal let alone moral to do what they proposed and her answer was that it was necessary i said we wouldnt help them and she said it was necessary that we did i said i wouldnt be able to face my family and friends if we cooperated and she said i wouldnt have to worry about that for long one way or another the pds syndicate were going to make sure we both disappeared looking back i can see that from the start this whole thing has acted to draw us into its centre and now i am at the event horizon almost unable to escape its pull but i think we have one last chance i am sure she will be visiting you as well she thinks we have no choice but i think a choice is all we have whatever you do hold out for better terms she has to believe that you are on side and motivated by greed so that she wont worry about any qualms you might have convince her that you will convince me to cooperate tell her that you think you should work from the collective in oslo and that you want payment via the bank in switzerland i got the impression that money is not a problem with money in a swiss bank and the expertise and connectivity afforded by the collective i think we have a chance to escape and to try to stop them perhaps we will survive this perhaps we can bring them down'"
846 "execution_count": 147,
848 "output_type": "execute_result"
852 "wcat(segment(bifid_decipher(c7bs, 'ligo', KeywordWrapAlphabet.from_a, period=4)))"
857 "execution_count": null,
866 "execution_count": null,
875 "execution_count": null,
884 "execution_count": null,
893 "execution_count": null,
902 "execution_count": 49,
908 "p0 = [(2, 1), (3, 3), (3, 3), (5, 1), (1, 4)]"
913 "execution_count": 54,
921 "[2, 1, 3, 3, 3, 3, 5, 1, 1, 4]"
924 "execution_count": 54,
926 "output_type": "execute_result"
930 "items = sum([list(p) for p in p0], [])\n",
936 "execution_count": 55,
944 "[(2, 3), (1, 5), (3, 1), (3, 1), (3, 4)]"
947 "execution_count": 55,
949 "output_type": "execute_result"
954 "[(items[i//2], items[i//2+gap]) for i in range(0, len(items), 2)]"
959 "execution_count": 91,
965 "c7bs = sanitise(c7b)"
970 "execution_count": 115,
976 "def bifid_break_mp(message, wordlist=keywords, fitness=Pletters,\n",
977 " number_of_solutions=1, chunksize=500):\n",
978 " \"\"\"Breaks a keyword substitution cipher using a dictionary and\n",
979 " frequency analysis\n",
981 " >>> keyword_break_mp(keyword_encipher('this is a test message for the ' \\\n",
982 " 'keyword decipherment', 'elephant', KeywordWrapAlphabet.from_last), \\\n",
983 " wordlist=['cat', 'elephant', 'kangaroo']) # doctest: +ELLIPSIS\n",
984 " (('elephant', <KeywordWrapAlphabet.from_last: 2>), -52.834575011...)\n",
985 " >>> keyword_break_mp(keyword_encipher('this is a test message for the ' \\\n",
986 " 'keyword decipherment', 'elephant', KeywordWrapAlphabet.from_last), \\\n",
987 " wordlist=['cat', 'elephant', 'kangaroo'], \\\n",
988 " number_of_solutions=2) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE\n",
989 " [(('elephant', <KeywordWrapAlphabet.from_last: 2>), -52.834575011...), \n",
990 " (('elephant', <KeywordWrapAlphabet.from_largest: 3>), -52.834575011...)]\n",
992 " with Pool() as pool:\n",
993 " helper_args = [(message, word, wrap, fitness)\n",
994 " for word in wordlist\n",
995 " for wrap in KeywordWrapAlphabet]\n",
996 " # Gotcha: the helper function here needs to be defined at the top level\n",
997 " # (limitation of Pool.starmap)\n",
998 " breaks = pool.starmap(bifid_break_worker, helper_args, chunksize)\n",
999 " if number_of_solutions == 1:\n",
1000 " return max(breaks, key=lambda k: k[1])\n",
1002 " return sorted(breaks, key=lambda k: k[1], reverse=True)[:number_of_solutions]\n"
1006 "cell_type": "code",
1007 "execution_count": 116,
1013 "def bifid_break_worker(message, keyword, wrap_alphabet, fitness):\n",
1014 " plaintext = bifid_decipher(message, keyword, wrap_alphabet)\n",
1015 " fit = fitness(plaintext)\n",
1016 " logger.debug('Keyword break attempt using key {0} (wrap={1}) gives fit of '\n",
1017 " '{2} and decrypt starting: {3}'.format(keyword, \n",
1018 " wrap_alphabet, fit, sanitise(plaintext)[:50]))\n",
1019 " return (keyword, wrap_alphabet), fit"
1023 "cell_type": "code",
1024 "execution_count": 107,
1032 "'enamokkneogiyegrkcuzbgsydkoqoswiwvtgbolrkfuzbgsyskdqusgnttqetuonyegyfkbsteqeycgbudbvqadcepgqrsbbeaeoqilrqcsosfcdyrbztiuirvqrtcmesbkudboeytksofknyegrambmctvxeogttfggemokopiqwinutqhdtoftsgsathnemlteprmrqbstdolsaklrueucsvncyhgqqcsfqlutsdxzthnfuvotauhnyegosloeogwrrqclelbonknefqkrkofvoqhxttvrimhyttvyqosrlegqtbeyroeuegbtnqkeecgqepblclvutouaehtoekceqgpeobwaohndxlstmvnvalttupquvoieruortugrhfsyqosnsqcesrvhtcrarvqnshkudbistnbwuootauhtqefiolctxqoqhdsmrneettrtberyybtnqblqxgrtrveqyfoboxwaehwlplqrcbiowhirimheyotqcciorhitvdaqkdurimhtheslelwxuooneagedooqlfibrlfhesrpxtgrrbkarhrxqobtogwaehwrimheyotlviqpesoyfkbsteqoviiynstnvhltfgarqostqdfotktpfhlrnadyegrtencsrtltknqffyqsnietwrixhogeqgsooihkiuhtwtonotknenquarhtnerycgicadbschhthlbeurbzpmqkqbsoebweprtepkhtsqhrslbrrefycoisnkumuedqrseqtshftqvftvkntlgbyqbyqosyotbucvtetvqoawhtgniucoadpiqomkeysgcyroeuegbefwimtedcpqcyogakzhbnepcztbqoviiotcnguiocdaipkqbkebwyqosepuqsrecnfsvedoipoqkmyegsqdsaogktgniurofkwfldeoupsqerncsfevoyqosxcoueswnfoqkspkbnyrheuqxotktarhasoiofnqhtokluoqivslbqhbcveqberoaboskskcsfslctsgkapbqftvuiilvcsbkaqlbrrubwtgtnkdboskylzlqqyetqekleuebrsyspnbrcfqspstdntrndsichescznbprqealulhteroctydoocwanhtprnocothnypoqysosniltodcsfyvvolwaehwdpiqoskedwonrtentycobwanelolftbnneksonwlhrsqcqqcqrsopeckrcountigqtldycoisnkuotktanhetwklvshfspkboxkqaolkmyegdqossdcorqoszoowaohabmityghiurocczicttqkifbboekyorhehedkxrobesooztmbqnsbtsqcnkgqnxcorruhokkaergezpctbpdnntqqshcqaehrfyvenwqtttbgsrcfvqasarhfksbkufvvawlacteqtfnvctvhspkqwyocnrtormzdnckouekbomkttarlptmroyketcbrusoeqystofbqoskctenquekbkybgtfrbktbxsqesswgeysggrqfsswgeedoovxaiqvdabaginnrptyqoqesomudleoylstoqtodcoawhkybgeukqdgogzxeiexrinpchoawheewgepth'"
1035 "execution_count": 107,
1037 "output_type": "execute_result"
1041 "c7bs = sanitise(c7b)\n",
1042 "c7br = cat(reversed(c7bs))\n",
1047 "cell_type": "code",
1048 "execution_count": 148,
1056 "(('ligo', <KeywordWrapAlphabet.from_a: 1>), -2505.924490942904)"
1059 "execution_count": 148,
1061 "output_type": "execute_result"
1065 "bifid_break_mp(c7bs, wordlist=['gravity', 'ligo'])"
1069 "cell_type": "code",
1070 "execution_count": 102,
1078 "'ksotagstmczesqstldwfasoehepicltaryruvgstiwbtylwzlanehrdmthhlqzeohpsdytllgdxfcetbiislqetoukobnterkoyonsetkodhtymxuefpdtnhnsulwnnurhiotctcrwhprbssrdblxanlrxadxgxatetsegdoeuhawberbaswolpqkrkpfcxufohcyefaeabqtkbrykbdonghsbaodvongcfdvngmeslhetnytkocenotirklsatenkdeeyoentbryuoleqoefcuxpqbsirotbogkvtqbrqgyoqamkninrfottolgmynbsekmeouwueklcpqrekyylvronsntcotrrctdvoyfthkgalscldypooicxrtpdyttohfoqtprrbgtwepsycwpswuylkedbiglsylbctcfecisumvrbyparteagabdqouuttohvbtcdtxczusxrtleburbtkapmsfctmokootcoibkclbetoaralxzdnlpanenadkhhgtsldnyrupnqsravhtpohmplgtaacuhfpttdebroaqhedgvooyyneoebrfudfodroyklhsheqheeqhdinusytmhdqqedsbbdzcylgukonttacivvvcrprteautwrxhdmczntnixhzbeasmboscsyeqdtsxxeiodohrnofaidlbabrobumelkaeuvnlylglqnfpeqklhwlqeselhameievlbeawrlnllyetoeolencrduoghqqoeqyhlqidrrvndrrwnfhmottqllpayunortyoeariuhharstrhnsfaaoqlipqkohcrnldicnlshnysnrtdbiggeonatcseqosygonehtdutacbzdbstdcrzttntrbtunrotcuewfslftkgdruetlrxrgbmvegfsqieybgqtfxaxrvqbybcaibhoeoolnpxnrdatsspxotloerkwotcheutoerrufnprncktohsqarexdccnbtbekxtqtcrtbaqsottmbltovlurbeoolrtpksbtpyvrasrbtkfricyeremtpaqunucemnterrmdpoldyaicofeoppgepxtdaioeesqqysthohkeotktnstxntgtmhqvyhoythkeanebdshlmtrnqhrunweeeozctiofegqolrfmmdbdacryrmqrypwuwvcntdyqksdamrsglgisanncrmoerfveprpkgbagkerobderbnbatdnedugenxarredlduheegqbrycawnknbnylomloetokdolqreyuecvufbrpsmsptadqthkuotdvknhuyetldctwotidfglrgspmhokusbvtpvbeietnxqbirwhspqetmyotewabodyfppaoacoequgsrrgtyqfsnegmtfvzelmfwosrutwpvnamanthhgcnepsepeguldrhaenwolwhhohnsrlpxnsdhenvadcbyqicaboptfaoknvcmeoerqbtlyovbbddommednhlmrlcyaeflratepytylrnpcantuepwpxxanfthsdnowzirihfqqcedlewwhkcelinfwniiohclardlbqqokzrwvdswbufemcsqqveqnbruynipgrbaytsqkkkyodugayche'"
1081 "execution_count": 102,
1083 "output_type": "execute_result"
1087 "bifid_decipher(c7bs, 'capris', KeywordWrapAlphabet.from_a )"
1091 "cell_type": "code",
1092 "execution_count": 104,
1100 "'dnrobchyoikvkwtucnsiganmyoanfatckweqpwxwehfdpoxqdvtworugsnpsxanmycvirrgedmuihpienwfnpwyzdffaqsxsoutvbvqlovoplenqrnktqlernruwptiswodnhaxomrtwbmpunnbnolcrvsasmcblsvawegytshecczeperucfeqlrcosbfdhdkcaeipnsligmsnapleqpoutoqgtcobyzorcehvvkkrhoxngkavnolkcrncshwetpocgnysxewemonekysintysuqrlntykpvsckgenbecfybfmycsrtzrxfckstgbirtnmnhdhcetfvuttwptpbigplyctfisoxttslhhbvtnotminnusfcqobdtnlhnpbnhxhpirckoatchwiaofaloprrbyonlouscekwlsnboyciswcoosyirodpwsgghcqhofeuosmtqfhqsztrsscwxfzwrnhhnphtpvwnurikaeoxgftoyodrmaqnosloukciskmbycicidsgeofsbrfodhsrtskwtpbtgnsmnyncrvsrhtwrsiolhlylrnntvrkenffvgfypknntxryqqgonspndmocrhcpfrnbgerwqncuiciqverfealtrnoomnwdnenepldpgatsbbffsaogoynownnotoxbeckllrnonbknycsensfleqbctonegzaccsifmnuezvlfqsurrgwviiuwrdcgoininoyseugowzkpntfctreowotnetkswlctahmgrpoypohsnoqnqooogboctspteznllttcurbcbiewnslipsshliwsybvalnlosrrtpcfzepwsnonktceovhhrnqfeilrkmsrlseoinyfsfunulffevuofwrenqbrettkrtkbnkelciibvsysafkrisombfmsqgwlfbnekikdyreipgzshnonclsrzgyceeanhlvcluucfsomraasehigprxbmfiftdnhgxhfbnzopntrsgcudoigstteflifktxiewbaqltwevuznctfgxhgtihgeruomubtgsvaxgoysnontudtebmabnbvsnsrqffslnigcfnemqgnhfckqpncoewfrnmbictedfkwaateghravmulprcftrqngazecectflxcicnhhwllbrwpoiitgqvknmogoeckpsqtvofttwbhpsntarshokvnigrlypropqiitoznlghoknmifdedtapmpisprrsfewfnqttitvnkoaltfmfqicnsaedyxuaklctantctroesoorbkkmpktnwnoulfnmrvougqstqkfdtttvarerhylgfoimeanomleupotornghfryklsyfgtnxdnnsttsoitriyisennougsveatellinkpetkaxodulaihaoebevagqodofghminllhpelcnszrbagvzsclxphrvplbhossnckahwaeroakctnekodiwgfinquogmgraqpgqafienectgnwoeusnilosiptysyfxuydrdxsgtcoucislntosflhttnogzrlntrwkrxiokklphbagvsufdlxpuhpnoqwuukirefqweuxtrtbtnnwrshqneawdghirfaturhpwesptebb'"
1103 "execution_count": 104,
1105 "output_type": "execute_result"
1109 "bifid_decipher(c7br, 'trinket', KeywordWrapAlphabet.from_a)"
1113 "cell_type": "code",
1114 "execution_count": null,
1124 "display_name": "Python 3",
1125 "language": "python",
1129 "codemirror_mode": {
1133 "file_extension": ".py",
1134 "mimetype": "text/x-python",
1136 "nbconvert_exporter": "python",
1137 "pygments_lexer": "ipython3",