4 "signature": "sha256:112d1c84c318592f927e18c5b0f15ed60ac8418ca15cb79596ba6212ff2d7e3f"
15 "import matplotlib.pyplot as plt\n",
16 "import pandas as pd\n",
17 "import collections\n",
19 "import numpy as np\n",
20 "from numpy import matrix\n",
21 "from numpy import linalg\n",
22 "%matplotlib inline\n",
24 "from cipher import *\n",
25 "from cipherbreak import *\n",
27 "c6a = open('2014/6a.ciphertext').read()\n",
28 "c6b = open('2014/6b.ciphertext').read()"
39 "key_a, score = railfence_break(sanitise(c6a))\n",
47 "output_type": "pyout",
50 "(3, -2314.997881051078)"
60 "' '.join(segment(railfence_decipher(sanitise(c6a), key_a)))"
67 "output_type": "pyout",
70 "'mark the last message told usa lot the scuttling equipment is designed to pump water in and out of the vessel like a submarine dive control but clearly they werent planning to turn a container ship into a sub this ship is a largescale version of something i have seen in the caribbean drug runners use a similar technique to get below radar coverage for inshore runs sinking the vessel so that the deck remains just below the wave tops the fda pirates seem more interested in staying away from shore but getting close enough to track and record electronic communications without detection i am guessing this scuttling system is what they call nautilus in their log but i am still baffled by the references to seahorse the next page of the log looks harder to crack but the cipher clerk tells me it is a hill cipher and that they must have been in a hurry or have been enciphering by hand since they just used a two by two matrix actually we have been pretty lax with our security and i think the next message is end will use avi genere cipher given that we are using secure cables i dont think we have too much to worry about so i will keep the keyword short say three characters more later harry'"
80 "c6bs = sanitise(c6b)\n",
88 "output_type": "pyout",
91 "'hwssswxfewhhrfewpdrvttdhxbccleayphalnadhiehaoudrotwnrrvysabjlttbaytmelrkaidopthatlelrtwaamaneksvvzrvllatkcrjquicizgtoqcpnrrkttowandqehtqrvtbaydqealannohulanuzlwextlvjrvivhnohdqmgykaclmswrupdetfioftfelhzpxhaswftwprrsweiseohefpdrvttnvagdvswgoerbetnharvaeevtlltbmgaiatgelinmdawevhatterdhrznbnvoutnefoteveaehlaymhacglzeptvvdimworfisgtuzlwibeqohubtghamqornjnnrumqvjtxeltfovgawdaeevllgrtxibgtibevmpsaateoasevaeyqohameonncfuidoefafattemuimnflznbekofobrliaehhauihnnnwzaeevtlltpaalnanvtzlzuucptaelinanpaahewfthaosetaribnbnvhaevdhyytlmuxb'"
101 "c6b_nums = [ord(c) - ord('a') for c in c6bs]\n",
104 "language": "python",
109 "output_type": "pyout",
649 "m = np.matrix([[7,8], [11,11]])\n",
652 "language": "python",
657 "output_type": "pyout",
658 "prompt_number": 106,
660 "matrix([[ 7, 8],\n",
673 "language": "python",
678 "output_type": "pyout",
679 "prompt_number": 107,
681 "-11.000000000000002"
693 "language": "python",
698 "output_type": "pyout",
699 "prompt_number": 108,
701 "matrix([[-1. , 0.72727273],\n",
702 " [ 1. , -0.63636364]])"
712 "v = np.matrix([[7], [22]])\n",
715 "language": "python",
720 "output_type": "pyout",
737 "language": "python",
742 "output_type": "pyout",
756 "np.linalg.solve(m, c) % 26"
758 "language": "python",
763 "output_type": "pyout",
779 "language": "python",
784 "output_type": "pyout",
800 "language": "python",
805 "output_type": "pyout",
819 "np.linalg.solve(m, (m*v)%26)%26"
821 "language": "python",
826 "output_type": "pyout",
842 "language": "python",
847 "output_type": "pyout",
860 "def hill_encipher(matrix, message_letters, fillvalue='a'):\n",
861 " n = len(matrix)\n",
862 " sanitised_message = sanitise(message_letters)\n",
863 " if len(sanitised_message) % n != 0:\n",
864 " padding = fillvalue[0] * (n - len(sanitised_message) % n)\n",
867 " message = [ord(c) - ord('a') for c in sanitised_message + padding]\n",
868 " message_chunks = [message[i:i+n] for i in range(0, len(message), n)]\n",
869 " # message_chunks = chunks(message, len(matrix), fillvalue=None)\n",
870 " enciphered_chunks = [((matrix * np.matrix(c).T).T).tolist()[0] for c in message_chunks]\n",
871 " return ''.join([chr(int(round(l)) % 26 + ord('a')) for l in sum(enciphered_chunks, [])])"
873 "language": "python",
882 "hill_encipher(m, 'hellothere')"
884 "language": "python",
889 "output_type": "pyout",
890 "prompt_number": 156,
902 "msg = [ord(c) - ord('a') for c in 'hellothere']\n",
905 "language": "python",
910 "output_type": "pyout",
913 "[7, 4, 11, 11, 14, 19, 7, 4, 17, 4]"
923 "msgc = [msg[i:i+len(m)] for i in range(0, len(msg), len(m))]\n",
926 "language": "python",
931 "output_type": "pyout",
932 "prompt_number": 112,
934 "[[7, 11], [14, 25], [21, 14], [7, 11], [11, 15], [0, 0]]"
944 "((m*np.matrix(msgc[0]).T).T % 26).tolist()[0]"
946 "language": "python",
951 "output_type": "pyout",
964 "def hill_decipher(matrix, message, fillvalue='a'):\n",
965 " adjugate = linalg.det(matrix)*linalg.inv(matrix)\n",
966 " inverse_determinant = modular_division_table[int(round(linalg.det(matrix))) % 26][1]\n",
967 " inverse_matrix = (inverse_determinant * adjugate) % 26\n",
968 " return hill_encipher(inverse_matrix, message, fillvalue) "
970 "language": "python",
979 "hill_decipher(m, 'drjiqzdrvx')"
981 "language": "python",
986 "output_type": "pyout",
987 "prompt_number": 161,
999 "msg = [ord(c) - ord('a') for c in 'drjiqzdrvxaa']\n",
1002 "language": "python",
1007 "output_type": "pyout",
1008 "prompt_number": 114,
1010 "[3, 17, 9, 8, 16, 25, 3, 17, 21, 23, 0, 0]"
1014 "prompt_number": 114
1017 "cell_type": "code",
1020 "msgc = [msg[i:i+len(m)] for i in range(0, len(msg), len(m))]\n",
1023 "language": "python",
1028 "output_type": "pyout",
1029 "prompt_number": 115,
1031 "[[3, 17], [9, 8], [16, 25], [3, 17], [21, 23], [0, 0]]"
1035 "prompt_number": 115
1038 "cell_type": "code",
1041 "(np.linalg.solve(m, np.matrix(msgc[0]).T).T % 26)"
1043 "language": "python",
1048 "output_type": "pyout",
1049 "prompt_number": 116,
1051 "matrix([[ 9.36363636, 18.18181818]])"
1055 "prompt_number": 116
1058 "cell_type": "code",
1061 "m_adj = linalg.det(m)*linalg.inv(m)\n",
1064 "language": "python",
1069 "output_type": "pyout",
1070 "prompt_number": 142,
1072 "matrix([[ 11., -8.],\n",
1077 "prompt_number": 142
1080 "cell_type": "code",
1083 "modular_division_table[int(round(linalg.det(m))) % 26][1]"
1085 "language": "python",
1090 "output_type": "pyout",
1091 "prompt_number": 148,
1097 "prompt_number": 148
1100 "cell_type": "code",
1103 "m_inv = (modular_division_table[int(round(linalg.det(m))) % 26][1] * m_adj) % 26\n",
1106 "language": "python",
1111 "output_type": "pyout",
1112 "prompt_number": 150,
1114 "matrix([[ 25., 22.],\n",
1119 "prompt_number": 150
1122 "cell_type": "code",
1125 "hill_encipher(m_inv, 'drjiqzdrvx')"
1127 "language": "python",
1132 "output_type": "pyout",
1133 "prompt_number": 157,
1139 "prompt_number": 157
1142 "cell_type": "code",
1145 "np.dot(m , 1/linalg.det(m) * mc)"
1147 "language": "python",
1152 "output_type": "pyout",
1153 "prompt_number": 120,
1155 "matrix([[ 1., 0.],\n",
1160 "prompt_number": 120
1163 "cell_type": "code",
1166 "ml = np.matrix([[6, 24, 1], [13, 16, 10], [20, 17, 15]])\n",
1169 "language": "python",
1174 "output_type": "pyout",
1175 "prompt_number": 122,
1177 "matrix([[ 6, 24, 1],\n",
1183 "prompt_number": 122
1186 "cell_type": "code",
1189 "ml_adj = linalg.det(ml)*linalg.inv(ml) % 26\n",
1192 "language": "python",
1197 "output_type": "pyout",
1198 "prompt_number": 137,
1200 "matrix([[ 18., 21., 16.],\n",
1201 " [ 5., 18., 5.],\n",
1202 " [ 5., 14., 18.]])"
1206 "prompt_number": 137
1209 "cell_type": "code",
1212 "modular_division_table[int(linalg.det(ml) % 26)][1]"
1214 "language": "python",
1219 "output_type": "pyout",
1220 "prompt_number": 138,
1226 "prompt_number": 138
1229 "cell_type": "code",
1232 "ml_inv = (modular_division_table[int(linalg.det(ml) % 26)][1] * ml_adj) % 26\n",
1235 "language": "python",
1240 "output_type": "pyout",
1241 "prompt_number": 139,
1243 "matrix([[ 8., 5., 10.],\n",
1244 " [ 21., 8., 21.],\n",
1245 " [ 21., 12., 8.]])"
1249 "prompt_number": 139
1252 "cell_type": "code",
1255 "hill_encipher(ml, 'hello there')"
1257 "language": "python",
1262 "output_type": "pyout",
1263 "prompt_number": 193,
1269 "prompt_number": 193
1272 "cell_type": "code",
1275 "hill_decipher(ml, 'tfjflpznvyac')"
1277 "language": "python",
1282 "output_type": "pyout",
1283 "prompt_number": 196,
1289 "prompt_number": 196
1292 "cell_type": "code",
1295 "hill_encipher(ml, 'act')"
1297 "language": "python",
1302 "output_type": "pyout",
1303 "prompt_number": 182,
1309 "prompt_number": 182
1312 "cell_type": "code",
1315 "hill_decipher(ml, 'poh')"
1317 "language": "python",
1321 "output_type": "stream",
1331 "output_type": "pyout",
1332 "prompt_number": 192,
1338 "prompt_number": 192
1341 "cell_type": "code",
1344 "[chr(int(round(i)) % 26 + ord('a')) for i in (ml_inv * np.matrix([ord(c) - ord('a') for c in 'poh']).T).T.tolist()[0]]"
1346 "language": "python",
1351 "output_type": "pyout",
1352 "prompt_number": 180,
1358 "prompt_number": 180
1361 "cell_type": "code",
1364 "hill_encipher(ml_inv, 'poh')"
1366 "language": "python",
1371 "output_type": "pyout",
1372 "prompt_number": 184,
1378 "prompt_number": 184
1381 "cell_type": "code",
1384 "len([list(m) for m in itertools.product([list(r) for r in itertools.product(range(26), repeat=3)], repeat=3)])"
1386 "language": "python",
1390 "ename": "KeyboardInterrupt",
1392 "output_type": "pyerr",
1394 "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
1395 "\u001b[1;31mKeyboardInterrupt\u001b[0m: "
1399 "prompt_number": 203
1402 "cell_type": "code",
1407 "language": "python",
1412 "output_type": "pyout",
1413 "prompt_number": 202,
1419 "prompt_number": 202
1422 "cell_type": "code",
1425 "[np.matrix(list(m)) for m in itertools.product([list(r) for r in itertools.product(range(3), repeat=2)], repeat=2)]"
1427 "language": "python",
1432 "output_type": "pyout",
1433 "prompt_number": 206,
1435 "[matrix([[0, 0],\n",
1436 " [0, 0]]), matrix([[0, 0],\n",
1437 " [0, 1]]), matrix([[0, 0],\n",
1438 " [0, 2]]), matrix([[0, 0],\n",
1439 " [1, 0]]), matrix([[0, 0],\n",
1440 " [1, 1]]), matrix([[0, 0],\n",
1441 " [1, 2]]), matrix([[0, 0],\n",
1442 " [2, 0]]), matrix([[0, 0],\n",
1443 " [2, 1]]), matrix([[0, 0],\n",
1444 " [2, 2]]), matrix([[0, 1],\n",
1445 " [0, 0]]), matrix([[0, 1],\n",
1446 " [0, 1]]), matrix([[0, 1],\n",
1447 " [0, 2]]), matrix([[0, 1],\n",
1448 " [1, 0]]), matrix([[0, 1],\n",
1449 " [1, 1]]), matrix([[0, 1],\n",
1450 " [1, 2]]), matrix([[0, 1],\n",
1451 " [2, 0]]), matrix([[0, 1],\n",
1452 " [2, 1]]), matrix([[0, 1],\n",
1453 " [2, 2]]), matrix([[0, 2],\n",
1454 " [0, 0]]), matrix([[0, 2],\n",
1455 " [0, 1]]), matrix([[0, 2],\n",
1456 " [0, 2]]), matrix([[0, 2],\n",
1457 " [1, 0]]), matrix([[0, 2],\n",
1458 " [1, 1]]), matrix([[0, 2],\n",
1459 " [1, 2]]), matrix([[0, 2],\n",
1460 " [2, 0]]), matrix([[0, 2],\n",
1461 " [2, 1]]), matrix([[0, 2],\n",
1462 " [2, 2]]), matrix([[1, 0],\n",
1463 " [0, 0]]), matrix([[1, 0],\n",
1464 " [0, 1]]), matrix([[1, 0],\n",
1465 " [0, 2]]), matrix([[1, 0],\n",
1466 " [1, 0]]), matrix([[1, 0],\n",
1467 " [1, 1]]), matrix([[1, 0],\n",
1468 " [1, 2]]), matrix([[1, 0],\n",
1469 " [2, 0]]), matrix([[1, 0],\n",
1470 " [2, 1]]), matrix([[1, 0],\n",
1471 " [2, 2]]), matrix([[1, 1],\n",
1472 " [0, 0]]), matrix([[1, 1],\n",
1473 " [0, 1]]), matrix([[1, 1],\n",
1474 " [0, 2]]), matrix([[1, 1],\n",
1475 " [1, 0]]), matrix([[1, 1],\n",
1476 " [1, 1]]), matrix([[1, 1],\n",
1477 " [1, 2]]), matrix([[1, 1],\n",
1478 " [2, 0]]), matrix([[1, 1],\n",
1479 " [2, 1]]), matrix([[1, 1],\n",
1480 " [2, 2]]), matrix([[1, 2],\n",
1481 " [0, 0]]), matrix([[1, 2],\n",
1482 " [0, 1]]), matrix([[1, 2],\n",
1483 " [0, 2]]), matrix([[1, 2],\n",
1484 " [1, 0]]), matrix([[1, 2],\n",
1485 " [1, 1]]), matrix([[1, 2],\n",
1486 " [1, 2]]), matrix([[1, 2],\n",
1487 " [2, 0]]), matrix([[1, 2],\n",
1488 " [2, 1]]), matrix([[1, 2],\n",
1489 " [2, 2]]), matrix([[2, 0],\n",
1490 " [0, 0]]), matrix([[2, 0],\n",
1491 " [0, 1]]), matrix([[2, 0],\n",
1492 " [0, 2]]), matrix([[2, 0],\n",
1493 " [1, 0]]), matrix([[2, 0],\n",
1494 " [1, 1]]), matrix([[2, 0],\n",
1495 " [1, 2]]), matrix([[2, 0],\n",
1496 " [2, 0]]), matrix([[2, 0],\n",
1497 " [2, 1]]), matrix([[2, 0],\n",
1498 " [2, 2]]), matrix([[2, 1],\n",
1499 " [0, 0]]), matrix([[2, 1],\n",
1500 " [0, 1]]), matrix([[2, 1],\n",
1501 " [0, 2]]), matrix([[2, 1],\n",
1502 " [1, 0]]), matrix([[2, 1],\n",
1503 " [1, 1]]), matrix([[2, 1],\n",
1504 " [1, 2]]), matrix([[2, 1],\n",
1505 " [2, 0]]), matrix([[2, 1],\n",
1506 " [2, 1]]), matrix([[2, 1],\n",
1507 " [2, 2]]), matrix([[2, 2],\n",
1508 " [0, 0]]), matrix([[2, 2],\n",
1509 " [0, 1]]), matrix([[2, 2],\n",
1510 " [0, 2]]), matrix([[2, 2],\n",
1511 " [1, 0]]), matrix([[2, 2],\n",
1512 " [1, 1]]), matrix([[2, 2],\n",
1513 " [1, 2]]), matrix([[2, 2],\n",
1514 " [2, 0]]), matrix([[2, 2],\n",
1515 " [2, 1]]), matrix([[2, 2],\n",
1520 "prompt_number": 206
1523 "cell_type": "code",
1526 "all_matrices = [np.matrix(list(m)) for m in itertools.product([list(r) for r in itertools.product(range(26), repeat=2)], repeat=2)]\n",
1527 "valid_matrices = [m for m, d in zip(all_matrices, (int(round(linalg.det(m))) for m in all_matrices))\n",
1530 " if d % 13 != 0 ]\n",
1531 "len(valid_matrices)"
1533 "language": "python",
1538 "output_type": "pyout",
1539 "prompt_number": 215,
1545 "prompt_number": 215
1548 "cell_type": "code",
1552 "[m for m, d in zip(all_matrices, (int(round(linalg.det(m))) for m in all_matrices))\n",
1555 " if d % 13 != 0 ]\n",
1558 "language": "python",
1562 "output_type": "stream",
1570 "output_type": "stream",
1578 "output_type": "stream",
1586 "output_type": "stream",
1590 "1 loops, best of 3: 10 s per loop\n"
1594 "prompt_number": 216
1597 "cell_type": "code",
1601 "[m for m in all_matrices\n",
1602 " if int(round(linalg.det(m))) != 0\n",
1603 " if int(round(linalg.det(m))) % 2 != 0\n",
1604 " if int(round(linalg.det(m))) % 13 != 0 ]\n",
1607 "language": "python",
1611 "output_type": "stream",
1619 "output_type": "stream",
1627 "output_type": "stream",
1635 "output_type": "stream",
1639 "1 loops, best of 3: 20.4 s per loop\n"
1643 "prompt_number": 217
1646 "cell_type": "code",
1649 "language": "python",