Done challenge 5
authorNeil Smith <neil.git@njae.me.uk>
Thu, 30 Apr 2020 17:51:42 +0000 (18:51 +0100)
committerNeil Smith <neil.git@njae.me.uk>
Thu, 30 Apr 2020 17:51:42 +0000 (18:51 +0100)
2020-early/2020-a-challenge5.ipynb [new file with mode: 0644]
2020-early/2020-a-challenge5.md [new file with mode: 0644]
2020-early/5a.ciphertext [new file with mode: 0644]
2020-early/5a.plaintext [new file with mode: 0644]
2020-early/5b.ciphertext [new file with mode: 0644]
2020-early/5b.plaintext [new file with mode: 0644]

diff --git a/2020-early/2020-a-challenge5.ipynb b/2020-early/2020-a-challenge5.ipynb
new file mode 100644 (file)
index 0000000..9e73729
--- /dev/null
@@ -0,0 +1,422 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import os,sys,inspect\n",
+    "currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))\n",
+    "parentdir = os.path.dirname(currentdir)\n",
+    "sys.path.insert(0,parentdir) "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from cipher.caesar import *\n",
+    "from cipher.affine import *\n",
+    "from cipher.keyword_cipher import *\n",
+    "from cipher.column_transposition import *\n",
+    "\n",
+    "from support.text_prettify import *\n",
+    "from support.utilities import *\n",
+    "from support.plot_frequency_histogram import *\n",
+    "%matplotlib inline"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "challenge_number = 5\n",
+    "plaintext_a_filename = f'{challenge_number}a.plaintext'\n",
+    "plaintext_b_filename = f'{challenge_number}b.plaintext'\n",
+    "ciphertext_a_filename = f'{challenge_number}a.ciphertext'\n",
+    "ciphertext_b_filename = f'{challenge_number}b.ciphertext'"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ca = open(ciphertext_a_filename).read()\n",
+    "cb = open(ciphertext_b_filename).read()\n",
+    "\n",
+    "sca = sanitise(ca)\n",
+    "pca = letters(ca)\n",
+    "pta = depunctuate(ca)\n",
+    "\n",
+    "scb = sanitise(cb)\n",
+    "pcb = letters(cb)\n",
+    "ptb = depunctuate(cb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fc = collections.Counter(sca)\n",
+    "plot_frequency_histogram(fc, sort_key=fc.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "14"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kshifta, score = caesar_break(sca, fitness=Ptrigrams)\n",
+    "kshifta"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "foodhoaihbfxkpdnfeeadlnoijxihofxonahozdmldhxzgahanolvimflgfgdhonnfvviptaeeqdolfrdeeahyoihiltfvnoijgannaihoiolfhnjilohilnczvslinoixcimzdfrvtfodloifnfmdeixfoaihnoijzfllvfncdsgdoiimmdlvipiplnpjjilonoijqinnahodeeaydhxdldjilonnpyydnoozfoozdydlgfhgaeaoflvfldxeindevgihaoilahyfeeqifonfhsmeayzonahfhsipoimhiltfvnoijnpyydnonjeaooahyxflyinoijxaraeafhmeayzonfenilancvnoijlfmzfrdimmdldsfjefhdnoijtaeexihofxoviprafozddgqfnnvnoijiozdlxiggphaxfoaihxzfhhdenahndxpldnoijsihioldjevoiozanodedylfggdnnfyddhsn\n"
+     ]
+    }
+   ],
+   "source": [
+    "pa = caesar_decipher(sca, kshifta)\n",
+    "print(pa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('telegram', <KeywordWrapAlphabet.from_last: 2>)"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(kworda, kwrapa), score = keyword_break_mp(sca, fitness=Ptrigrams)\n",
+    "kworda, kwrapa"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "attentionjacquesallierstopcontactsinthefrenchministryofarmamentssayyouwillbetravellingtonorwaystopmissiontotransportnorskhydrostockofheavywatertoasafelocationstopharryaskedmetoofferyouoursupportstopbossintelligencereportssuggestthatthegermanmilitaryarecloselymonitoringallboatsandflightsinandoutofnorwaystopsuggestsplittingcargostopcivilianflightsalsoriskystoprafhaveofferedaplanestopwillcontactyouviatheembassystopothercommunicationchannelsinsecurestopdonotreplytothistelegrammessageends\n"
+     ]
+    }
+   ],
+   "source": [
+    "pa = keyword_decipher(sca, kworda, kwrapa)\n",
+    "print(pa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "attention jacques allier stop contacts in the french ministry of armaments say you will be\n",
+      "travelling to norway stop mission to transport norsk hydro stock of heavy water to a safe locations\n",
+      "top harry asked me to offer you our support stop boss intelligence reports suggest that the german\n",
+      "military are closely monitoring all boats and flights in and out of norway stop suggest splitting\n",
+      "cargo stop civilian flights also risky stop raf have offered a planes top will contact you via the\n",
+      "embassy stop other communication channels insecure stop do not reply to this telegram message ends\n"
+     ]
+    }
+   ],
+   "source": [
+    "fpa = lcat(tpack(segment(pa)))\n",
+    "print(fpa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "585"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_a_filename, 'w').write(fpa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAa0AAAEiCAYAAABKsI06AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAUQklEQVR4nO3dfbRldX3f8fcnjMqDGgQuFnnIRdcsE2KagCMLo3ZZMQ2KEbIKqdSEiaFraqXRxFCF2hSXrStjddUma0WTEaiTSlFCNNBgEulEQ4yCzgxPA2iYwggjExmfiECrjnz7x95TTskd5pyz7+HOb+77tdZd9+yH3/l9z777nM/57bPvPqkqJElqwQ8tdQGSJI3L0JIkNcPQkiQ1w9CSJDXD0JIkNcPQkiQ1Y8VSFwBwxBFH1Pz8/FKXIUnaB2zatOnrVTW30LJ9IrTm5+fZuHHjUpchSdoHJPnKnpZ5eFCS1AxDS5LUDENLktQMQ0uS1AxDS5LUDENLktQMQ0uS1AxDS5LUDENLktQMQ0uS1Ix94jJOkqR90/yF14697ra1p8+wko4jLUlSMwwtSVIzDC1JUjMMLUlSMwwtSVIzDC1JUjMMLUlSMwwtSVIzDC1JUjP2GlpJLkvyQJItCyy7IEklOaKfTpLfSbI1ya1JTppF0ZKk5WmckdaHgdMePzPJscDPAPeOzH4VsLL/WQN8cHiJkiR19hpaVXU98M0FFr0feBtQI/POAP6gOjcAhyY5alEqlSQte1N9ppXktcBXq+qWxy06GrhvZHp7P2+h+1iTZGOSjTt37pymDEnSMjNxaCU5GHgH8O8XWrzAvFpgHlW1rqpWVdWqubm5ScuQJC1D03w1yfOA44FbkgAcA2xOcjLdyOrYkXWPAe4fWqQkSTDFSKuqbquqI6tqvqrm6YLqpKr6W+Aa4Nz+LMJTgAerasfilixJWq7GOeX9CuDzwPOTbE9y3hOs/kngbmAr8CHgTYtSpSRJjHF4sKrO2cvy+ZHbBZw/vCxJkv4+r4ghSWqGoSVJaoahJUlqhqElSWqGoSVJaoahJUlqxjRXxJAkNWb+wmvHXnfb2tNnWMkwjrQkSc0wtCRJzTC0JEnNMLQkSc0wtCRJzTC0JEnNMLQkSc0wtCRJzTC0JEnNMLQkSc0wtCRJzTC0JEnNMLQkSc0wtCRJzfCrSSSpEZN8vQjs218xMi1HWpKkZhhakqRm7DW0klyW5IEkW0bmvTfJl5LcmuQTSQ4dWXZRkq1JvpzkZ2dVuCRp+RlnpPVh4LTHzbsOeEFV/UPgb4CLAJKcALwO+PG+zQeSHLBo1UqSlrW9hlZVXQ9883HzPlVVu/rJG4Bj+ttnAB+tqu9W1T3AVuDkRaxXkrSMLcZnWr8C/Gl/+2jgvpFl2/t5kiQNNii0krwD2AVcvnvWAqvVHtquSbIxycadO3cOKUOStExMHVpJVgOvAV5fVbuDaTtw7MhqxwD3L9S+qtZV1aqqWjU3NzdtGZKkZWSq0EpyGvB24LVV9cjIomuA1yV5WpLjgZXAF4aXKUnSGFfESHIF8HLgiCTbgYvpzhZ8GnBdEoAbquqNVXV7kiuBO+gOG55fVT+YVfGSpOVlr6FVVecsMPvSJ1j/3cC7hxQlSdJCvCKGJKkZhpYkqRmGliSpGYaWJKkZhpYkqRmGliSpGYaWJKkZhpYkqRmGliSpGYaWJKkZhpYkqRmGliSpGYaWJKkZhpYkqRmGliSpGYaWJKkZhpYkqRmGliSpGYaWJKkZhpYkqRmGliSpGSuWugBJWm7mL7x2ovW3rT19RpW0x5GWJKkZhpYkqRmGliSpGXsNrSSXJXkgyZaReYcluS7JXf3vZ/Xzk+R3kmxNcmuSk2ZZvCRpeRlnpPVh4LTHzbsQ2FBVK4EN/TTAq4CV/c8a4IOLU6YkSWOEVlVdD3zzcbPPANb3t9cDZ47M/4Pq3AAcmuSoxSpWkrS8TXvK+7OragdAVe1IcmQ//2jgvpH1tvfzdjz+DpKsoRuNcdxxx01ZhiQtnUlOXfe09cWx2CdiZIF5tdCKVbWuqlZV1aq5ublFLkOStD+aNrS+tvuwX//7gX7+duDYkfWOAe6fvjxJkh4zbWhdA6zub68Grh6Zf25/FuEpwIO7DyNKkjTUXj/TSnIF8HLgiCTbgYuBtcCVSc4D7gXO7lf/JPBqYCvwCPCGGdQsSVqm9hpaVXXOHhadusC6BZw/tChJkhbiFTEkSc0wtCRJzTC0JEnNMLQkSc3wSyAlLXte2aIdjrQkSc1wpCVpv+BX2C8PjrQkSc0wtCRJzTC0JEnNMLQkSc0wtCRJzTC0JEnNMLQkSc0wtCRJzTC0JEnN8IoYkvYpXtlCT8TQkjQTXoRWs+DhQUlSMwwtSVIzDC1JUjMMLUlSMwwtSVIzDC1JUjMGhVaSX09ye5ItSa5IcmCS45PcmOSuJB9L8tTFKlaStLxNHVpJjgbeDKyqqhcABwCvA94DvL+qVgLfAs5bjEIlSRp6eHAFcFCSFcDBwA7gFcBV/fL1wJkD+5AkCRgQWlX1VeB9wL10YfUgsAn4dlXt6lfbDhy9UPska5JsTLJx586d05YhSVpGhhwefBZwBnA88BzgEOBVC6xaC7WvqnVVtaqqVs3NzU1bhiRpGRlyePCVwD1VtbOqvg98HPhp4ND+cCHAMcD9A2uUJAkYFlr3AqckOThJgFOBO4BPA2f166wGrh5WoiRJnSGfad1Id8LFZuC2/r7WAW8H3ppkK3A4cOki1ClJ0rCvJqmqi4GLHzf7buDkIfcrSdJCvCKGJKkZhpYkqRmGliSpGYaWJKkZhpYkqRmGliSpGYaWJKkZhpYkqRmGliSpGYaWJKkZhpYkqRmGliSpGYaWJKkZhpYkqRmGliSpGYaWJKkZhpYkqRmGliSpGYaWJKkZhpYkqRmGliSpGYaWJKkZhpYkqRmGliSpGSuGNE5yKHAJ8AKggF8Bvgx8DJgHtgG/UFXfGlSlpCUzf+G1Y6+7be3pM6xEGj7S+m3gz6rqR4GfBO4ELgQ2VNVKYEM/LUnSYFOHVpJnAv8IuBSgqr5XVd8GzgDW96utB84cWqQkSTBspPVcYCfwX5PclOSSJIcAz66qHQD97yMXoU5JkgaF1grgJOCDVXUi8DATHApMsibJxiQbd+7cOaAMSdJyMSS0tgPbq+rGfvoquhD7WpKjAPrfDyzUuKrWVdWqqlo1Nzc3oAxJ0nIxdWhV1d8C9yV5fj/rVOAO4BpgdT9vNXD1oAolSeoNOuUd+FXg8iRPBe4G3kAXhFcmOQ+4Fzh7YB+SJAEDQ6uqbgZWLbDo1CH3K0nSQrwihiSpGYaWJKkZhpYkqRmGliSpGYaWJKkZhpYkqRmGliSpGYaWJKkZhpYkqRmGliSpGYaWJKkZhpYkqRmGliSpGYaWJKkZhpYkqRmGliSpGYaWJKkZhpYkqRmGliSpGYaWJKkZhpYkqRkrlroASbM3f+G1E62/be3pM6pEGsaRliSpGYaWJKkZhpYkqRmDQyvJAUluSvIn/fTxSW5McleSjyV56vAyJUlanJHWW4A7R6bfA7y/qlYC3wLOW4Q+JEkaFlpJjgFOBy7ppwO8AriqX2U9cOaQPiRJ2m3oKe//BXgb8Ix++nDg21W1q5/eDhy9UMMka4A1AMcdd9zAMqTlwVPXtdxNPdJK8hrggaraNDp7gVVrofZVta6qVlXVqrm5uWnLkCQtI0NGWi8BXpvk1cCBwDPpRl6HJlnRj7aOAe4fXqYkSQNCq6ouAi4CSPJy4IKqen2SPwTOAj4KrAauXoQ6pf3KJIf5PMQnPWYW/6f1duCtSbbSfcZ16Qz6kCQtQ4ty7cGq+gzwmf723cDJi3G/0r7OEZP05PKKGJKkZniVdy17nkYutcORliSpGYaWJKkZHh7UfsPDfNL+z5GWJKkZhpYkqRmGliSpGYaWJKkZnoihfY5XmZC0J460JEnNMLQkSc0wtCRJzTC0JEnNMLQkSc0wtCRJzTC0JEnNMLQkSc0wtCRJzfCKGJoZr2whabE50pIkNcPQkiQ1w9CSJDXD0JIkNWPq0EpybJJPJ7kzye1J3tLPPyzJdUnu6n8/a/HKlSQtZ0NGWruA36iqHwNOAc5PcgJwIbChqlYCG/ppSZIGmzq0qmpHVW3ub38HuBM4GjgDWN+vth44c2iRkiTBIn2mlWQeOBG4EXh2Ve2ALtiAI/fQZk2SjUk27ty5czHKkCTt5waHVpKnA38E/FpV/d247apqXVWtqqpVc3NzQ8uQJC0Dg0IryVPoAuvyqvp4P/trSY7qlx8FPDCsREmSOkPOHgxwKXBnVf3nkUXXAKv726uBq6cvT5Kkxwy59uBLgF8Cbktycz/v3wJrgSuTnAfcC5w9rERJkjpTh1ZVfRbIHhafOu39ajYmuXgtPHYB22nbSdIseEUMSVIzDC1JUjMMLUlSM/wSyMb4xYqSljNHWpKkZhhakqRmeHhwiXiYT5Im50hLktQMQ0uS1AxDS5LUDENLktQMQ0uS1AxDS5LUDENLktQMQ0uS1AxDS5LUDENLktQMQ0uS1AxDS5LUDENLktQMQ0uS1AxDS5LUDENLktQMvwSSyb6QER77UsZp20mSpjOz0EpyGvDbwAHAJVW1dlZ97ea3AUvS/m0mhweTHAD8LvAq4ATgnCQnzKIvSdLyMavPtE4GtlbV3VX1PeCjwBkz6kuStEzMKrSOBu4bmd7ez5MkaWqpqsW/0+Rs4Ger6l/0078EnFxVvzqyzhpgTT/5fODLi17IY44Avr4ft1uKPn2Mi99uKfr0MS5+u6Xos6XHOI4fqaq5BZdU1aL/AC8G/nxk+iLgoln0NWY9G/fndi3V6mPct/r0MfoYn+zHOPRnVocHvwisTHJ8kqcCrwOumVFfkqRlYianvFfVriT/GvhzulPeL6uq22fRlyRp+ZjZ/2lV1SeBT87q/ie0bj9vtxR9+hgXv91S9OljXPx2S9FnS49xkJmciCFJ0ix47UFJUjMMrSeQ5HNLXcPeJJlPsmV/7a9FSd6c5M4kly91LXuT5KGB7d+Z5ILFqmcPfSzJPtfC83+IJIcmedNS1zEpQ+sJVNVPL3UNatKbgFdX1euXuhBNb+jzP519+TX2ULp9tSn78gYdJMmLktya5MAkhyS5PckLJryPid6FJnlHki8n+Z9Jrhj3HWiS94y+4+nfvf7GJH337Z6b5KYkL9rLev8hyVtGpt+d5M0TdLUiyfp++16V5OAxaptP8qVJ2/Vtz+3b3JLkv42x/tt2P54k70/yF/3tU5N8ZIz2v9nXet0kf8e+7e8BzwWuSfLrY6y/e7tckmRLksuTvDLJXye5K8nJY7TfMjJ9QZJ3jlvvNEb3c7oLA4zb7pAk1/Z/xy1J/tkE3R6Q5EP98/hTSQ4ao7/5fsQ7UbuR9hOPQkf6/ACwGTh2zHZv7bfJliS/NmGff5xkU/8Y1+y9xf+zFnhekpuTvHeC/n4xyRf6dr+f7lqzT56l+OewJ+sH+I/A++gu3jvxPzcDD02w7guB24CDgWcCW4ELxmx7IvCXI9N3AMeN2XYe2EL34nET8FNjttnc3/4h4H8Bh0/QXwEv6acvG+dxDmj343RXSzminz5sjDanAH/Y3/4r4AvAU4CLgX+5l7argJuBg4BnAHeN+3ccuY9tu+sdc7vsAn6i/1ts6rdN6K7X+cfj/P1Hpi8A3jmLfXwR9vN/CnxoZPqHJ9xGP9VPXwn84qzaTbttRvp8FDhlim16CPB04HbgxAnaH9b/Pqh/LZjkubxl3H76Nj8G/A/gKf30B4BzJ91OQ37225FW713Az9C9EP2nGff1MuATVfVIVf0dE/wzdVXdBByZ5DlJfhL4VlXdO0Hfc8DVdE/Im8fobxvwjSQnAv8EuKmqvjFBf/dV1V/3tz8CvHSG7V4BXFVVXweoqm+O0WYT8MIkzwC+C3yebh94GV2IPZGXAldX1f+uqu/QPUFn7Z6quq2qHqV7wdpQ3SvCbXQvLPuSqfdzusfzyv7Iwsuq6sEJ2t4zsm9vYvztMm27Ib5SVTdMsP5L6bbpw1X1EPBxuu08rjcnuQW4gW5kt3KCtpM6lS5kv5jk5n76uTPs7+/Z378E8jC6dy5PAQ4EHp5xf0P+f+Aq4CzgH9BdFX8SD9JdoPgldC9647gE+OW+v8sm7O/xj3Pcxz1Nu0xw/92dVn0/yTbgDcDngFuBfww8D7hzjP6ebN8duf3oyPSj7P05uov//zD/gYtY155MtZ9X1d8keSHwauC3knyqqt41ZvPRbfQDulHFLNsNMenrzNT7XJKXA68EXlxVjyT5DLPdBwKsr6qLZtjHE9rfR1rrgN8ELgfeM+O+rgd+PslB/Tv8n5uw/UfpLnd1Fl2ATeJ7wJnAuUn++ZhtPgGcBryI7solkzguyYv72+cAn51huw3ALyQ5HCDJYWP2dT3dobLr6UZXbwRu7kcwT+SzwM/1n4U+HdjXvy30a3Sj9MOTPA14zYz7m3o/T/Ic4JGq+gjdYfuTZlRja64HzkxycJJDgJ9n70cEdvthuiMzjyT5UbpD4+P6Dt0h8ElsAM5KciR0z8ckPzLhfQyy3460kpwL7Kqq/95/UPi5JK+oqr+Y4G7GfkdZVZuTfIzu85CvMP5Ot7v97f2LwFerasckbfv2Dyd5DXBdkoer6uq9rP+9JJ8Gvl1VP5iwuzuB1Ul+n+4znw/Oql2/Xd4N/GWSH9B9bvfLY/T1V8A7gM/32+b/MMbfpKq+mOQa4Ba6v+NGupHsPqkfVb4LuBG4B/jSjPsbsp//BPDeJI8C3wf+1QxKbE6/TT9M99krdN/0ftOYzf8MeGOSW+k++x37sGRVfaM/4WcL8KdV9W/GaHNHkn8HfCrdmZHfB86n2xeeFF4RYw/6d/abq2qqdxH9GVwPVdX7FrWwRdLvcJuBs6vqriehv3ngT6pqojM4l0KSp1fVQ+nObrweWFNVm5e6Lkn7/+HBqfSHMT5Pdwhjv5PkBLqzvjY8GYHVoHX9h8ybgT8ysKR9hyMtSVIzHGlJkpphaEmSmmFoSZKaYWhJkpphaEmSmmFoSZKa8X8B/xyTWwFxHaAAAAAASUVORK5CYII=\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fc = collections.Counter(scb)\n",
+    "plot_frequency_histogram(fc, sort_key=fc.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'\\nf ryain lyelA ivmbe odahe swrwh cmoum eeirn ortdt eoier ndnes iutos grtao setth cnsca eoeig tanel aubyh rweeb utumt teieu rsaDo mflkr oigge yhitd rdaen hndue nuron odkoa ocfde talsh nhatd etaph ltnth gahdi oswea rcroo ddufn otnni asnat irari domkr dHsyh ooetN eotik naurn kbitj nsRau ngreh tOihm otiko wnfey ahrci gaowo thwao ontnk tbdwu erNyw oaeoe alvds tieti luelr heAat tsoli sbttp iIsva iitso shfet ueorp pnwhg ittio sshdo xsreo tcrne fruta baeci rrsag esnta phset meiem hdaet srtno audaf lneir dvreh naaed FRapA latnt harpd toeli edera hfier sntat trOea ugchy ietmh tiinc rfeao ditnn oucfl odute tbwle hifge shdst aeidh mhdha tthme oswko lhcoi etnsS uniiq rhree trsfu teFmh iaenr gtofm smnsi ieasw maeln risno ldaAc hgaer nitog fswsn aohte etrie utdba shrec eedar nieht dtosd abrgr teanr buguO oemHt aphnl eaict ntgdr eiert gdahn etifh ltegi pntic enrwe hidtt akass fwwfa eLhtu efapt nltmr etoht Wfear egyaH vrpnt oirss atnha aetwn thgit sScpu ecttk iensr geeat sphae tirhw taeom gtmde srmoA tlooS hctkf hmrto fngla iagom rskeo idlue rnhdn onduo ogrfo aaorc raasf cpeac dshee yrphu onarN wiWil heees nmtsh vmion tngio edrpr oignm haoln wlitw ohifr hdgae escrw egnte Anjna uRkap inltt ecrci rylod etnhh gesvi iitlo edubt hwhae iitot npssp uooge tthal ndeio ttipn tsata hhsea sryko dHrNo sofrm ltods oteni hngai asitr shoto thwad ohsrs dacrn esasB yadiP essee rPdaa eunBq aehtd twako drilh elrso Aluyr yiePv orarN wteos nfolm cdure eatvc ushra dvpte obsrs oehna edwwl aeodm hlfio hteao vnrdg aeWnr etaom arpti tinhg sieon mlvdv oeaun swiue arBex emiue toDhf emmrb eeila elruc Aeqsa tathJ stwhs oarnm meytA orfih snMir eceFn ofhmr tfrcf aiagt lnsoi ifssa Aslny'"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "rscb = cat(reversed(cb))\n",
+    "rscb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(((4, 1, 3, 5, 0, 2), False, False), -4695.301044758612)"
+      ]
+     },
+     "execution_count": 21,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(kwordb, fillb, emptyb), score = column_transposition_break_mp(scb, fitness=Ptrigrams)\n",
+    "(kwordb, fillb, emptyb), score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'analysisofsignalstrafficfromthefrenchministryofarmamentsshowthatjacquesallieramemberofthedeuxiemebureauwasinvolvedinsomethingimportantwearrangedtohavehimfollowedandhewasobservedtopurchasetraveldocumentsfornorwaypreviouslyallierhadworkedatthebanquedeparisdespaysbasandrecordsshowthatthisorganisationheldmostofnorskhydrossharesatthatpointleadingtothesuppositionthathewouldbevisitingthehydroelectricplantinrjukanagentswerechargedwithfollowinghimandreportingonhismovementswhileinnorwayhepurchasedspaceforacargoofaroundonehundredkilogramsonaflightfromstockholmtoamsterdamtogetherwithapassengerticketsuspectingthathewastransportingheavywaterfromtheplanttheluftwaffewastaskedwithinterceptingtheflightandredirectingtheplanetohamburgouragentsboardeditthereandsearcheditbuttherewasnosignofthecargoandalliersnamewasmissingfromthemanifestfurtherenquiriesinstockholmshowedthathehadmissedtheflightbutwecouldfindnotraceofhiminthecityouragentsattheairfieldreportedthatanrafplanehadarrivedandleftaroundthesametimeasthepassengeraircraftbutnorecordsexistshowingthepurposeofthatvisititispossiblethatallierusedittoleavenorwaybutwedonotknowwhatcargoifanyhetookwithhimouragentsinrjukanbrokeintothenorskhydroadministrationandfoundarecordshowingthattheplanthadheldastockofaroundonehundredandeightykilogramsofdeuteriumbuttheywereunabletogainaccesstothestorageunitsinordertodeterminehowmuchwasremovedbyallierifany'"
+      ]
+     },
+     "execution_count": 23,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pb = column_transposition_decipher(scb, kwordb, fillcolumnwise=fillb, emptycolumnwise=emptyb)\n",
+    "pb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "analysis of signals traffic from the french ministry of armaments show that jacques allier a member\n",
+      "of the deuxieme bureau was involved in something important we arranged to have him followed and he\n",
+      "was observed to purchase travel documents for norway previously allier had worked at the banque de\n",
+      "paris des pays bas and records show that this organisation held most of norsk hydros shares at that\n",
+      "point leading to the supposition that he would be visiting the hydroelectric plant in rj uk an\n",
+      "agents were charged with following him and reporting on his movements while in norway he purchased\n",
+      "space for a cargo of around one hundred kilograms on a flight from stockholm to amsterdam together\n",
+      "with a passenger ticket suspecting that he was transporting heavy water from the plant the luftwaffe\n",
+      "was tasked with intercepting the flight and redirecting the plane to hamburg our agents board edit\n",
+      "there and search edit but there was no sign of the cargo and all iers name was missing from the\n",
+      "manifest further enquiries in stockholm showed that he had missed the flight but we could find not\n",
+      "race of him in the city our agents at the airfield reported that an raf plane had arrived and left\n",
+      "around the same time as the passenger aircraft but no records exist showing the purpose of that\n",
+      "visit it is possible that allier used it to leave norway but we do not know what cargo if any he\n",
+      "took with him our agents in rj uk an broke into the norsk hydro administration and found a record\n",
+      "showing that the plant had held a stock of around one hundred and eighty kilograms of deuterium but\n",
+      "they were unable to gain access to the storage units in order to determine how much was removed by\n",
+      "allier if any\n"
+     ]
+    }
+   ],
+   "source": [
+    "fpb = lcat(tpack(segment(pb)))\n",
+    "print(fpb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1688"
+      ]
+     },
+     "execution_count": 25,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_b_filename, 'w').write(fpb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['menial',\n",
+       " 'pitman',\n",
+       " 'shtick',\n",
+       " 'thules',\n",
+       " 'thumbs',\n",
+       " 'thymes',\n",
+       " 'merrick',\n",
+       " 'pepsico',\n",
+       " 'pittman',\n",
+       " 'reticle',\n",
+       " 'retrial',\n",
+       " 'revival',\n",
+       " 'shticks',\n",
+       " 'skulker',\n",
+       " 'skylark',\n",
+       " 'slummer',\n",
+       " 'titular',\n",
+       " 'toupees',\n",
+       " 'tourist',\n",
+       " 'reticent',\n",
+       " 'skylarks',\n",
+       " 'tourists',\n",
+       " 'reticence']"
+      ]
+     },
+     "execution_count": 26,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "transpositions[kwordb]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "jupytext": {
+   "formats": "ipynb,md"
+  },
+  "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.7.4"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/2020-early/2020-a-challenge5.md b/2020-early/2020-a-challenge5.md
new file mode 100644 (file)
index 0000000..27ecfc1
--- /dev/null
@@ -0,0 +1,125 @@
+---
+jupyter:
+  jupytext:
+    formats: ipynb,md
+    text_representation:
+      extension: .md
+      format_name: markdown
+      format_version: '1.2'
+      jupytext_version: 1.3.4
+  kernelspec:
+    display_name: Python 3
+    language: python
+    name: python3
+---
+
+```python
+import os,sys,inspect
+currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
+parentdir = os.path.dirname(currentdir)
+sys.path.insert(0,parentdir) 
+```
+
+```python
+from cipher.caesar import *
+from cipher.affine import *
+from cipher.keyword_cipher import *
+from cipher.column_transposition import *
+
+from support.text_prettify import *
+from support.utilities import *
+from support.plot_frequency_histogram import *
+%matplotlib inline
+```
+
+```python
+challenge_number = 5
+plaintext_a_filename = f'{challenge_number}a.plaintext'
+plaintext_b_filename = f'{challenge_number}b.plaintext'
+ciphertext_a_filename = f'{challenge_number}a.ciphertext'
+ciphertext_b_filename = f'{challenge_number}b.ciphertext'
+```
+
+```python
+ca = open(ciphertext_a_filename).read()
+cb = open(ciphertext_b_filename).read()
+
+sca = sanitise(ca)
+pca = letters(ca)
+pta = depunctuate(ca)
+
+scb = sanitise(cb)
+pcb = letters(cb)
+ptb = depunctuate(cb)
+```
+
+```python
+fc = collections.Counter(sca)
+plot_frequency_histogram(fc, sort_key=fc.get)
+```
+
+```python
+kshifta, score = caesar_break(sca, fitness=Ptrigrams)
+kshifta
+```
+
+```python
+pa = caesar_decipher(sca, kshifta)
+print(pa)
+```
+
+```python
+(kworda, kwrapa), score = keyword_break_mp(sca, fitness=Ptrigrams)
+kworda, kwrapa
+```
+
+```python
+pa = keyword_decipher(sca, kworda, kwrapa)
+print(pa)
+```
+
+```python
+fpa = lcat(tpack(segment(pa)))
+print(fpa)
+```
+
+```python
+open(plaintext_a_filename, 'w').write(fpa)
+```
+
+```python
+fc = collections.Counter(scb)
+plot_frequency_histogram(fc, sort_key=fc.get)
+```
+
+```python
+rscb = cat(reversed(cb))
+rscb
+```
+
+```python
+(kwordb, fillb, emptyb), score = column_transposition_break_mp(scb, fitness=Ptrigrams)
+(kwordb, fillb, emptyb), score
+```
+
+```python
+pb = column_transposition_decipher(scb, kwordb, fillcolumnwise=fillb, emptycolumnwise=emptyb)
+pb
+```
+
+```python
+fpb = lcat(tpack(segment(pb)))
+print(fpb)
+```
+
+```python
+open(plaintext_b_filename, 'w').write(fpb)
+```
+
+```python
+transpositions[kwordb]
+```
+
+```python
+
+```
diff --git a/2020-early/5a.ciphertext b/2020-early/5a.ciphertext
new file mode 100644 (file)
index 0000000..c25e792
--- /dev/null
@@ -0,0 +1,2 @@
+TCCRVCOWV PTLYDRB TSSORZ BCWX
+LWVCTLCB OV CNR AZRVLN UOVOBCZJ WA TZUTURVCB BTJ JWD HOSS ER CZTFRSSOVM CW VWZHTJ BCWX UOBBOWV CW CZTVBXWZC VWZBQ NJGZW BCWLQ WA NRTFJ HTCRZ CW T BTAR SWLTCOWV BCWX NTZZJ TBQRG UR CW WAARZ JWD WDZ BDXXWZC BCWX EWBB OVCRSSOMRVLR ZRXWZCB BDMMRBC CNTC CNR MRZUTV UOSOCTZJ TZR LSWBRSJ UWVOCWZOVM TSS EWTCB TVG ASOMNCB OV TVG WDC WA VWZHTJ BCWX BDMMRBC BXSOCCOVM LTZMW BCWX LOFOSOTV ASOMNCB TSBW ZOBQJ BCWX ZTA NTFR WAARZRG T XSTVR BCWX HOSS LWVCTLC JWD FOT CNR RUETBBJ BCWX WCNRZ LWUUDVOLTCOWV LNTVVRSB OVBRLDZR BCWX GW VWC ZRXSJ CW CNOB CRSRMZTU URBBTMR RVGB
diff --git a/2020-early/5a.plaintext b/2020-early/5a.plaintext
new file mode 100644 (file)
index 0000000..1dd84cd
--- /dev/null
@@ -0,0 +1,6 @@
+attention jacques allier stop contacts in the french ministry of armaments say you will be
+travelling to norway stop mission to transport norsk hydro stock of heavy water to a safe locations
+top harry asked me to offer you our support stop boss intelligence reports suggest that the german
+military are closely monitoring all boats and flights in and out of norway stop suggest splitting
+cargo stop civilian flights also risky stop raf have offered a planes top will contact you via the
+embassy stop other communication channels insecure stop do not reply to this telegram message ends
\ No newline at end of file
diff --git a/2020-early/5b.ciphertext b/2020-early/5b.ciphertext
new file mode 100644 (file)
index 0000000..23f2dc6
--- /dev/null
@@ -0,0 +1 @@
+ynlsA assfi iosnl tgaia fcrft rmhfo nFece riMns hifro Atyem mnrao shwts Jhtat asqeA curle aliee brmme fhDot euime xeBra euiws nuaeo vdvlm noeis ghnit itpra moate rnWea gdrnv oaeth oiflh mdoea lwwde anheo srsbo etpvd arhsu cvtae erudc mlofn soetw Nraro vPeiy ryulA osrle hlird okawt dthea qBnue aadPr eesse Piday Bsase nrcad srsho dawht otohs rtisa iagnh ineto sdotl mrfos oNrHd okyrs aeshh atast npitt oiedn lahtt egoou psspn totii eahwh tbude oltii ivseg hhnte dolyr icrce ttlni pakRu anjnA etnge wrcse eagdh rfiho wtilw nloah mngio rprde oignt noimv hstmn seeeh liWiw Nrano uhpry eehsd caepc fsaar croaa ofrgo oudno ndhnr euldi oeksr mogai algnf otrmh fktch Soolt Aomrs edmtg moeat whrit eahps taeeg rsnei kttce upcSs tight nwtea ahnta ssrio tnprv Hayge raefW thote rmtln tpafe uthLe afwwf ssaka ttdih ewrne citnp igetl hfite nhadg treie rdgtn tciae lnhpa tHmeo Ougub rnaet rgrba dsotd thein radee cerhs abdtu eirte ethoa nswsf gotin reagh cAadl onsir nleam wsaei isnms mfotg rneai hmFet ufsrt eerhr qiinu Ssnte iochl okwso emhtt ahdhm hdiea tsdhs egfih elwbt etudo lfcuo nntid oaefr cniit hmtei yhcgu aeOrt tatns reifh arede ileot dprah tntal ApaRF deaan hervd rienl fadua ontrs teadh meiem teshp atnse gasrr iceab aturf enrct oersx odhss oitti ghwnp proeu tefhs ostii avsIi pttbs ilost taAeh rleul iteit sdvla eoeao wyNre uwdbt kntno oawht owoag icrha yefnw okito mhiOt hergn uaRsn jtibk nruan kitoe Nteoo hysHd rkmod irari tansa innto nfudd oorcr aewso idhag htntl hpate dtahn hslat edfco aokdo norun eudnh neadr dtihy eggio rklfm oDasr ueiet tmutu beewr hybua lenat gieoe acsnc httes oatrg sotui sendn reioe tdtro nriee muomc hwrws ehado ebmvi Aleyl niayr f
diff --git a/2020-early/5b.plaintext b/2020-early/5b.plaintext
new file mode 100644 (file)
index 0000000..b072f6a
--- /dev/null
@@ -0,0 +1,18 @@
+analysis of signals traffic from the french ministry of armaments show that jacques allier a member
+of the deuxieme bureau was involved in something important we arranged to have him followed and he
+was observed to purchase travel documents for norway previously allier had worked at the banque de
+paris des pays bas and records show that this organisation held most of norsk hydros shares at that
+point leading to the supposition that he would be visiting the hydroelectric plant in rj uk an
+agents were charged with following him and reporting on his movements while in norway he purchased
+space for a cargo of around one hundred kilograms on a flight from stockholm to amsterdam together
+with a passenger ticket suspecting that he was transporting heavy water from the plant the luftwaffe
+was tasked with intercepting the flight and redirecting the plane to hamburg our agents board edit
+there and search edit but there was no sign of the cargo and all iers name was missing from the
+manifest further enquiries in stockholm showed that he had missed the flight but we could find not
+race of him in the city our agents at the airfield reported that an raf plane had arrived and left
+around the same time as the passenger aircraft but no records exist showing the purpose of that
+visit it is possible that allier used it to leave norway but we do not know what cargo if any he
+took with him our agents in rj uk an broke into the norsk hydro administration and found a record
+showing that the plant had held a stock of around one hundred and eighty kilograms of deuterium but
+they were unable to gain access to the storage units in order to determine how much was removed by
+allier if any
\ No newline at end of file