Done challenge 6
authorNeil Smith <neil.git@njae.me.uk>
Thu, 7 May 2020 13:20:08 +0000 (14:20 +0100)
committerNeil Smith <neil.git@njae.me.uk>
Thu, 7 May 2020 13:20:08 +0000 (14:20 +0100)
2020-early/2020-a-challenge6.ipynb [new file with mode: 0644]
2020-early/2020-a-challenge6.md [new file with mode: 0644]
2020-early/6a.ciphertext [new file with mode: 0644]
2020-early/6a.plaintext [new file with mode: 0644]
2020-early/6b.ciphertext [new file with mode: 0644]
2020-early/6b.plaintext [new file with mode: 0644]

diff --git a/2020-early/2020-a-challenge6.ipynb b/2020-early/2020-a-challenge6.ipynb
new file mode 100644 (file)
index 0000000..1ebc696
--- /dev/null
@@ -0,0 +1,435 @@
+{
+ "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": 2,
+   "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 = 6\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": 6,
+   "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": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('norway', <KeywordWrapAlphabet.from_last: 2>)"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(kworda, kwrapa), score = keyword_break_mp(sca, fitness=Ptrigrams)\n",
+    "kworda, kwrapa"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "harryiguessyouhaveheardbynowabouttheinvasionithascomeasnoshocktoanyonethebritishhadbeenopenlydiscussingacountermanoeuvreandthatisnowasignificantpartofthenazipropagandatheofficiallineisthewehrmachtaretheretoprotectthecountrysneutralityagainstfrancobritishaggressiontheattachedinvasionorderswereinterceptedbybossagentsinthecapitalwhohaveestablishedaheadquartersnexttothetelephoneexchangeasfaraswecantelltheirtapintothesecuretelegraphicsystemhasnotyetbeendetectedbutwewillneedtolookoutforfakeintelligenceincasethatchangesunsurprisinglytheordersusethemostsecurecipherwehaveseenyetacolumnartranspositionluckilyihadsomeideawhattolookforsincenorskhydrowasanimportanttargetforthereichserziehungsministeriumandthatgavemeabigcluethemessagemakesmeverygladthatmonsieurallierwasabletoevacuatetheheavywaternowthatthesshavetakencontrolofrjukanitisonlyamatteroftimeuntiltheybuilduptheirownstocksbutthatwilltakeawhileandwecanusethatperiodtoworkoutwhattodonextwewillberelyingheavilyonyournetworkinthecountrytofeeduswithintelligenceonthefactorywhichiswhyiaskedourcommunicationsteamtosetupthismoresecurechannelifwecanbreakthetelegraphsystemweshouldassumethatthenaziscantooiwouldlikeustomovetousingvigenereciphersforourfuturemessagesstaysafephil\n"
+     ]
+    }
+   ],
+   "source": [
+    "pa = cat(reversed(keyword_decipher(sca, kworda, kwrapa)))\n",
+    "print(pa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "harry i guess you have heard by now about the invasion it has come as no shock to anyone the british\n",
+      "had been openly discussing a counter manoeuvre and that is now a significant part of the nazi\n",
+      "propaganda the official line is the wehrmacht are there to protect the country s neutrality against\n",
+      "franco british aggression the attached invasion orders were intercepted by boss agents in the\n",
+      "capital who have established a headquarters next to the telephone exchange as far as we can tell\n",
+      "their tap into the secure telegraphic system has not yet been detected but we will need to lookout\n",
+      "for fake intelligence in case that changes unsurprisingly the orders use the most secure cipher we\n",
+      "have seen yet a columnar transposition luckily i had some idea what to look for since norsk hydro\n",
+      "was an important target for the reichs erziehung s ministerium and that gave me a big clue the\n",
+      "message makes me very glad that monsieur allier was able to evacuate the heavy water now that the ss\n",
+      "have taken control of rj uk an it is only a matter of time until they buildup their own stocks but\n",
+      "that will take a while and we can use that period to workout what to do next we will be relying\n",
+      "heavily on your network in the country to feed us with intelligence on the factory which is why i\n",
+      "asked our communications team to setup this more secure channel if we can break the telegraph system\n",
+      "we should assume that the nazis can too i would like us to move to using vi genere ciphers for our\n",
+      "future messages stay safe phil\n"
+     ]
+    }
+   ],
+   "source": [
+    "fpa = lcat(tpack(segment(pa)))\n",
+    "print(fpa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1501"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_a_filename, 'w').write(fpa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "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(scb)\n",
+    "plot_frequency_histogram(fc, sort_key=fc.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'\\nTRSXS EYHHN LASOR ILHRN NZCHT LYRON AEHSN UIPCN EOLDO ADPNC TRHRS ATORS ONAWT EETDD RYTNO DBEIF INCTR MIEOT ASSGR TRDPE SVBHL OAHEE ACMCE OMLTE RLEFY AYOFS OTAEN REAEO ENBAS OTEVA ENRNN UVJIE NTARL EEMID ATTOD ITRUE UDRRI FRAEB FHDHH UWUSS ESRCC UESEE NVAIE SATSI ACOSA AOENI AWTED OEIHN RELEU IENUR NICNR YEYCT ITDTS TELRY FOAOF WNAAC YSUNE HAVTL STRAU SBDRT TATTT RSHOS KEHHU DLDRE OESOC SIDHE HEEHT SCLNE ENEAE BANVT INSRL PJASH HIEIH TTTUI TRRUN LWEIU RITNI TAHUL BFSAC TENER LONRE IOILH HTUTS ASDRL OTSES REREE LRARN ARLEH OOCPE DBHAE KDRUN EEDRD RDSPP ETLWE NUYDN TEABA IHFRF HNOSP OYRAO PTCTD AMEIF ENENV UEERF IBTHO IMOAG DOSYF NXFRC KPHOE ETMOO EDLFN RTSFO IIGIH EALOR UDCEA TDRSL ETSCI TLPER UOWME ISNIP OKFTK IHCAH OGAUA DUELF TANWA EOONH UEVOT UHYTU LDEEE OAWTE ADLES IRTUL ETEIF ASCDR TISAR TWJEL EPRDL STRAL ECBGU WENEE AICTN HMNDM OINHY REASO RSGTC YNTIU REWSE EFRIM TMHEE TOWSE RDPEF TDENH ODLEP ATRVT TLCEY CINRT YOOCL SRSAC AMDNE DGURP IHTIL ETHLD SWHCR UOEDC NUEUL TRERE OOBAC NNTUW EOYCT AOOKE NEETE EKTSA ODRDE BEKTA IEABS MEOTO ITLTR JRYNC IRNII SOEEN'"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "rscb = cat(reversed(cb))\n",
+    "rscb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(((3, 1, 4, 2, 0), False, True), -3026.420927215971)"
+      ]
+     },
+     "execution_count": 15,
+     "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": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'uranprojektspecialordersforsixtyninthinfantrydivisioncommandedbygeneralmajorhermanntitteloncetheinitialobjectivesofunternehmenweseruebunghavebeenachievedanelitetaskforceistobeassembledandorderedtoproceedatallspeedtorjukanwheretheyaretotakepossessionofthenorskhydrofactorystaffatthefacilityaretobetreatedwellbutmustnotunderanycircumstancesbeallowedtoleavetheareathepowerplantshouldbesurveyedsecuredandplacedundertwentyfourhourguardstocksofheavywatershouldbeheldinthemostprotectedlocationwithinthefacilitypreferablyundergroundandcertainlyunderarmedguardoncetheareaissecurethesswilltakecontrolofnorskhydroitsoperationsanditssecuritythewehrmachtwillcontinuetoprovideareapatrolsandtopolicelocalresidentsoncetheplantissecuredanditsstaffhavebeenplacedunderhousearrestyouwillcontactthereichserziehungsministeriumwhowillfurnishfurtherordersnhstaffwillbeundertheauthorityoftheministryexercisedthroughthess'"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pb = column_transposition_decipher(scb, kwordb, fillcolumnwise=fillb, emptycolumnwise=emptyb)\n",
+    "pb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "uran projekt special orders for sixty ninth infantry division commanded by general major hermann\n",
+      "tittel once the initial objectives of unternehmen we serue bung have been achieved an elite\n",
+      "taskforce is to be assembled and ordered to proceed at all speed to rj uk an where they are to take\n",
+      "possession of the norsk hydro factory staff at the facility are to be treated well but must not\n",
+      "under any circumstances be allowed to leave the area the powerplant should be surveyed secured and\n",
+      "placed under twenty four hour guard stocks of heavy water should beheld in the most protected\n",
+      "location within the facility preferably underground and certainly under armed guard once the area is\n",
+      "secure the ss will take control of norsk hydro its operations and its security the wehrmacht will\n",
+      "continue to provide area patrols and to police local residents once the plant is secured and its\n",
+      "staff have been placed under house arrest you will contact the reichs erziehung s ministerium who\n",
+      "will furnish further orders nh staff will be under the authority of the ministry exercised through\n",
+      "the ss\n"
+     ]
+    }
+   ],
+   "source": [
+    "fpb = lcat(tpack(segment(pb)))\n",
+    "print(fpb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1077"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_b_filename, 'w').write(fpb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['penal',\n",
+       " 'reich',\n",
+       " 'renal',\n",
+       " 'ripen',\n",
+       " 'scram',\n",
+       " 'scrap',\n",
+       " 'sepal',\n",
+       " 'shoal',\n",
+       " 'shock',\n",
+       " 'shrek',\n",
+       " 'siren',\n",
+       " 'sloan',\n",
+       " 'venal',\n",
+       " 'verdi',\n",
+       " 'vetch',\n",
+       " 'viral',\n",
+       " 'vireo',\n",
+       " 'virgo',\n",
+       " 'vital',\n",
+       " 'voter',\n",
+       " 'votes',\n",
+       " 'welch',\n",
+       " 'wench',\n",
+       " 'wendi',\n",
+       " 'wesak',\n",
+       " 'wiser',\n",
+       " 'wives',\n",
+       " 'yowls',\n",
+       " 'remake',\n",
+       " 'remark',\n",
+       " 'rename',\n",
+       " 'repair',\n",
+       " 'repeal',\n",
+       " 'scrams',\n",
+       " 'scraps',\n",
+       " 'sepals',\n",
+       " 'serape',\n",
+       " 'shoals',\n",
+       " 'shocks',\n",
+       " 'shreks',\n",
+       " 'sirens',\n",
+       " 'tercel',\n",
+       " 'terran',\n",
+       " 'thrall',\n",
+       " 'tirana',\n",
+       " 'tishri',\n",
+       " 'unsnap',\n",
+       " 'virgil',\n",
+       " 'virgin',\n",
+       " 'wesaks',\n",
+       " 'within',\n",
+       " 'seepage',\n",
+       " 'serapes',\n",
+       " 'teenage',\n",
+       " 'tishris',\n",
+       " 'unsnaps',\n",
+       " 'wendell',\n",
+       " 'wittier',\n",
+       " 'remedied',\n",
+       " 'repairer',\n",
+       " 'repealer',\n",
+       " 'ringling',\n",
+       " 'riparian',\n",
+       " 'seepages',\n",
+       " 'selassie',\n",
+       " 'singling',\n",
+       " 'teetotal',\n",
+       " 'terraria',\n",
+       " 'tingling',\n",
+       " 'wittiest',\n",
+       " 'selassies']"
+      ]
+     },
+     "execution_count": 19,
+     "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-challenge6.md b/2020-early/2020-a-challenge6.md
new file mode 100644 (file)
index 0000000..61f8e69
--- /dev/null
@@ -0,0 +1,115 @@
+---
+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 = 6
+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
+(kworda, kwrapa), score = keyword_break_mp(sca, fitness=Ptrigrams)
+kworda, kwrapa
+```
+
+```python
+pa = cat(reversed(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/6a.ciphertext b/2020-early/6a.ciphertext
new file mode 100644 (file)
index 0000000..42bd909
--- /dev/null
@@ -0,0 +1 @@
+FCBJA YNMVN PMMAZ NMMAG ALQPQ YLQIL IYMLA BJCRA LAHAZ CSZHC MQIPA SIGIP MQAEC FWFQI TCIIP HNRMC XNHAB PPNBP AGQMM NWFQI BMATG APMVM BJNLZ AFAPA BPENA LOHNR ATYCF AHHNB RALQR AMALI GMCBP JQPAM IPGNA PMHIC PNRCH QGGIR LQIWA EMNCV BTMCB RCBTV LIPRN YABPH IARHA ZCFFA PHCBP CTMQW AAYIP VLPHQ IRABP HCELI TPAHL QIVHI VFCSN ABZHC VFALA OFFCT ATPUA HIWIP PNBTP QIELI TIPWI CLAJP NBPAM QHNRA TWHNA FCBTN AENPF FCTPN BPPQO MERIP MHTIL CABPJ QWFCQ OVABP FCPHQ AGCPY ILAPP NGNVF HIMCP CHNEQ DLYIF ILPHI RHAEN PASNB MMABP PNBPT IHLAP NTVSN ABABP APNQR NSAIP AFONM NTLAC FFNLQ ACMHI GPNBP WNFZV LASAG MAENG AZNMM AGABP AQFRZ CONAG ASNZP NBPWH NGQCL APMCH CGMZH QBACX LAMBR CALAB PLIYP AZLNP PHNPL IJGCH NMNTI LWVBE MLIHA RHCML IYEII FIPPN BTNAW CAGIM WNBCV FCERQ FHICP CMIJM HNLPL NHGQF IRNPA VHAAM ASNBA TLABJ CRALQ RAMPM IGABP AMQML AWLIA BPVFZ HCMCL JLQMH QMAZH NBRPN BPAMN RHCAR HAZCF FAPHC AENYL IYPQI EIIFI PWAAH FFCTA TPQOW APRAP AWHAA OPAVP IHMNB GAPMV MRCBJ NLZAF APALQ RAMAB PIPHC JNPLC ABPFF APHNR ATMNL NYMNA ZHNBR UAAHI BJAFA PABPI PPUAH MLAPL NQKWN ABNWA BMCFO NPMAA SNBIB TFNPC JNRAB PHCMP HAZNM MIOVO WAPJA RLAPH CALAT MLAWL IHICM NSHCW ABRNP PNABP HICMM ALZZN BMCPC LOIRH NLYPM HCNZN VPCFN LPQAH MVLPH QIRAB PPRAP ILJIP ALABP ALNPB RNGLB ATABP MCAHC FFNCR CYYIA BPNWH NZNJI LJCXN HABPY IPLNJ PHNRC YCHZC MNTIH MCPNB PWHNA LSQAI HNGLA PHQIR NZHCM MQRMC WVFHA JIHAA OWNBB MCPCL OABPA HIVHN IPERI BMIHM NAGIR MNBPC HICMN SHCAB PPQIO NTIHV OWLNA BASNB QIVMM AQZCV LLNB
diff --git a/2020-early/6a.plaintext b/2020-early/6a.plaintext
new file mode 100644 (file)
index 0000000..c832226
--- /dev/null
@@ -0,0 +1,16 @@
+harry i guess you have heard by now about the invasion it has come as no shock to anyone the british
+had been openly discussing a counter manoeuvre and that is now a significant part of the nazi
+propaganda the official line is the wehrmacht are there to protect the country s neutrality against
+franco british aggression the attached invasion orders were intercepted by boss agents in the
+capital who have established a headquarters next to the telephone exchange as far as we can tell
+their tap into the secure telegraphic system has not yet been detected but we will need to lookout
+for fake intelligence in case that changes unsurprisingly the orders use the most secure cipher we
+have seen yet a columnar transposition luckily i had some idea what to look for since norsk hydro
+was an important target for the reichs erziehung s ministerium and that gave me a big clue the
+message makes me very glad that monsieur allier was able to evacuate the heavy water now that the ss
+have taken control of rj uk an it is only a matter of time until they buildup their own stocks but
+that will take a while and we can use that period to workout what to do next we will be relying
+heavily on your network in the country to feed us with intelligence on the factory which is why i
+asked our communications team to setup this more secure channel if we can break the telegraph system
+we should assume that the nazis can too i would like us to move to using vi genere ciphers for our
+future messages stay safe phil
\ No newline at end of file
diff --git a/2020-early/6b.ciphertext b/2020-early/6b.ciphertext
new file mode 100644 (file)
index 0000000..68023bf
--- /dev/null
@@ -0,0 +1 @@
+NEEOS IINRI CNYRJ RTLTI OTOEM SBAEI ATKEB EDRDO ASTKE ETEEN EKOOA TCYOE WUTNN CABOO ERERT LUEUN CDEOU RCHWS DLHTE LITHI PRUGD ENDMA CASRS LCOOY TRNIC YECLT TVRTA PELDO HNEDT FEPDR ESWOT EEHMT MIRFE ESWER UITNY CTGSR OSAER YHNIO MDNMH NTCIA EENEW UGBCE LARTS LDRPE LEJWT RASIT RDCSA FIETE LUTRI SELDA ETWAO EEEDL UTYHU TOVEU HNOOE AWNAT FLEUD AUAGO HACHI KTFKO PINSI EMWOU REPLT ICSTE LSRDT AECDU ROLAE HIGII OFSTR NFLDE OOMTE EOHPK CRFXN FYSOD GAOMI OHTBI FREEU VNENE FIEMA DTCTP OARYO PSONH FRFHI ABAET NDYUN EWLTE PPSDR DRDEE NURDK EAHBD EPCOO HELRA NRARL EERER SESTO LRDSA STUTH HLIOI ERNOL RENET CASFB LUHAT INTIR UIEWL NURRT IUTTT HIEIH HSAJP LRSNI TVNAB EAENE ENLCS THEEH EHDIS COSEO ERDLD UHHEK SOHSR TTTAT TRDBS UARTS LTVAH ENUSY CAANW FOAOF YRLET STDTI TCYEY RNCIN RUNEI UELER NHIEO DETWA INEOA ASOCA ISTAS EIAVN EESEU CCRSE SSUWU HHDHF BEARF IRRDU EURTI DOTTA DIMEE LRATN EIJVU NNRNE AVETO SABNE OEAER NEATO SFOYA YFELR ETLMO ECMCA EEHAO LHBVS EPDRT RGSSA TOEIM RTCNI FIEBD ONTYR DDTEE TWANO SROTA SRHRT CNPDA ODLOE NCPIU NSHEA NORYL THCZN NRHLI ROSAL NHHYE SXSRT
diff --git a/2020-early/6b.plaintext b/2020-early/6b.plaintext
new file mode 100644 (file)
index 0000000..db562df
--- /dev/null
@@ -0,0 +1,12 @@
+uran projekt special orders for sixty ninth infantry division commanded by general major hermann
+tittel once the initial objectives of unternehmen we serue bung have been achieved an elite
+taskforce is to be assembled and ordered to proceed at all speed to rj uk an where they are to take
+possession of the norsk hydro factory staff at the facility are to be treated well but must not
+under any circumstances be allowed to leave the area the powerplant should be surveyed secured and
+placed under twenty four hour guard stocks of heavy water should beheld in the most protected
+location within the facility preferably underground and certainly under armed guard once the area is
+secure the ss will take control of norsk hydro its operations and its security the wehrmacht will
+continue to provide area patrols and to police local residents once the plant is secured and its
+staff have been placed under house arrest you will contact the reichs erziehung s ministerium who
+will furnish further orders nh staff will be under the authority of the ministry exercised through
+the ss
\ No newline at end of file