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 cipher import *\n",
21 "from cipherbreak import *\n",
23 "c6a = open('2014/6a.ciphertext').read()\n",
24 "c6b = open('2014/6b.ciphertext').read()"
37 "(3, -2314.997881051078)"
42 "output_type": "execute_result"
46 "key_a, score = railfence_break(sanitise(c6a))\n",
60 "'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'"
65 "output_type": "execute_result"
69 "' '.join(segment(railfence_decipher(sanitise(c6a), key_a)))"
82 "'hwssswxfewhhrfewpdrvttdhxbccleayphalnadhiehaoudrotwnrrvysabjlttbaytmelrkaidopthatlelrtwaamaneksvvzrvllatkcrjquicizgtoqcpnrrkttowandqehtqrvtbaydqealannohulanuzlwextlvjrvivhnohdqmgykaclmswrupdetfioftfelhzpxhaswftwprrsweiseohefpdrvttnvagdvswgoerbetnharvaeevtlltbmgaiatgelinmdawevhatterdhrznbnvoutnefoteveaehlaymhacglzeptvvdimworfisgtuzlwibeqohubtghamqornjnnrumqvjtxeltfovgawdaeevllgrtxibgtibevmpsaateoasevaeyqohameonncfuidoefafattemuimnflznbekofobrliaehhauihnnnwzaeevtlltpaalnanvtzlzuucptaelinanpaahewfthaosetaribnbnvhaevdhyytlmuxb'"
87 "output_type": "execute_result"
91 "c6bs = sanitise(c6b)\n",
97 "execution_count": 17,
635 "execution_count": 17,
637 "output_type": "execute_result"
641 "c6b_nums = [ord(c) - ord('a') for c in c6bs]\n",
647 "execution_count": 106,
655 "matrix([[ 7, 8],\n",
659 "execution_count": 106,
661 "output_type": "execute_result"
665 "m = np.matrix([[7,8], [11,11]])\n",
671 "execution_count": 107,
679 "-11.000000000000002"
682 "execution_count": 107,
684 "output_type": "execute_result"
693 "execution_count": 108,
701 "matrix([[-1. , 0.72727273],\n",
702 " [ 1. , -0.63636364]])"
705 "execution_count": 108,
707 "output_type": "execute_result"
716 "execution_count": 37,
728 "execution_count": 37,
730 "output_type": "execute_result"
734 "v = np.matrix([[7], [22]])\n",
740 "execution_count": 46,
752 "execution_count": 46,
754 "output_type": "execute_result"
764 "execution_count": 48,
776 "execution_count": 48,
778 "output_type": "execute_result"
782 "np.linalg.solve(m, c) % 26"
787 "execution_count": 40,
799 "execution_count": 40,
801 "output_type": "execute_result"
810 "execution_count": 41,
822 "execution_count": 41,
824 "output_type": "execute_result"
833 "execution_count": 42,
845 "execution_count": 42,
847 "output_type": "execute_result"
851 "np.linalg.solve(m, (m*v)%26)%26"
856 "execution_count": 51,
867 "execution_count": 51,
869 "output_type": "execute_result"
878 "execution_count": 181,
884 "def hill_encipher(matrix, message_letters, fillvalue='a'):\n",
885 " n = len(matrix)\n",
886 " sanitised_message = sanitise(message_letters)\n",
887 " if len(sanitised_message) % n != 0:\n",
888 " padding = fillvalue[0] * (n - len(sanitised_message) % n)\n",
891 " message = [ord(c) - ord('a') for c in sanitised_message + padding]\n",
892 " message_chunks = [message[i:i+n] for i in range(0, len(message), n)]\n",
893 " # message_chunks = chunks(message, len(matrix), fillvalue=None)\n",
894 " enciphered_chunks = [((matrix * np.matrix(c).T).T).tolist()[0] for c in message_chunks]\n",
895 " return ''.join([chr(int(round(l)) % 26 + ord('a')) for l in sum(enciphered_chunks, [])])"
900 "execution_count": 156,
911 "execution_count": 156,
913 "output_type": "execute_result"
917 "hill_encipher(m, 'hellothere')"
922 "execution_count": 68,
930 "[7, 4, 11, 11, 14, 19, 7, 4, 17, 4]"
933 "execution_count": 68,
935 "output_type": "execute_result"
939 "msg = [ord(c) - ord('a') for c in 'hellothere']\n",
945 "execution_count": 112,
953 "[[7, 11], [14, 25], [21, 14], [7, 11], [11, 15], [0, 0]]"
956 "execution_count": 112,
958 "output_type": "execute_result"
962 "msgc = [msg[i:i+len(m)] for i in range(0, len(msg), len(m))]\n",
968 "execution_count": 87,
979 "execution_count": 87,
981 "output_type": "execute_result"
985 "((m*np.matrix(msgc[0]).T).T % 26).tolist()[0]"
990 "execution_count": 195,
996 "def hill_decipher(matrix, message, fillvalue='a'):\n",
997 " adjugate = linalg.det(matrix)*linalg.inv(matrix)\n",
998 " inverse_determinant = modular_division_table[int(round(linalg.det(matrix))) % 26][1]\n",
999 " inverse_matrix = (inverse_determinant * adjugate) % 26\n",
1000 " return hill_encipher(inverse_matrix, message, fillvalue) "
1004 "cell_type": "code",
1005 "execution_count": 161,
1016 "execution_count": 161,
1018 "output_type": "execute_result"
1022 "hill_decipher(m, 'drjiqzdrvx')"
1026 "cell_type": "code",
1027 "execution_count": 114,
1035 "[3, 17, 9, 8, 16, 25, 3, 17, 21, 23, 0, 0]"
1038 "execution_count": 114,
1040 "output_type": "execute_result"
1044 "msg = [ord(c) - ord('a') for c in 'drjiqzdrvxaa']\n",
1049 "cell_type": "code",
1050 "execution_count": 115,
1058 "[[3, 17], [9, 8], [16, 25], [3, 17], [21, 23], [0, 0]]"
1061 "execution_count": 115,
1063 "output_type": "execute_result"
1067 "msgc = [msg[i:i+len(m)] for i in range(0, len(msg), len(m))]\n",
1072 "cell_type": "code",
1073 "execution_count": 116,
1081 "matrix([[ 9.36363636, 18.18181818]])"
1084 "execution_count": 116,
1086 "output_type": "execute_result"
1090 "(np.linalg.solve(m, np.matrix(msgc[0]).T).T % 26)"
1094 "cell_type": "code",
1095 "execution_count": 142,
1103 "matrix([[ 11., -8.],\n",
1107 "execution_count": 142,
1109 "output_type": "execute_result"
1113 "m_adj = linalg.det(m)*linalg.inv(m)\n",
1118 "cell_type": "code",
1119 "execution_count": 148,
1130 "execution_count": 148,
1132 "output_type": "execute_result"
1136 "modular_division_table[int(round(linalg.det(m))) % 26][1]"
1140 "cell_type": "code",
1141 "execution_count": 150,
1149 "matrix([[ 25., 22.],\n",
1153 "execution_count": 150,
1155 "output_type": "execute_result"
1159 "m_inv = (modular_division_table[int(round(linalg.det(m))) % 26][1] * m_adj) % 26\n",
1164 "cell_type": "code",
1165 "execution_count": 157,
1176 "execution_count": 157,
1178 "output_type": "execute_result"
1182 "hill_encipher(m_inv, 'drjiqzdrvx')"
1186 "cell_type": "code",
1187 "execution_count": 120,
1195 "matrix([[ 1., 0.],\n",
1199 "execution_count": 120,
1201 "output_type": "execute_result"
1205 "np.dot(m , 1/linalg.det(m) * mc)"
1209 "cell_type": "code",
1210 "execution_count": 122,
1218 "matrix([[ 6, 24, 1],\n",
1223 "execution_count": 122,
1225 "output_type": "execute_result"
1229 "ml = np.matrix([[6, 24, 1], [13, 16, 10], [20, 17, 15]])\n",
1234 "cell_type": "code",
1235 "execution_count": 137,
1243 "matrix([[ 18., 21., 16.],\n",
1244 " [ 5., 18., 5.],\n",
1245 " [ 5., 14., 18.]])"
1248 "execution_count": 137,
1250 "output_type": "execute_result"
1254 "ml_adj = linalg.det(ml)*linalg.inv(ml) % 26\n",
1259 "cell_type": "code",
1260 "execution_count": 138,
1271 "execution_count": 138,
1273 "output_type": "execute_result"
1277 "modular_division_table[int(linalg.det(ml) % 26)][1]"
1281 "cell_type": "code",
1282 "execution_count": 139,
1290 "matrix([[ 8., 5., 10.],\n",
1291 " [ 21., 8., 21.],\n",
1292 " [ 21., 12., 8.]])"
1295 "execution_count": 139,
1297 "output_type": "execute_result"
1301 "ml_inv = (modular_division_table[int(linalg.det(ml) % 26)][1] * ml_adj) % 26\n",
1306 "cell_type": "code",
1307 "execution_count": 193,
1318 "execution_count": 193,
1320 "output_type": "execute_result"
1324 "hill_encipher(ml, 'hello there')"
1328 "cell_type": "code",
1329 "execution_count": 196,
1340 "execution_count": 196,
1342 "output_type": "execute_result"
1346 "hill_decipher(ml, 'tfjflpznvyac')"
1350 "cell_type": "code",
1351 "execution_count": 182,
1362 "execution_count": 182,
1364 "output_type": "execute_result"
1368 "hill_encipher(ml, 'act')"
1372 "cell_type": "code",
1373 "execution_count": 192,
1380 "output_type": "stream",
1393 "execution_count": 192,
1395 "output_type": "execute_result"
1399 "hill_decipher(ml, 'poh')"
1403 "cell_type": "code",
1404 "execution_count": 180,
1415 "execution_count": 180,
1417 "output_type": "execute_result"
1421 "[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]]"
1425 "cell_type": "code",
1426 "execution_count": 184,
1437 "execution_count": 184,
1439 "output_type": "execute_result"
1443 "hill_encipher(ml_inv, 'poh')"
1447 "cell_type": "code",
1448 "execution_count": 203,
1454 "ename": "KeyboardInterrupt",
1456 "output_type": "error",
1458 "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
1459 "\u001b[1;31mKeyboardInterrupt\u001b[0m: "
1464 "len([list(m) for m in itertools.product([list(r) for r in itertools.product(range(26), repeat=3)], repeat=3)])"
1468 "cell_type": "code",
1469 "execution_count": 202,
1480 "execution_count": 202,
1482 "output_type": "execute_result"
1490 "cell_type": "code",
1491 "execution_count": 206,
1499 "[matrix([[0, 0],\n",
1500 " [0, 0]]), matrix([[0, 0],\n",
1501 " [0, 1]]), matrix([[0, 0],\n",
1502 " [0, 2]]), matrix([[0, 0],\n",
1503 " [1, 0]]), matrix([[0, 0],\n",
1504 " [1, 1]]), matrix([[0, 0],\n",
1505 " [1, 2]]), matrix([[0, 0],\n",
1506 " [2, 0]]), matrix([[0, 0],\n",
1507 " [2, 1]]), matrix([[0, 0],\n",
1508 " [2, 2]]), matrix([[0, 1],\n",
1509 " [0, 0]]), matrix([[0, 1],\n",
1510 " [0, 1]]), matrix([[0, 1],\n",
1511 " [0, 2]]), matrix([[0, 1],\n",
1512 " [1, 0]]), matrix([[0, 1],\n",
1513 " [1, 1]]), matrix([[0, 1],\n",
1514 " [1, 2]]), matrix([[0, 1],\n",
1515 " [2, 0]]), matrix([[0, 1],\n",
1516 " [2, 1]]), matrix([[0, 1],\n",
1517 " [2, 2]]), matrix([[0, 2],\n",
1518 " [0, 0]]), matrix([[0, 2],\n",
1519 " [0, 1]]), matrix([[0, 2],\n",
1520 " [0, 2]]), matrix([[0, 2],\n",
1521 " [1, 0]]), matrix([[0, 2],\n",
1522 " [1, 1]]), matrix([[0, 2],\n",
1523 " [1, 2]]), matrix([[0, 2],\n",
1524 " [2, 0]]), matrix([[0, 2],\n",
1525 " [2, 1]]), matrix([[0, 2],\n",
1526 " [2, 2]]), matrix([[1, 0],\n",
1527 " [0, 0]]), matrix([[1, 0],\n",
1528 " [0, 1]]), matrix([[1, 0],\n",
1529 " [0, 2]]), matrix([[1, 0],\n",
1530 " [1, 0]]), matrix([[1, 0],\n",
1531 " [1, 1]]), matrix([[1, 0],\n",
1532 " [1, 2]]), matrix([[1, 0],\n",
1533 " [2, 0]]), matrix([[1, 0],\n",
1534 " [2, 1]]), matrix([[1, 0],\n",
1535 " [2, 2]]), matrix([[1, 1],\n",
1536 " [0, 0]]), matrix([[1, 1],\n",
1537 " [0, 1]]), matrix([[1, 1],\n",
1538 " [0, 2]]), matrix([[1, 1],\n",
1539 " [1, 0]]), matrix([[1, 1],\n",
1540 " [1, 1]]), matrix([[1, 1],\n",
1541 " [1, 2]]), matrix([[1, 1],\n",
1542 " [2, 0]]), matrix([[1, 1],\n",
1543 " [2, 1]]), matrix([[1, 1],\n",
1544 " [2, 2]]), matrix([[1, 2],\n",
1545 " [0, 0]]), matrix([[1, 2],\n",
1546 " [0, 1]]), matrix([[1, 2],\n",
1547 " [0, 2]]), matrix([[1, 2],\n",
1548 " [1, 0]]), matrix([[1, 2],\n",
1549 " [1, 1]]), matrix([[1, 2],\n",
1550 " [1, 2]]), matrix([[1, 2],\n",
1551 " [2, 0]]), matrix([[1, 2],\n",
1552 " [2, 1]]), matrix([[1, 2],\n",
1553 " [2, 2]]), matrix([[2, 0],\n",
1554 " [0, 0]]), matrix([[2, 0],\n",
1555 " [0, 1]]), matrix([[2, 0],\n",
1556 " [0, 2]]), matrix([[2, 0],\n",
1557 " [1, 0]]), matrix([[2, 0],\n",
1558 " [1, 1]]), matrix([[2, 0],\n",
1559 " [1, 2]]), matrix([[2, 0],\n",
1560 " [2, 0]]), matrix([[2, 0],\n",
1561 " [2, 1]]), matrix([[2, 0],\n",
1562 " [2, 2]]), matrix([[2, 1],\n",
1563 " [0, 0]]), matrix([[2, 1],\n",
1564 " [0, 1]]), matrix([[2, 1],\n",
1565 " [0, 2]]), matrix([[2, 1],\n",
1566 " [1, 0]]), matrix([[2, 1],\n",
1567 " [1, 1]]), matrix([[2, 1],\n",
1568 " [1, 2]]), matrix([[2, 1],\n",
1569 " [2, 0]]), matrix([[2, 1],\n",
1570 " [2, 1]]), matrix([[2, 1],\n",
1571 " [2, 2]]), matrix([[2, 2],\n",
1572 " [0, 0]]), matrix([[2, 2],\n",
1573 " [0, 1]]), matrix([[2, 2],\n",
1574 " [0, 2]]), matrix([[2, 2],\n",
1575 " [1, 0]]), matrix([[2, 2],\n",
1576 " [1, 1]]), matrix([[2, 2],\n",
1577 " [1, 2]]), matrix([[2, 2],\n",
1578 " [2, 0]]), matrix([[2, 2],\n",
1579 " [2, 1]]), matrix([[2, 2],\n",
1583 "execution_count": 206,
1585 "output_type": "execute_result"
1589 "[np.matrix(list(m)) for m in itertools.product([list(r) for r in itertools.product(range(3), repeat=2)], repeat=2)]"
1593 "cell_type": "code",
1594 "execution_count": 215,
1605 "execution_count": 215,
1607 "output_type": "execute_result"
1611 "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",
1612 "valid_matrices = [m for m, d in zip(all_matrices, (int(round(linalg.det(m))) for m in all_matrices))\n",
1615 " if d % 13 != 0 ]\n",
1616 "len(valid_matrices)"
1620 "cell_type": "code",
1621 "execution_count": 216,
1628 "output_type": "stream",
1634 "1 loops, best of 3: 10 s per loop\n"
1640 "[m for m, d in zip(all_matrices, (int(round(linalg.det(m))) for m in all_matrices))\n",
1643 " if d % 13 != 0 ]\n",
1648 "cell_type": "code",
1649 "execution_count": 217,
1656 "output_type": "stream",
1662 "1 loops, best of 3: 20.4 s per loop\n"
1668 "[m for m in all_matrices\n",
1669 " if int(round(linalg.det(m))) != 0\n",
1670 " if int(round(linalg.det(m))) % 2 != 0\n",
1671 " if int(round(linalg.det(m))) % 13 != 0 ]\n",
1676 "cell_type": "code",
1677 "execution_count": null,
1687 "display_name": "Python 3",
1688 "language": "python",
1692 "codemirror_mode": {
1696 "file_extension": ".py",
1697 "mimetype": "text/x-python",
1699 "nbconvert_exporter": "python",
1700 "pygments_lexer": "ipython3",