Done challenge 4
authorNeil Smith <neil.git@njae.me.uk>
Thu, 23 Apr 2020 08:22:09 +0000 (09:22 +0100)
committerNeil Smith <neil.git@njae.me.uk>
Thu, 23 Apr 2020 08:25:03 +0000 (09:25 +0100)
12 files changed:
2020-early/2020-a-challenge1.ipynb
2020-early/2020-a-challenge1.md [new file with mode: 0644]
2020-early/2020-a-challenge2.ipynb
2020-early/2020-a-challenge2.md [new file with mode: 0644]
2020-early/2020-a-challenge3.ipynb
2020-early/2020-a-challenge3.md [new file with mode: 0644]
2020-early/2020-a-challenge4.ipynb [new file with mode: 0644]
2020-early/2020-a-challenge4.md [new file with mode: 0644]
2020-early/4a.ciphertext [new file with mode: 0644]
2020-early/4a.plaintext [new file with mode: 0644]
2020-early/4b.ciphertext [new file with mode: 0644]
2020-early/4b.plaintext [new file with mode: 0644]

index 4834440a78056333efcddf201119050943e4bc70..e12b2dd76807cc0dc8589491e43e189b2eac60e9 100644 (file)
   }
  ],
  "metadata": {
+  "jupytext": {
+   "formats": "ipynb,md"
+  },
   "kernelspec": {
    "display_name": "Python 3",
    "language": "python",
diff --git a/2020-early/2020-a-challenge1.md b/2020-early/2020-a-challenge1.md
new file mode 100644 (file)
index 0000000..c2a0301
--- /dev/null
@@ -0,0 +1,66 @@
+---
+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 *
+```
+
+```python
+challenge_number = 1
+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()
+
+```
+
+```python
+k_a, score_a = caesar_break(ca)
+print(k_a, '\n')
+pa = caesar_decipher(ca, k_a)
+print(pa)
+```
+
+```python
+open(plaintext_a_filename, 'w').write(pa)
+```
+
+```python
+k_b, score_b = caesar_break(cb)
+print(k_b, '\n')
+pb = caesar_decipher(cb, k_b)
+print(pb)
+```
+
+```python
+open(plaintext_b_filename, 'w').write(pb)
+```
+
+```python
+
+```
index 385076c077cab67dc0ef8ff35aab2685970dcecb..93a980b60004ab82f0330a24a37b604b590e273e 100644 (file)
   }
  ],
  "metadata": {
+  "jupytext": {
+   "formats": "ipynb,md"
+  },
   "kernelspec": {
    "display_name": "Python 3",
    "language": "python",
diff --git a/2020-early/2020-a-challenge2.md b/2020-early/2020-a-challenge2.md
new file mode 100644 (file)
index 0000000..b20f25e
--- /dev/null
@@ -0,0 +1,77 @@
+---
+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 support.text_prettify import *
+from support.utilities import *
+from support.plot_frequency_histogram import *
+```
+
+```python
+challenge_number = 2
+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
+(ma, ca, za), score_a = affine_break(sca)
+print((ma, ca, za), '\n')
+pa = repunctuate(affine_decipher(sca, ma, ca, za), pta)
+print(pa)
+```
+
+```python
+open(plaintext_a_filename, 'w').write(pa)
+```
+
+```python
+(mb, cb, zb), score_a = affine_break(scb)
+print((mb, cb, zb), '\n')
+pb = repunctuate(affine_decipher(scb, mb, cb, zb), ptb)
+print(pb)
+```
+
+```python
+open(plaintext_b_filename, 'w').write(pb)
+```
+
+```python
+
+```
index 0c65ac36a049e88c560fc56e2494c6eb1a76cd2d..51f0764296d4671931e023b05fae76f9e3be53e2 100644 (file)
   }
  ],
  "metadata": {
+  "jupytext": {
+   "formats": "ipynb,md"
+  },
   "kernelspec": {
    "display_name": "Python 3",
    "language": "python",
diff --git a/2020-early/2020-a-challenge3.md b/2020-early/2020-a-challenge3.md
new file mode 100644 (file)
index 0000000..46a1a98
--- /dev/null
@@ -0,0 +1,84 @@
+---
+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 support.text_prettify import *
+from support.utilities import *
+from support.plot_frequency_histogram import *
+```
+
+```python
+challenge_number = 3
+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
+(kworda, kwrapa), score = keyword_break_mp(sca, fitness=Ptrigrams)
+kworda, kwrapa
+```
+
+```python
+pa = keyword_decipher(ca, kworda, kwrapa)
+print(pa)
+```
+
+```python
+open(plaintext_a_filename, 'w').write(pa)
+```
+
+```python
+(kwordb, kwrapb), score = keyword_break_mp(scb, fitness=Ptrigrams)
+kwordb, kwrapb
+```
+
+```python
+pb = keyword_decipher(cb, kwordb, kwrapb)
+print(pb)
+```
+
+```python
+open(plaintext_b_filename, 'w').write(pb)
+```
+
+```python
+
+```
diff --git a/2020-early/2020-a-challenge4.ipynb b/2020-early/2020-a-challenge4.ipynb
new file mode 100644 (file)
index 0000000..aa14210
--- /dev/null
@@ -0,0 +1,337 @@
+{
+ "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": 17,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from cipher.caesar import *\n",
+    "from cipher.affine import *\n",
+    "from cipher.keyword_cipher 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 = 4\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": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "12"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kshifta, score = caesar_break(sca, fitness=Ptrigrams)\n",
+    "kshifta"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "philmyvisittomeitnersgroupwasveryinterestingandpaidoffinanunexpectedwayasyoususpectednuclearenergyhasseriouspotentialandthereareanumberofgroupsworkingtorealisethatoneofmeitnerscollaboratorshasbeenincontactwithagroupofdissidentgermanscientistsclosetoeinsteinandtheyhavebeenpassingintelligenceconcerningthenazinuclearprogrammetotheswedishteamwhileiwasthereoneoftheircontactsinberlinsmuggledoutacopyofalettersentbythescientistsjoosandhanletowilhelmdamesatthereichserziehungsministeriumitoutlinesthepotentialmilitaryapplicationsofnuclearenergyandapparentlytheministerwassoimpressedbyitscontentsthatwithinaweekhehadconvenedatoplevelgrouptodeveloptheideaswithinitthebossteaminberlinhaverampedupmonitoringofcommunicationstoandfromtheministryandthemostpromisingleadistheattachedmemotheenvelopewasmarkeddiealchemisteniamnotsurehowfreeyouaretotravelbutihavetomeetupwithmynewnorwegianfriendsandthenheadbacktoenglandcouldyoumoveyourbasetofranceandmakecontactwithsomeofouralliesithinkweshouldopendiscussionswiththefrenchministerofarmamentswearegoingtoneedhishelpharry\n"
+     ]
+    }
+   ],
+   "source": [
+    "pa = caesar_decipher(sca, kshifta)\n",
+    "print(pa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "phil my visit to meitner s group was very interesting and paid off in an unexpected way as you\n",
+      "suspected nuclear energy has serious potential and there area number of groups working to realise\n",
+      "that one of meitner s collaborators has been in contact with a group of dissident german scientists\n",
+      "close to einstein and they have been passing intelligence concerning the nazi nuclear programme to\n",
+      "the swedish team while i was there one of their contacts in berlin smuggled out a copy of a letter\n",
+      "sent by the scientists joos and hanle to wilhelm dames at the reichs erziehung s ministerium it\n",
+      "outlines the potential military applications of nuclear energy and apparently the minister was so\n",
+      "impressed by its contents that within a week he had convened a toplevel group to develop the ideas\n",
+      "within it the boss team in berlin have ramped up monitoring of communications to and from the\n",
+      "ministry and the most promising lead is the attached memo the envelope was marked die alchemist en i\n",
+      "am not sure how free you are to travel but i have to meetup with my new norwegian friends and then\n",
+      "head back to england could you move your base to france and make contact with some of our allies i\n",
+      "think we should open discussions with the french minister of armaments we are going to need his help\n",
+      "harry\n"
+     ]
+    }
+   ],
+   "source": [
+    "fpa = lcat(tpack(segment(pa)))\n",
+    "print(fpa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1283"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_a_filename, 'w').write(fpa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "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": [
+       "('yerkes', <KeywordWrapAlphabet.from_last: 2>)"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(kwordb, kwrapb), score = keyword_break_mp(scb, fitness=Ptrigrams)\n",
+    "kwordb, kwrapb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'heavywtrsqxzbcdfgijklmnopu'"
+      ]
+     },
+     "execution_count": 19,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kwordb, score = simulated_annealing_break(scb, fitness=Ptrigrams)\n",
+    "kwordb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "first meeting of die alchemisten committee, reichserjiehungsministerium, twenty ninth april nineteen thirty nine\n",
+      "the committee was reconvened by the minister at the request of the chancellor himself.\n",
+      "it is tasked with realising the military and industrial promise of nuclear energy.\n",
+      "the committee recognises the technical challenges involved in industrialising the processes hitherto conducted under laboratory conditions, but feels that the obstacles can be overcome by a combination of scientific and engineering excellence already possessed by the state.\n",
+      "the committee identified that the principle issue is that of controlling the nuclear reaction which is mediated by the energy of free neutrons. these need to be slowed to effectively harness their power, and to this end the committee recommends the acquisition of a suitable moderator.\n",
+      "the best-known candidate is deuterium and the best source of this material is the power plant at vemork in norway. the tronstad and brun electrolytic process at that facility is producing over twenty kilograms of heavy water per year, and this could easily be scaled up.\n",
+      "since we do not want to alert our enemies to the importance of the material the committee recommends placing an initial order for five litres of heavy water through our own dye industry syndicate corporation which, by happy accident, owns a quarter of the shares in the vemork plant.\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(keyword_decipher(cb, kwordb))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "first meeting of die alchemisten committee, reichserziehungsministerium, twenty ninth april nineteen thirty nine\n",
+      "the committee was reconvened by the minister at the request of the chancellor himself.\n",
+      "it is tasked with realising the military and industrial promise of nuclear energy.\n",
+      "the committee recognises the technical challenges involved in industrialising the processes hitherto conducted under laboratory conditions, but feels that the obstacles can be overcome by a combination of scientific and engineering excellence already possessed by the state.\n",
+      "the committee identified that the principle issue is that of controlling the nuclear reaction which is mediated by the energy of free neutrons. these need to be slowed to effectively harness their power, and to this end the committee recommends the acquisition of a suitable moderator.\n",
+      "the best-known candidate is deuterium and the best source of this material is the power plant at vemork in norway. the tronstad and brun electrolytic process at that facility is producing over twenty kilograms of heavy water per year, and this could easily be scaled up.\n",
+      "since we do not want to alert our enemies to the importance of the material the committee recommends placing an initial order for five litres of heavy water through our own dye industry syndicate corporation which, by happy accident, owns a quarter of the shares in the vemork plant.\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "pb = keyword_decipher(cb, 'heavywater', KeywordWrapAlphabet.from_last)\n",
+    "print(pb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1399"
+      ]
+     },
+     "execution_count": 21,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_b_filename, 'w').write(pb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "heavywtrsuxzbcdfgijklmnopq\n",
+      "heavywtrsqxzbcdfgijklmnopu\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(keyword_cipher_alphabet_of('heavywater', KeywordWrapAlphabet.from_last))\n",
+    "print(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-challenge4.md b/2020-early/2020-a-challenge4.md
new file mode 100644 (file)
index 0000000..8160cef
--- /dev/null
@@ -0,0 +1,109 @@
+---
+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 support.text_prettify import *
+from support.utilities import *
+from support.plot_frequency_histogram import *
+%matplotlib inline
+```
+
+```python
+challenge_number = 4
+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
+kshifta, score = caesar_break(sca, fitness=Ptrigrams)
+kshifta
+```
+
+```python
+pa = caesar_decipher(sca, kshifta)
+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
+(kwordb, kwrapb), score = keyword_break_mp(scb, fitness=Ptrigrams)
+kwordb, kwrapb
+```
+
+```python
+kwordb, score = simulated_annealing_break(scb, fitness=Ptrigrams)
+kwordb
+```
+
+```python
+print(keyword_decipher(cb, kwordb))
+```
+
+```python
+pb = keyword_decipher(cb, 'heavywater', KeywordWrapAlphabet.from_last)
+print(pb)
+```
+
+```python
+open(plaintext_b_filename, 'w').write(pb)
+```
+
+```python
+print(keyword_cipher_alphabet_of('heavywater', KeywordWrapAlphabet.from_last))
+print(kwordb)
+```
+
+```python
+
+```
diff --git a/2020-early/4a.ciphertext b/2020-early/4a.ciphertext
new file mode 100644 (file)
index 0000000..5f541f4
--- /dev/null
@@ -0,0 +1 @@
+BTUXY KHUEU FFAYQ UFZQD ESDAG BIMEH QDKUZ FQDQE FUZSM ZPBMU PARRU ZMZGZ QJBQO FQPIM KMEKA GEGEB QOFQP ZGOXQ MDQZQ DSKTM EEQDU AGEBA FQZFU MXMZP FTQDQ MDQMZ GYNQD ARSDA GBEIA DWUZS FADQM XUEQF TMFAZ QARYQ UFZQD EOAXX MNADM FADET MENQQ ZUZOA ZFMOF IUFTM SDAGB ARPUE EUPQZ FSQDY MZEOU QZFUE FEOXA EQFAQ UZEFQ UZMZP FTQKT MHQNQ QZBME EUZSU ZFQXX USQZO QOAZO QDZUZ SFTQZ MLUZG OXQMD BDASD MYYQF AFTQE IQPUE TFQMY ITUXQ UIMEF TQDQA ZQARF TQUDO AZFMO FEUZN QDXUZ EYGSS XQPAG FMOAB KARMX QFFQD EQZFN KFTQE OUQZF UEFEV AAEMZ PTMZX QFAIU XTQXY PMYQE MFFTQ DQUOT EQDLU QTGZS EYUZU EFQDU GYUFA GFXUZ QEFTQ BAFQZ FUMXY UXUFM DKMBB XUOMF UAZEA RZGOX QMDQZ QDSKM ZPMBB MDQZF XKFTQ YUZUE FQDIM EEAUY BDQEE QPNKU FEOAZ FQZFE FTMFI UFTUZ MIQQW TQTMP OAZHQ ZQPMF ABXQH QXSDA GBFAP QHQXA BFTQU PQMEI UFTUZ UFFTQ NAEEF QMYUZ NQDXU ZTMHQ DMYBQ PGBYA ZUFAD UZSAR OAYYG ZUOMF UAZEF AMZPR DAYFT QYUZU EFDKM ZPFTQ YAEFB DAYUE UZSXQ MPUEF TQMFF MOTQP YQYAF TQQZH QXABQ IMEYM DWQPP UQMXO TQYUE FQZUM YZAFE GDQTA IRDQQ KAGMD QFAFD MHQXN GFUTM HQFAY QQFGB IUFTY KZQIZ ADIQS UMZRD UQZPE MZPFT QZTQM PNMOW FAQZS XMZPO AGXPK AGYAH QKAGD NMEQF ARDMZ OQMZP YMWQO AZFMO FIUFT EAYQA RAGDM XXUQE UFTUZ WIQET AGXPA BQZPU EOGEE UAZEI UFTFT QRDQZ OTYUZ UEFQD ARMDY MYQZF EIQMD QSAUZ SFAZQ QPTUE TQXBT MDDK
diff --git a/2020-early/4a.plaintext b/2020-early/4a.plaintext
new file mode 100644 (file)
index 0000000..1c7a737
--- /dev/null
@@ -0,0 +1,14 @@
+phil my visit to meitner s group was very interesting and paid off in an unexpected way as you
+suspected nuclear energy has serious potential and there area number of groups working to realise
+that one of meitner s collaborators has been in contact with a group of dissident german scientists
+close to einstein and they have been passing intelligence concerning the nazi nuclear programme to
+the swedish team while i was there one of their contacts in berlin smuggled out a copy of a letter
+sent by the scientists joos and hanle to wilhelm dames at the reichs erziehung s ministerium it
+outlines the potential military applications of nuclear energy and apparently the minister was so
+impressed by its contents that within a week he had convened a toplevel group to develop the ideas
+within it the boss team in berlin have ramped up monitoring of communications to and from the
+ministry and the most promising lead is the attached memo the envelope was marked die alchemist en i
+am not sure how free you are to travel but i have to meetup with my new norwegian friends and then
+head back to england could you move your base to france and make contact with some of our allies i
+think we should open discussions with the french minister of armaments we are going to need his help
+harry
\ No newline at end of file
diff --git a/2020-early/4b.ciphertext b/2020-early/4b.ciphertext
new file mode 100644 (file)
index 0000000..9135e95
--- /dev/null
@@ -0,0 +1,7 @@
+WSIJK BYYKSCT DW VSY HZARYBSJKYC ADBBSKKYY, IYSARJYIQSYRLCTJBSCSJKYISLB, KNYCKP CSCKR HFISZ CSCYKYYC KRSIKP CSCY
+KRY ADBBSKKYY NHJ IYADCMYCYV EP KRY BSCSJKYI HK KRY IYGLYJK DW KRY ARHCAYZZDI RSBJYZW.
+SK SJ KHJXYV NSKR IYHZSJSCT KRY BSZSKHIP HCV SCVLJKISHZ FIDBSJY DW CLAZYHI YCYITP.
+KRY ADBBSKKYY IYADTCSJYJ KRY KYARCSAHZ ARHZZYCTYJ SCMDZMYV SC SCVLJKISHZSJSCT KRY FIDAYJJYJ RSKRYIKD ADCVLAKYV LCVYI ZHEDIHKDIP ADCVSKSDCJ, ELK WYYZJ KRHK KRY DEJKHAZYJ AHC EY DMYIADBY EP H ADBESCHKSDC DW JASYCKSWSA HCV YCTSCYYISCT YOAYZZYCAY HZIYHVP FDJJYJJYV EP KRY JKHKY.
+KRY ADBBSKKYY SVYCKSWSYV KRHK KRY FISCASFZY SJJLY SJ KRHK DW ADCKIDZZSCT KRY CLAZYHI IYHAKSDC NRSAR SJ BYVSHKYV EP KRY YCYITP DW WIYY CYLKIDCJ. KRYJY CYYV KD EY JZDNYV KD YWWYAKSMYZP RHICYJJ KRYSI FDNYI, HCV KD KRSJ YCV KRY ADBBSKKYY IYADBBYCVJ KRY HAGLSJSKSDC DW H JLSKHEZY BDVYIHKDI.
+KRY EYJK-XCDNC AHCVSVHKY SJ VYLKYISLB HCV KRY EYJK JDLIAY DW KRSJ BHKYISHZ SJ KRY FDNYI FZHCK HK MYBDIX SC CDINHP. KRY KIDCJKHV HCV EILC YZYAKIDZPKSA FIDAYJJ HK KRHK WHASZSKP SJ FIDVLASCT DMYI KNYCKP XSZDTIHBJ DW RYHMP NHKYI FYI PYHI, HCV KRSJ ADLZV YHJSZP EY JAHZYV LF.
+JSCAY NY VD CDK NHCK KD HZYIK DLI YCYBSYJ KD KRY SBFDIKHCAY DW KRY BHKYISHZ KRY ADBBSKKYY IYADBBYCVJ FZHASCT HC SCSKSHZ DIVYI WDI WSMY ZSKIYJ DW RYHMP NHKYI KRIDLTR DLI DNC VPY SCVLJKIP JPCVSAHKY ADIFDIHKSDC NRSAR, EP RHFFP HAASVYCK, DNCJ H GLHIKYI DW KRY JRHIYJ SC KRY MYBDIX FZHCK.
diff --git a/2020-early/4b.plaintext b/2020-early/4b.plaintext
new file mode 100644 (file)
index 0000000..9ad14a8
--- /dev/null
@@ -0,0 +1,7 @@
+first meeting of die alchemisten committee, reichserziehungsministerium, twenty ninth april nineteen thirty nine
+the committee was reconvened by the minister at the request of the chancellor himself.
+it is tasked with realising the military and industrial promise of nuclear energy.
+the committee recognises the technical challenges involved in industrialising the processes hitherto conducted under laboratory conditions, but feels that the obstacles can be overcome by a combination of scientific and engineering excellence already possessed by the state.
+the committee identified that the principle issue is that of controlling the nuclear reaction which is mediated by the energy of free neutrons. these need to be slowed to effectively harness their power, and to this end the committee recommends the acquisition of a suitable moderator.
+the best-known candidate is deuterium and the best source of this material is the power plant at vemork in norway. the tronstad and brun electrolytic process at that facility is producing over twenty kilograms of heavy water per year, and this could easily be scaled up.
+since we do not want to alert our enemies to the importance of the material the committee recommends placing an initial order for five litres of heavy water through our own dye industry syndicate corporation which, by happy accident, owns a quarter of the shares in the vemork plant.