Initial commit
authorNeil Smith <neil.git@njae.me.uk>
Thu, 22 Oct 2020 16:10:34 +0000 (17:10 +0100)
committerNeil Smith <neil.git@njae.me.uk>
Thu, 22 Oct 2020 16:10:34 +0000 (17:10 +0100)
338 files changed:
.gitignore [new file with mode: 0644]
2012/1a.ciphertext [new file with mode: 0644]
2012/1a.plaintext [new file with mode: 0644]
2012/1b.ciphertext [new file with mode: 0644]
2012/1b.plaintext [new file with mode: 0644]
2012/2a.ciphertext [new file with mode: 0644]
2012/2a.plaintext [new file with mode: 0644]
2012/2b.ciphertext [new file with mode: 0644]
2012/2b.plaintext [new file with mode: 0644]
2012/3a.ciphertext [new file with mode: 0644]
2012/3a.plaintext [new file with mode: 0644]
2012/3b.ciphertext [new file with mode: 0644]
2012/3b.plaintext [new file with mode: 0644]
2012/4a.ciphertext [new file with mode: 0644]
2012/4a.plaintext [new file with mode: 0644]
2012/4b.ciphertext [new file with mode: 0644]
2012/4b.plaintext [new file with mode: 0644]
2012/5a.ciphertext [new file with mode: 0644]
2012/5a.plaintext [new file with mode: 0644]
2012/5b.ciphertext [new file with mode: 0644]
2012/5b.plaintext [new file with mode: 0644]
2012/6a.ciphertext [new file with mode: 0644]
2012/6a.plaintext [new file with mode: 0644]
2012/6b.ciphertext [new file with mode: 0644]
2012/6b.plaintext [new file with mode: 0644]
2012/7a.ciphertext [new file with mode: 0644]
2012/7a.plaintext [new file with mode: 0644]
2012/7b.ciphertext [new file with mode: 0644]
2012/7b.plaintext [new file with mode: 0644]
2012/8a.ciphertext [new file with mode: 0644]
2012/8a.plaintext [new file with mode: 0644]
2012/8b.ciphertext [new file with mode: 0644]
2012/8b.plaintext [new file with mode: 0644]
2013/1a.ciphertext [new file with mode: 0644]
2013/1a.plaintext [new file with mode: 0644]
2013/1b.ciphertext [new file with mode: 0644]
2013/1b.plaintext [new file with mode: 0644]
2013/2013-challenge6.ipynb [new file with mode: 0644]
2013/2013-challenge7.ipynb [new file with mode: 0644]
2013/2a.ciphertext [new file with mode: 0644]
2013/2a.plaintext [new file with mode: 0644]
2013/2b.ciphertext [new file with mode: 0644]
2013/2b.plaintext [new file with mode: 0644]
2013/3a.ciphertext [new file with mode: 0644]
2013/3b.ciphertext [new file with mode: 0644]
2013/4a.ciphertext [new file with mode: 0644]
2013/4b.ciphertext [new file with mode: 0644]
2013/5a.ciphertext [new file with mode: 0644]
2013/5b.ciphertext [new file with mode: 0644]
2013/6a.ciphertext [new file with mode: 0644]
2013/6b.ciphertext [new file with mode: 0644]
2013/7a.ciphertext [new file with mode: 0644]
2013/7b.ciphertext [new file with mode: 0644]
2013/mona-lisa-words.txt [new file with mode: 0644]
2013/solutions.txt [new file with mode: 0644]
2014/1a.ciphertext [new file with mode: 0644]
2014/1b.ciphertext [new file with mode: 0644]
2014/2014-challenge1.ipynb [new file with mode: 0644]
2014/2014-challenge2.ipynb [new file with mode: 0644]
2014/2014-challenge3.ipynb [new file with mode: 0644]
2014/2014-challenge4.ipynb [new file with mode: 0644]
2014/2014-challenge5.ipynb [new file with mode: 0644]
2014/2014-challenge6.ipynb [new file with mode: 0644]
2014/2014-challenge7.ipynb [new file with mode: 0644]
2014/2014-challenge8.ipynb [new file with mode: 0644]
2014/2a.ciphertext [new file with mode: 0644]
2014/2b.ciphertext [new file with mode: 0644]
2014/3a.ciphertext [new file with mode: 0644]
2014/3b.ciphertext [new file with mode: 0644]
2014/4a.ciphertext [new file with mode: 0644]
2014/4b.ciphertext [new file with mode: 0644]
2014/5a.ciphertext [new file with mode: 0644]
2014/5b.ciphertext [new file with mode: 0644]
2014/6a.ciphertext [new file with mode: 0644]
2014/6b.ciphertext [new file with mode: 0644]
2014/7a.ciphertext [new file with mode: 0644]
2014/7b.ciphertext [new file with mode: 0644]
2014/8a.ciphertext [new file with mode: 0644]
2014/8b.ciphertext [new file with mode: 0644]
2015/1a.ciphertext [new file with mode: 0644]
2015/1b.ciphertext [new file with mode: 0644]
2015/2015-challenge1.ipynb [new file with mode: 0644]
2015/2015-challenge2.ipynb [new file with mode: 0644]
2015/2015-challenge3.ipynb [new file with mode: 0644]
2015/2015-challenge4.ipynb [new file with mode: 0644]
2015/2015-challenge5.ipynb [new file with mode: 0644]
2015/2015-challenge6.ipynb [new file with mode: 0644]
2015/2015-challenge7.ipynb [new file with mode: 0644]
2015/2015-challenge8.ipynb [new file with mode: 0644]
2015/2a.ciphertext [new file with mode: 0644]
2015/2b.ciphertext [new file with mode: 0644]
2015/3a.ciphertext [new file with mode: 0644]
2015/3b.ciphertext [new file with mode: 0644]
2015/4a.ciphertext [new file with mode: 0644]
2015/4b.ciphertext [new file with mode: 0644]
2015/5a.ciphertext [new file with mode: 0644]
2015/5b.ciphertext [new file with mode: 0644]
2015/6a.ciphertext [new file with mode: 0644]
2015/6b.ciphertext [new file with mode: 0644]
2015/7a.ciphertext [new file with mode: 0644]
2015/7b.ciphertext [new file with mode: 0644]
2015/8a.ciphertext [new file with mode: 0644]
2015/8b.ciphertext [new file with mode: 0644]
2015/Solitaire.py [new file with mode: 0644]
2015/cards2.png [new file with mode: 0644]
2015/sol.py [new file with mode: 0644]
2016/1a.ciphertext [new file with mode: 0644]
2016/1b.ciphertext [new file with mode: 0644]
2016/2016-challenge1.ipynb [new file with mode: 0644]
2016/2016-challenge2.ipynb [new file with mode: 0644]
2016/2016-challenge3.ipynb [new file with mode: 0644]
2016/2016-challenge4.ipynb [new file with mode: 0644]
2016/2016-challenge5.ipynb [new file with mode: 0644]
2016/2016-challenge6.ipynb [new file with mode: 0644]
2016/2016-challenge7.ipynb [new file with mode: 0644]
2016/2016-challenge8.ipynb [new file with mode: 0644]
2016/2016-challenge8b.ipynb [new file with mode: 0644]
2016/2a.ciphertext [new file with mode: 0644]
2016/2b.ciphertext [new file with mode: 0644]
2016/3a.ciphertext [new file with mode: 0644]
2016/3b.ciphertext [new file with mode: 0644]
2016/4a.ciphertext [new file with mode: 0644]
2016/4b.ciphertext [new file with mode: 0644]
2016/5a.ciphertext [new file with mode: 0644]
2016/5b.ciphertext [new file with mode: 0644]
2016/6a.ciphertext [new file with mode: 0644]
2016/6b.ciphertext [new file with mode: 0644]
2016/7a.ciphertext [new file with mode: 0644]
2016/7b.ciphertext [new file with mode: 0644]
2016/8a.ciphertext [new file with mode: 0644]
2016/8b.ciphertext [new file with mode: 0644]
2017/1a.ciphertext [new file with mode: 0644]
2017/1a.plaintext [new file with mode: 0644]
2017/1b.ciphertext [new file with mode: 0644]
2017/1b.plaintext [new file with mode: 0644]
2017/2017-challenge1.ipynb [new file with mode: 0644]
2017/2017-challenge2.ipynb [new file with mode: 0644]
2017/2017-challenge3.ipynb [new file with mode: 0644]
2017/2017-challenge4.ipynb [new file with mode: 0644]
2017/2017-challenge5.ipynb [new file with mode: 0644]
2017/2017-challenge6.ipynb [new file with mode: 0644]
2017/2017-challenge7.ipynb [new file with mode: 0644]
2017/2017-challenge8.ipynb [new file with mode: 0644]
2017/2a.ciphertext [new file with mode: 0644]
2017/2a.plaintext [new file with mode: 0644]
2017/2b.ciphertext [new file with mode: 0644]
2017/2b.plaintext [new file with mode: 0644]
2017/3a.ciphertext [new file with mode: 0644]
2017/3a.plaintext [new file with mode: 0644]
2017/3b.ciphertext [new file with mode: 0644]
2017/3b.plaintext [new file with mode: 0644]
2017/4a.ciphertext [new file with mode: 0644]
2017/4a.plaintext [new file with mode: 0644]
2017/4b.ciphertext [new file with mode: 0644]
2017/4b.plaintext [new file with mode: 0644]
2017/5a.ciphertext [new file with mode: 0644]
2017/5a.plaintext [new file with mode: 0644]
2017/5b.ciphertext [new file with mode: 0644]
2017/5b.plaintext [new file with mode: 0644]
2017/6a.ciphertext [new file with mode: 0644]
2017/6a.plaintext [new file with mode: 0644]
2017/6b.ciphertext [new file with mode: 0644]
2017/6b.plaintext [new file with mode: 0644]
2017/7a.ciphertext [new file with mode: 0644]
2017/7a.plaintext [new file with mode: 0644]
2017/7b.ciphertext [new file with mode: 0644]
2017/7b.plaintext [new file with mode: 0644]
2017/8a.ciphertext [new file with mode: 0644]
2017/8a.plaintext [new file with mode: 0644]
2017/8b.ciphertext [new file with mode: 0644]
2017/8b.plaintext [new file with mode: 0644]
2017/Aquilae-Clue-6.jpg [new file with mode: 0644]
2017/picture-clue.ipynb [new file with mode: 0644]
2017/polybius-development.ipynb [new file with mode: 0644]
2018/1a.ciphertext [new file with mode: 0644]
2018/1a.plaintext [new file with mode: 0644]
2018/1b.ciphertext [new file with mode: 0644]
2018/1b.plaintext [new file with mode: 0644]
2018/2018-challenge1.ipynb [new file with mode: 0644]
2018/2018-challenge1.py [new file with mode: 0644]
2018/2018-challenge2.ipynb [new file with mode: 0644]
2018/2018-challenge3.ipynb [new file with mode: 0644]
2018/2018-challenge4.ipynb [new file with mode: 0644]
2018/2018-challenge5.ipynb [new file with mode: 0644]
2018/2018-challenge6.ipynb [new file with mode: 0644]
2018/2018-challenge7.ipynb [new file with mode: 0644]
2018/2018-challenge8.ipynb [new file with mode: 0644]
2018/2018-challenge9.ipynb [new file with mode: 0644]
2018/2018-challengea.ipynb [new file with mode: 0644]
2018/2a.ciphertext [new file with mode: 0644]
2018/2a.plaintext [new file with mode: 0644]
2018/2b.ciphertext [new file with mode: 0644]
2018/2b.plaintext [new file with mode: 0644]
2018/3a.ciphertext [new file with mode: 0644]
2018/3a.plaintext [new file with mode: 0644]
2018/3b.ciphertext [new file with mode: 0644]
2018/3b.plaintext [new file with mode: 0644]
2018/4a.ciphertext [new file with mode: 0644]
2018/4a.plaintext [new file with mode: 0644]
2018/4b.ciphertext [new file with mode: 0644]
2018/4b.plaintext [new file with mode: 0644]
2018/5a.ciphertext [new file with mode: 0644]
2018/5a.plaintext [new file with mode: 0644]
2018/5b.ciphertext [new file with mode: 0644]
2018/5b.plaintext [new file with mode: 0644]
2018/6a.ciphertext [new file with mode: 0644]
2018/6a.plaintext [new file with mode: 0644]
2018/6b.ciphertext [new file with mode: 0644]
2018/6b.plaintext [new file with mode: 0644]
2018/7a.ciphertext [new file with mode: 0644]
2018/7a.plaintext [new file with mode: 0644]
2018/7b.ciphertext [new file with mode: 0644]
2018/7b.plaintext [new file with mode: 0644]
2018/8a.ciphertext [new file with mode: 0644]
2018/8a.plaintext [new file with mode: 0644]
2018/8b.ciphertext [new file with mode: 0644]
2018/8b.plaintext [new file with mode: 0644]
2018/9a.ciphertext [new file with mode: 0644]
2018/9a.plaintext [new file with mode: 0644]
2018/9b.ciphertext [new file with mode: 0644]
2018/9b.plaintext [new file with mode: 0644]
2018/aa.ciphertext [new file with mode: 0644]
2018/aa.plaintext [new file with mode: 0644]
2018/ab.ciphertext [new file with mode: 0644]
2018/ab.plaintext [new file with mode: 0644]
2018/history-words-raw.txt [new file with mode: 0644]
2018/history-words.txt [new file with mode: 0644]
2018/make-history-words.ipynb [new file with mode: 0644]
2019/1a.ciphertext [new file with mode: 0644]
2019/1a.plaintext [new file with mode: 0644]
2019/1b.ciphertext [new file with mode: 0644]
2019/1b.plaintext [new file with mode: 0644]
2019/2019-challenge1.ipynb [new file with mode: 0644]
2019/2019-challenge2.ipynb [new file with mode: 0644]
2019/2019-challenge3.ipynb [new file with mode: 0644]
2019/2019-challenge4.ipynb [new file with mode: 0644]
2019/2019-challenge5.ipynb [new file with mode: 0644]
2019/2019-challenge6.ipynb [new file with mode: 0644]
2019/2019-challenge7.ipynb [new file with mode: 0644]
2019/2019-challenge8.ipynb [new file with mode: 0644]
2019/2019-challenge8b.ipynb [new file with mode: 0644]
2019/2019-challenge9.ipynb [new file with mode: 0644]
2019/2019-challenge9b.ipynb [new file with mode: 0644]
2019/2a.ciphertext [new file with mode: 0644]
2019/2a.plaintext [new file with mode: 0644]
2019/2b.ciphertext [new file with mode: 0644]
2019/2b.plaintext [new file with mode: 0644]
2019/3a.ciphertext [new file with mode: 0644]
2019/3a.plaintext [new file with mode: 0644]
2019/3b.ciphertext [new file with mode: 0644]
2019/3b.plaintext [new file with mode: 0644]
2019/4a.ciphertext [new file with mode: 0644]
2019/4a.plaintext [new file with mode: 0644]
2019/4b.ciphertext [new file with mode: 0644]
2019/4b.plaintext [new file with mode: 0644]
2019/5a.ciphertext [new file with mode: 0644]
2019/5a.plaintext [new file with mode: 0644]
2019/5b.ciphertext [new file with mode: 0644]
2019/5b.plaintext [new file with mode: 0644]
2019/6a.ciphertext [new file with mode: 0644]
2019/6a.plaintext [new file with mode: 0644]
2019/6b.ciphertext [new file with mode: 0644]
2019/6b.plaintext [new file with mode: 0644]
2019/7a.ciphertext [new file with mode: 0644]
2019/7a.plaintext [new file with mode: 0644]
2019/7b.ciphertext [new file with mode: 0644]
2019/7b.plaintext [new file with mode: 0644]
2019/8a.ciphertext [new file with mode: 0644]
2019/8a.given.plaintext [new file with mode: 0644]
2019/8a.plaintext [new file with mode: 0644]
2019/8b.ciphertext [new file with mode: 0644]
2019/8b.given.plaintext [new file with mode: 0644]
2019/8b.plaintext [new file with mode: 0644]
2019/9a.ciphertext [new file with mode: 0644]
2019/9a.plaintext [new file with mode: 0644]
2019/9b.ciphertext [new file with mode: 0644]
2019/9b.plaintext [new file with mode: 0644]
2020-early/1a.ciphertext [new file with mode: 0644]
2020-early/1a.plaintext [new file with mode: 0644]
2020-early/1b.ciphertext [new file with mode: 0644]
2020-early/1b.plaintext [new file with mode: 0644]
2020-early/2020-a-challenge1.ipynb [new file with mode: 0644]
2020-early/2020-a-challenge1.md [new file with mode: 0644]
2020-early/2020-a-challenge2.ipynb [new file with mode: 0644]
2020-early/2020-a-challenge2.md [new file with mode: 0644]
2020-early/2020-a-challenge3.ipynb [new file with mode: 0644]
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/2020-a-challenge5.ipynb [new file with mode: 0644]
2020-early/2020-a-challenge5.md [new file with mode: 0644]
2020-early/2020-a-challenge6.ipynb [new file with mode: 0644]
2020-early/2020-a-challenge6.md [new file with mode: 0644]
2020-early/2020-a-challenge7.ipynb [new file with mode: 0644]
2020-early/2020-a-challenge7.md [new file with mode: 0644]
2020-early/2020-a-challenge8.ipynb [new file with mode: 0644]
2020-early/2020-a-challenge8.md [new file with mode: 0644]
2020-early/2020-a-challenge9.ipynb [new file with mode: 0644]
2020-early/2020-a-challenge9.md [new file with mode: 0644]
2020-early/2a.ciphertext [new file with mode: 0644]
2020-early/2a.plaintext [new file with mode: 0644]
2020-early/2b.ciphertext [new file with mode: 0644]
2020-early/2b.plaintext [new file with mode: 0644]
2020-early/3a.ciphertext [new file with mode: 0644]
2020-early/3a.plaintext [new file with mode: 0644]
2020-early/3b.ciphertext [new file with mode: 0644]
2020-early/3b.plaintext [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]
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]
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]
2020-early/7a.ciphertext [new file with mode: 0644]
2020-early/7a.plaintext [new file with mode: 0644]
2020-early/7b.ciphertext [new file with mode: 0644]
2020-early/7b.plaintext [new file with mode: 0644]
2020-early/8a.ciphertext [new file with mode: 0644]
2020-early/8a.plaintext [new file with mode: 0644]
2020-early/8b.ciphertext [new file with mode: 0644]
2020-early/8b.plaintext [new file with mode: 0644]
2020-early/9a.ciphertext [new file with mode: 0644]
2020-early/9a.plaintext [new file with mode: 0644]
2020-early/9b.ciphertext [new file with mode: 0644]
2020-early/9b.plaintext [new file with mode: 0644]
2020-early/morse.txt [new file with mode: 0644]
2020/2020-a-challenge1.ipynb [new file with mode: 0644]
2020/2020-a-challenge1.md [new file with mode: 0644]
2020/ciphertext.1a.txt [new file with mode: 0644]
2020/ciphertext.1b.txt [new file with mode: 0644]
2020/plaintext.1a.txt [new file with mode: 0644]
2020/plaintext.1b.txt [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..1e96007
--- /dev/null
@@ -0,0 +1,9 @@
+*~
+*doc
+*log
+/tmp
+/__pycache__/*
+*pyc
+.ipynb*
+*.sublime-workspace
+.directory/*
\ No newline at end of file
diff --git a/2012/1a.ciphertext b/2012/1a.ciphertext
new file mode 100644 (file)
index 0000000..c5bd87f
--- /dev/null
@@ -0,0 +1,11 @@
+UG LMIZ KPIZTMA, 
+
+Q PIDM LMKGXPMZML BPM NQZAB AMKBQWV WN UG CVKTM’A EQTT IVL Q IU LMMXTG AILLMVML IVL XMZXTMFML JG QB. Q PIL PWXML BPIB QB EWCTL MFXTIQV BPM AIL KQZKCUABIVKMA WN PQA LMIBP IVL ITTWE UM BW ZMUMUJMZ PQU EQBP BPM INNMKBQWV Q ZMKITT NZWU UG KPQTLPWWL. WN KWCZAM Q SVME BPIB BQJMZQCA PIL JMMV MVOIOML QV AMKZMB OWDMZVUMVB EWZS XZQWZ BW BPM EIZ, JCB Q PIL ZMNCAML BW JMTQMDM BPIB PM KWCTL PIDM PIL IVGBPQVO BW LW EQBP BPWAM NWCT VME EMIXWVA BPIB AW AKIZZML UG OMVMZIBQWV. Q IU VWB ACZM BPIB Q EIVB BW ZMIL BPM ZMAB WN PQA TMBBMZ BW UM. JMNWZM Q ZMIL QB Q KWCTL VWB PIDM IKKMXBML BPIB PM PIL KWTTIJWZIBML EQBP BPM MVMUG, JCB Q PIL VWB ZMITQHML BPIB PM EIA IKYCIQVBML EQBP PIPV, I NIKB Q ZMIL EQBP LQABIABM, IVL PQA KTIQU BW PIDM UIQVBIQVML BPIB ZMTIBQWVAPQX IB BPM ZMYCMAB WN BPM OWDMZVUMVB QA BPM EWZAB AWZB WN AMTN-RCABQNQKIBQWV. 
+
+Q IU XCHHTML JG BQJMZQCA’A ABZIVOM QVABZCKBQWV BPIB Q APWCTL LMKGXPMZ BPM LWKCUMVB. QB AMMUA I BZQDQITQHQVO, QN VWB BW AIG NZQDWTWCA, ZMYCMAB. QB QA PIZL BW AYCIZM BPQA EQBP BPM ACQKQLM VWBM WN I BZIQBWZ, JCB XMZPIXA Q PIDM JMMV PMZM WV UITBI NWZ BWW TWVO. QB QA UIVG GMIZA AQVKM Q AXMVB BQUM QV BPM KWUXIVG WN NZQMVLA WZ ZMTIBQDMA IVL, BPWCOP Q NQVL BPM AWTQBCLM KWVAWTQVO, QB UISMA UM I XWWZ RCLOM WN KPIZIKBMZ. 
+
+Q IU AWZZG BW AIG BPIB Q IU IAPIUML WN UG CVKTM IVL Q PIDM LMKQLML VWB BW KWVBQVCM EQBP BPQA CVXTMIAIVB OIUM. Q EQTT PIDM VWBPQVO UWZM BW LW EQBP PQU, JCB Q AMM VW VMML BW ILL BW BPM MUJIZZIAAUMVB WN PQA NZQMVLA IVL NIUQTG IVL Q EWCTL IAS GWC BW UIQVBIQV BPM OZMIBMAB LQAKZMBQWV QV GWCZ KWUUCVQKIBQWVA KWVKMZVQVO BPQA LQAIXXWQVBQVO LWKCUMVB, IA Q PIDM LWVM QV MVKZGXBQVO BPQA TMBBMZ. 
+
+GWCZA AQVKMZMTG, 
+
+VQKPWTIA 
\ No newline at end of file
diff --git a/2012/1a.plaintext b/2012/1a.plaintext
new file mode 100644 (file)
index 0000000..ce786bd
--- /dev/null
@@ -0,0 +1,11 @@
+My Dear Charles, 
+
+I have decyphered the first section of my Uncle’s will and I am deeply saddened and perplexed by it. I had hoped that it would explain the sad circumstances of his death and allow me to remember him with the affection I recall from my childhood. Of course I knew that Tiberius had been engaged in secret government work prior to the War, but I had refused to believe that he could have had anything to do with those foul new weapons that so scarred my generation. I am not sure that I want to read the rest of his letter to me. Before I read it I could not have accepted that he had collaborated with the enemy, but I had not realized that he was acquainted with Hahn, a fact I read with distaste, and his claim to have maintained that relationship at the request of the government is the worst sort of self-justification. 
+
+I am puzzled by Tiberius’s strange instruction that I should decypher the document. It seems a trivializing, if not to say frivolous, request. It is hard to square this with the suicide note of a traitor, but perhaps I have been here on Malta for too long. It is many years since I spent time in the company of friends or relatives and, though I find the solitude consoling, it makes me a poor judge of character. 
+
+I am sorry to say that I am ashamed of my Uncle and I have decided not to continue with this unpleasant game. I will have nothing more to do with him, but I see no need to add to the embarrassment of his friends and family and I would ask you to maintain the greatest discretion in your communications concerning this disappointing document, as I have done in encrypting this letter. 
+
+Yours sincerely, 
+
+Nicholas 
\ No newline at end of file
diff --git a/2012/1b.ciphertext b/2012/1b.ciphertext
new file mode 100644 (file)
index 0000000..ec0ba85
--- /dev/null
@@ -0,0 +1,5 @@
+V, GVOREVHF UNJXFZBBE, ORVAT BS FBHAQ ZVAQ, UREROL ERIBXR NYY BGURE JVYYF NAQ PBQVPVYF V ZNL CERIVBHFYL UNIR RKRPHGRQ. GUVF QBPHZRAG VF ZL SVANY QRPYNENGVBA BS VAGRAG SBE GUR QVFCBFNY BS NAL NFFRGF GUNG ERZNVA HAQRE ZL BJAREFUVC NAQ PBAGEBY, NAQ VF ZL SVANY BCCBEGHAVGL GB FRG GUR ERPBEQ FGENVTUG PBAPREAVAT GUR NJSHY RIRAGF BS GUR YNFG SVSGRRA LRNEF. VG VF NYFB ZL SVANY YRGGRE GB LBH, QRNE AVPUBYNF. 
+V PBHYQ ORTVA VA NAL AHZORE BS JNLF, OHG CREUNCF V FUBHYQ FGNEG ONPX VA AVARGRRA GUVEGRRA, JURA V ERPRVIRQ NA VAIVGNGVBA SEBZ CEBS. BGGB UNUA GB NGGRAQ N ZRRGVAT BS GUR QRHGFPURA PURZVFPURA TRFRYYFPUNSG MH OREYVA. GUR FBPVRGL JNF GB OR NQQERFFRQ OL CEBS. RZVYR SVFPURE BA UVF JBEX PBAPREAVAT PBEEBFVIR TNFRF NAQ GURVE RSSRPGF BA GUR UHZNA OBQL. GUVF JNF N FHOWRPG GUNG V SBHAQ CREFBANYYL QVFGNFGRSHY OHG CEBSRFFVBANYYL BS CEBSBHAQ VZCBEGNAPR, FVAPR V BJARQ NAQ BCRENGRQ N AHZORE BS SNPGBEVRF ZNAHSNPGHEVAT PURZVPNY CEBQHPGF, NAQ V GBBX GUR FNSRGL BS GUBFR CYNAGF NAQ ZL RZCYBLRRF IREL FREVBHFYL. GUR IVFVG JNF CEBQHPGVIR NAQ V YRNEARQ N YBG, CREUNCF ZBER GUNA JNF TBBQ SBE ZR. 
+BA ZL ERGHEA V JNF ZRG SEBZ GUR OBNG VA FBHGUNZCGBA OL GJB TRAGYRZRA SEBZ NA BETNAVMNGVBA GURL PNYYRQ IREBAN - IBYHAGRRE RAGRECEVFRF, EBLNY BEQANAPR NFFBPVNGVBA. GUVF GBC-FRPERG TBIREAZRAG NTRAPL JNF ERFCBAFVOYR SBE ERPEHVGVAT YRNQREF BS GUR ZNAHSNPGHEVAT VAQHFGEVRF GB FHCCBEG GUR QVCYBZNGVP NAQ ZVYVGNEL RSSBEGF BS GUR SBERVTA BSSVPR, NAQ GURL NFXRQ ZR GB CEBIVQR GURZ JVGU N ERCBEG BA SVFPURE’F JBEX. V UNQ QRRC ERFREINGVBAF, OHG V ERPBTAVFRQ GUR TEBJVAT GUERNG BS JNE NAQ V JNF VAPERNFVATYL NSENVQ GUNG PURZVPNY JRNCBAF ZVTUG OR HFRQ. VA NAL PNFR GUR GJB TRAGYRZRA, JUB, SBE BOIVBHF ERNFBAF, V AVPXANZRQ INYRAGVAR NAQ CEBGRHF, JRER IREL CREFHNFVIR. V YRNEARQ YNGRE GUNG GURL ORYBATRQ GB N TEBHC JVGUVA IREBAN XABJA NF GUR SNOHYVFGF, QRQVPNGRQ GB JUNG JR JBHYQ ABJ PNYY VASBEZNGVBA JNESNER. GURL JRER FXVYYRQ CEBCBARAGF BS CEBCNTNAQN NAQ ZVFVASBEZNGVBA, NAQ ZNFGREF BS N JUBYR CNABCYL BS ZRGUBQF BS CREFHNFVBA. 
+XABJVAT BS LBHE BJA QERNQSHY RKCREVRAPRF V NZ NFUNZRQ GB NQZVG GUNG V SBHAQ ZLFRYS NGGENPGRQ OL GUR ARJ PUNYYRATRF BS JBEX JVGU GUR NTRAPL. NG GUNG FGNTR V JNF NYZBFG RAGVERYL PBAPREARQ JVGU VAIRFGVTNGVAT ZRGUBQF BS CEBGRPGVBA NTNVAFG GUR ENINTRF BS PUYBEVAR NAQ ZHFGNEQ TNF NGGNPXF NAQ V JNF PBAIVAPRQ GUNG ZL JBEX PBHYQ FNIR YVIRF. V ERQVFPBIRERQ N YBIR SBE GUR QNVYL EVGHNYF BS GUR YNOBENGBEL NAQ RAWBLRQ GUR PYBFR PBYYRTVNY NGZBFCURER VA GUR FRPERG JBEYQ BS IREBAN. NG GURVE ERDHRFG V ZNVAGNVARQ ZL PBAGNPGF JVGU GUR TREZNA FPVRAGVFGF, PBAIVAPRQ GUNG QVNYBT ZVTUG CERIRAG GUR SHYY UBEEBEF BS GUR PBZVAT JNE, OHG VA WHAR AVARGRRA SBHEGRRA N PBAIREFNGVBA JVGU I NAQ C YRQ GB ZR GB ERNYVFR GUNG, OL CEBIVQVAT BHE NEZL JVGU CEBGRPGVBA SEBZ GUR RSSRPGF BS GURFR GREEVOYR JRNCBAF, ZL ERFRNEPU PBHYQ CERPVCVGNGR GURVE HFR OL BHE BJA FVQR. 
+SEVTUGRARQ OL GUVF NAQ OL GUR TEBJVAT CBYVGVPNY VAFGNOVYVGL VA RHEBCR V ERFVTARQ VZZRQVNGRYL SEBZ GUR NTRAPL NAQ ERGHEARQ GB GUR YNOBENGBEVRF BS GUR PBZCNAL V UNQ SBHAQRQ. GUR GJB TRAGYRZNA BS IREBAN JRER, GB FNL GUR YRNFG, HAUNCCL, OHG V PBAIVAPRQ GURZ GUNG ZL SNPGBEVRF JRER FGVYY IVGNY GB OEVGVFU RPBABZVP VAGRERFGF NAQ SBE N JUVYR GURL YRSG ZR NYBAR. GUVF FGBEL ZVTUG UNIR RAQRQ GURER VS V UNQ ABG ERPRVIRQ GUR GRYRTENZ SEBZ LBHE ZBGURE BA WNAHNEL SVSGU, AVARGRRA SVSGRRA. 
\ No newline at end of file
diff --git a/2012/1b.plaintext b/2012/1b.plaintext
new file mode 100644 (file)
index 0000000..b319044
--- /dev/null
@@ -0,0 +1,7 @@
+Plaintext
+
+I, Tiberius Hawksmoor, being of sound mind, hereby revoke all other wills and codicils I may previously have executed. This document is my final declaration of intent for the disposal of any assets that remain under my ownership and control, and is my final opportunity to set the record straight concerning the awful events of the last fifteen years. It is also my final letter to you, dear Nicholas. 
+I could begin in any number of ways, but perhaps I should start back in Nineteen Thirteen, when I received an invitation from Prof. Otto Hahn to attend a meeting of the Deutschen chemischen Gesellschaft zu Berlin. The society was to be addressed by Prof. Emile Fischer on his work concerning corrosive gases and their effects on the human body. This was a subject that I found personally distasteful but professionally of profound importance, since I owned and operated a number of factories manufacturing chemical products, and I took the safety of those plants and my employees very seriously. The visit was productive and I learned a lot, perhaps more than was good for me. 
+On my return I was met from the boat in Southampton by two gentlemen from an organization they called VERONA - Volunteer Enterprises, Royal OrdNance Association. This top-secret government agency was responsible for recruiting leaders of the manufacturing industries to support the diplomatic and military efforts of the Foreign Office, and they asked me to provide them with a report on Fischer’s work. I had deep reservations, but I recognised the growing threat of war and I was increasingly afraid that chemical weapons might be used. In any case the two gentlemen, who, for obvious reasons, I nicknamed Valentine and Proteus, were very persuasive. I learned later that they belonged to a group within VERONA known as the Fabulists, dedicated to what we would now call information warfare. They were skilled proponents of propaganda and misinformation, and masters of a whole panoply of methods of persuasion. 
+Knowing of your own dreadful experiences I am ashamed to admit that I found myself attracted by the new challenges of work with the agency. At that stage I was almost entirely concerned with investigating methods of protection against the ravages of Chlorine and Mustard Gas attacks and I was convinced that my work could save lives. I rediscovered a love for the daily rituals of the laboratory and enjoyed the close collegial atmosphere in the secret world of VERONA. At their request I maintained my contacts with the German scientists, convinced that dialog might prevent the full horrors of the coming war, but in June Nineteen Fourteen a conversation with V and P led to me to realise that, by providing our army with protection from the effects of these terrible weapons, my research could precipitate their use by our own side. 
+Frightened by this and by the growing political instability in Europe I resigned immediately from the agency and returned to the laboratories of the company I had founded. The two gentleman of VERONA were, to say the least, unhappy, but I convinced them that my factories were still vital to British economic interests and for a while they left me alone. This story might have ended there if I had not received the telegram from your mother on January Fifth, Nineteen Fifteen. 
\ No newline at end of file
diff --git a/2012/2a.ciphertext b/2012/2a.ciphertext
new file mode 100644 (file)
index 0000000..4328c08
--- /dev/null
@@ -0,0 +1,14 @@
+TF KLHY UPJOVSHZ 
+
+P RUVD OVD ZOVJRPUN AOLZL YLCLSHAPVUZ TBZA OHCL ILLU MVY FVB, HUK NPCLU FVBY WHZA LEWLYPLUJLZ UV VUL JVBSK ISHTL FVB MVY AOL KLJPZPVU FVB OHCL THKL AV ABYU FVBY IHJR VU FVBY BUJSL’Z ZAYHUNL YLXBLZA. UVULAOLSLZZ, DOPSL DL HYL ZAPSS BUZBYL VM AOL WBYWVZL VM AOL KVJBTLUA P AOPUR PA DVBSK IL H TPZAHRL AV YLSPUXBPZO AOL AHZR OL OHZ ZLA FVB. 
+
+P TBZA HKTPA AOHA P MPUK PA HSTVZA PTWVZZPISL AV YLJVUJPSL FVBY JBYYLUA CPLD VM APILYPBZ DPAO AOL THU DL IVAO RULD, HUK ZV P OHCL AHRLU AOL SPILYAF VM KLJPWOLYPUN AOL ULEA JOHWALY VM OPZ DPSS TFZLSM, PU AOL OVWL VM YLCLHSPUN TVYL PUMVYTHAPVU AOHA TPNOA OLSW BZ AV BUKLYZAHUK OPT ILAALY. P RUVD AOHA PAZ JVUALUAZ DPSS UVA LUAPYLSF YLHZZBYL FVB, IBA P AOPUR FVB VDL PA AV FVBYZLSM, PM UVA AV APILYPBZ, AV YLHK VU. 
+
+PU AOL TLHUAPTL HSSVD TL AV ZOHYL ZVTL YLTHYRZ JVUJLYUPUN AOL DPSS. AOYVBNOVBA TF WYVMLZZPVUHS SPML, P OHCL OHK AOL TPZMVYABUL AV YLHK H UBTILY VM MPUHS SLAALYZ DYPAALU IF TLU KYPCLU AV ZLSM KLZAYBJAPVU HUK P TBZA ALSS FVB AOHA AOPZ OHZ HU LUAPYLSF KPMMLYLUA MLLS AV PA. AOLYL PZ H MYHURULZZ DOPJO ZBNNLZAZ AOHA APILYPBZ PZ TVYL JVUJLYULK MVY AOL AYBAO AV IL RUVDU AOHU OL PZ AV WYVALJA OPZ YLWBAHAPVU. P OHCL H MLLSPUN AOHA APILYPBZ BUKLYZAVVK AOHA AOPZ DVBSK IL OHYK MVY FVB, IBA DOLAOLY FVB SPRL PA VY UVA P HT JLYAHPU AOHA FVB DPSS SLHYU AOL AYBAO PM FVB JVTWSLAL AOL JOHSSLUNL OL OHZ SLMA FVB. 
+
+FVB ZHPK AOHA DL ZOVBSK THPUAHPU AOL NYLHALZA KPZJYLAPVU, IBA P HT ZBYL APILYPBZ DVBSK YLTPUK FVB AOHA H JHLZHY ZOPMA JFWOLY JVBSK UVA WVZZPISF WYVCPKL FVB DPAO AOL KLNYLL VM ZLJBYPAF FVB YLXBPYL. P ZBNNLZA AOHA FVB TPNOA MVSSVD APILYPBZ’Z SLHK HUK BZL ZVTLAOPUN TVYL ZLJBYL SPRL HU HMMPUL ZOPMA JFWOLY MVY FVBY YLWSF. 
+
+FVBYZ, 
+
+
+JOHYSLZ
\ No newline at end of file
diff --git a/2012/2a.plaintext b/2012/2a.plaintext
new file mode 100644 (file)
index 0000000..92f8c1f
--- /dev/null
@@ -0,0 +1,14 @@
+My dear Nicholas 
+
+I know how shocking these revelations must have been for you, and given your past experiences no one could blame you for the decision you have made to turn your back on your uncle’s strange request. Nonetheless, while we are still unsure of the purpose of the document I think it would be a mistake to relinquish the task he has set you. 
+
+I must admit that I find it almost impossible to reconcile your current view of Tiberius with the man we both knew, and so I have taken the liberty of deciphering the next chapter of his will myself, in the hope of revealing more information that might help us to understand him better. I know that its contents will not entirely reassure you, but I think you owe it to yourself, if not to Tiberius, to read on. 
+
+In the meantime allow me to share some remarks concerning the will. Throughout my professional life, I have had the misfortune to read a number of final letters written by men driven to self destruction and I must tell you that this has an entirely different feel to it. There is a frankness which suggests that Tiberius is more concerned for the truth to be known than he is to protect his reputation. I have a feeling that Tiberius understood that this would be hard for you, but whether you like it or not I am certain that you will learn the truth if you complete the challenge he has left you. 
+
+You said that we should maintain the greatest discretion, but I am sure Tiberius would remind you that a Caesar shift cypher could not possibly provide you with the degree of security you require. I suggest that you might follow Tiberius’s lead and use something more secure like an affine shift cypher for your reply. 
+
+Yours, 
+
+
+Charles
\ No newline at end of file
diff --git a/2012/2b.ciphertext b/2012/2b.ciphertext
new file mode 100644 (file)
index 0000000..ea3676a
--- /dev/null
@@ -0,0 +1,9 @@
+CUF YFRX CULC BDH ULA QFFY IZVJFA HI QB TZOZCLSB IDOZVF CSBZYP CD MDOHYCFFS KDS BDHS ODVLO SFPZTFYC KZOOFA TF RZCU ASFLA. BDH RFSF YDC LODYF, Z OLCFS TFC TLYB HYAFSLPF QDBX RUD ULA AFVFZMFA CUF SFVSHZCZYP XFSPFLYCX LYA TLAF CUFZS RLB CD CUF QLCCOFKZFOAX DK KSLYVF LYA QFOPZHT, QHC BDHS VDHSLPF XULTFA TF ZYCD EDZYZYP CUF KZPUC TBXFOK. 
+
+LC CULC CZTF Z ULA DYOB EHXC QFPHY CD UFLS XCDSZFX DK CUF TZXFSB DK CSFYVU RLSKLSF QHC ZC RLX VOFLS CD TLYB DK HX CULC CUZX RLX L YFR JZYA DK RLS, DYF ZY RUZVU CFVUYDODPB RDHOA IOLB L VFYCSLO SDOF. CUZX KLVC RLX YDC ODXC DY TB FSXCRUZOF FTIODBFSX RUD RFSF NHZVJ CD OFLSY CULC Z ULA EDZYFA HI LYA CD TB XHSISZXF CUF CRD PFYCOFTFY KSDT MFSDYL TFC TF LX Z AZXFTQLSJFA DY CUF VDYCZYFYC RZCU L CUDHXLYA DCUFS YFR SFVSHZCX. Z RLX CLJFY CD L VULCFLH KDS QSZFKZYP DY CUF PFSTLY AFMFODITFYC DK PLX RFLIDYX, LYA DY CUF CRFYCB KZSXC DK LISZO YZYFCFFY KZKCFFY Z RLX XFYC QB CSLZY CD EDZY CUF XFVDYA LSTB XFVCDS ZY CUF BISFX XLOZFYC LC XC EHOZFY. 
+
+CUF KDOODRZYP ALB Z RLX ZYCSDAHVFA CD CUF KHOO UDSSDS DK TDAFSY RLSKLSF. LC KZMF D’VODVJ CUF OFLA IZIFX OLZA DMFS CUF FAPF DK CUF PFSTLY CSFYVUFX UZXXFA LYA L TZXC SDOOFA CDRLSAX HX LVSDXX CUF DIFY OLYA. ZC RLX BFOODRZXU-PSFFY, L UFOOZXU, XHOIUHSDHX ULGF, LYA CUF FKKFVCX RFSF LOTDXC ZYXCLYCLYFDHX. MFSDYL ULA LYCZVZILCFA CUF LCCLVJ LYA TB DSAFSX RFSF CD SFVDSA TB DQXFSMLCZDYX DY CUF AFIODBTFYC DK CUF RFLIDY. Z OFLSYFA OLCFS CULC CUF MLOMFX RFSF DIFY KDS EHXC KZMF TZYHCFX QFKDSF CUF PLX VBOZYAFSX RFSF FTICB LYA CUF PLX RLX QODRY QB L PFYCOF YDSCUFSY QSFFGF LC LQDHC KZMF TZOFX LY UDHS. QHC CUF FKKFVCX RFSF KFOC KDS UDHSX LKCFSRLSAX, LYA CUF OFZXHSFOB ILVF DK CUF QZOODRZYP VODHA QFOZFA ZCX AFXCSHVCZMF IDRFS LX ZC ASZKCFA LODYP L XFVCZDY DK CUF CSFYVUFX LC OFLXC L ULOK TZOF ZY OFYPCU. 
+
+CUF PLX OFKC TLYB XHSMZMDSX HYLQOF CD XIFLJ, LYA CUZX ZYVSFLXFA CUF ILYZV, FXIFVZLOOB LTDYP CUF BDHYPFS CSDDIX. CUDXF RUD RFSF YDC DMFSRUFOTFA QB CUF VUDJZYP VUODSZYF RZCUASFR CD QDFXZYPUF, QHC KFLS DK CUF CFSSZKBZYP YFR RFLIDY XFFIFA CUSDHPU CUF OZYFX LYA CULC IDXZCZDY CDD RLX XDDY ODXC. 
+
+RUZOF DCUFS MFSDYL LPFYCX VDYCZYHFA CD CLJF DQXFSMLCZDYX LVSDXX CUF QLCCOFKZFOA Z RLX XFYC CD CUF SFLS CD FWLTZYF CUF XHSMZMDSX, LYA CD SFVDSA CUF FKKDSCX DK CUF TFAZVX CD LOOFMZLCF CUF XDOAZFSX’ XHKKFSZYP.
\ No newline at end of file
diff --git a/2012/2b.plaintext b/2012/2b.plaintext
new file mode 100644 (file)
index 0000000..8868a59
--- /dev/null
@@ -0,0 +1,9 @@
+The news that you had been picked up by Military Police trying to volunteer for your local regiment filled me with dread. You were not alone, I later met many underage boys who had deceived the recruiting sergeants and made their way to the battlefields of France and Belgium, but your courage shamed me into joining the fight myself. 
+
+At that time I had only just begun to hear stories of the misery of trench warfare but it was clear to many of us that this was a new kind of war, one in which technology would play a central role. This fact was not lost on my erstwhile employers who were quick to learn that I had joined up and to my surprise the two gentlemen from VERONA met me as I disembarked on the continent with a thousand other new recruits. I was taken to a chateau for briefing on the German development of gas weapons, and on the twenty first of April nineteen fifteen I was sent by train to join the Second Army sector in the Ypres Salient at St Julien. 
+
+The following day I was introduced to the full horror of modern warfare. At five o’clock the lead pipes laid over the edge of the German trenches hissed and a mist rolled towards us across the open land. It was yellowish-green, a hellish, sulphurous haze, and the effects were almost instantaneous. VERONA had anticipated the attack and my orders were to record my observations on the deployment of the weapon. I learned later that the valves were open for just five minutes before the gas cylinders were empty and the gas was blown by a gentle northern breeze at about five miles an hour. But the effects were felt for hours afterwards, and the leisurely pace of the billowing cloud belied its destructive power as it drifted along a section of the trenches at least a half mile in length. 
+
+The gas left many survivors unable to speak, and this increased the panic, especially among the younger troops. Those who were not overwhelmed by the choking chlorine withdrew to Boesinghe, but fear of the terrifying new weapon seeped through the lines and that position too was soon lost. 
+
+While other VERONA agents continued to take observations across the battlefield I was sent to the rear to examine the survivors, and to record the efforts of the medics to alleviate the soldiers’ suffering.
\ No newline at end of file
diff --git a/2012/3a.ciphertext b/2012/3a.ciphertext
new file mode 100644 (file)
index 0000000..19b7e9f
--- /dev/null
@@ -0,0 +1,13 @@
+TD SVJI PEJIQVL, 
+
+JO DZRI RIBHWB H JT PZWOHWRHWB OZ SVPDCEVI TD RWPQV’L XHQQ. EHL LOJOVTVWO OEJO “OEV SJWBVI SHS WZO VWS XHOE OEV XJI” HL LZTVXEJO JQJITHWB. XJL HO EHL HWOVWOHZW OZ LRBBVLO OEJO H JT JO LZTV IHLN? PZRQS EHL JPOHZWL SRIHWB OEV XJI IVJQQD MV CZLHWB J SJWBVI OZ TV JYOVI JQQ OEHL OHTV? HO HL PQVJI OEJO XV XHQQ EJUV OZ PZTCQVOV OEV SVPIDCOHZW HY XV JIV OZ RWSVILOJWS. 
+
+H SHS WZO VWPZRWOVI UVIZWJ SRIHWB OEV XJI, JWS EJUV EVJIS WZOEHWB JMZRO HO SRIHWB TD VAHQV EVIV ZW TJQOJ, MRO H OEHWN HO THBEO MV OHTV OZ TJNV SHLPIVOV VWFRHIHVL JMZRO HO HW QZWSZW. XZRQS DZR ZMQHBV TV HW OEHL? 
+
+ZWV ZOEVI OEHWB. JQTZLO PVIOJHWQD H JT KRTCHWB JO LEJSZXL, MRO TD QJWSQJSD IVTJINVS OEJO ZUVI OEV QJLO XVVN ZI LZ LEV EJL WZOHPVS OXZ TVW QZHOVIHWB HW OEV WVHBEMZRIEZZS ZY TD JCJIOTVWO. H PJWWZO MVQHVUV OEJO OEHL HL PZWWVPOVS XHOE TD RWPQV’L XHQQ, MRO EHL XJIWHWB EJL JQJITVS TV JWS H EJUV VWBJBVS OEV JLLHLOJWPV ZY J QZPJQ SVOVPOHUV OZ NVVC XJOPE. 
+
+H OJNV DZRI CZHWO JMZRO LVPRIHWB ZRI PZTTRWHPJOHZWL. OHMVIHRL HL PQVJIQD TZIV PZWPVIWVS OZ LVPRIV OEVLV QJOVI LVPOHZWL ZY OEV SZPRTVWO JL XVQQ, JWS H EJS OZ XZIN EJIS OZ MIVJN OEV NVDXZIS PDCEVI EV RLVS EVIV. IVORIWHWB OZ OEV XJIOHTV PZWUVWOHZW ZY YHUV QVOOVI MQZPNL IVJQQD SZVL JSS OZ OEV LVPRIHOD ZY OEV OVAO, JWS H EJS OZ PJIID ZRO YIVFRVWPD JWJQDLHL ZW OEHL LVPOHZW ZY OEV XHQQ. H LRBBVLO OEJO HW OEV YRORIV XV OZZ RLV OEV XJIOHTV PZWUVWOHZW. H OEHWN OEJO XHOE OEHL CIVPJROHZW OEV JYYHWV LEHYO PDCEVI LEZRQS JYYZIS RL LRYYHPHVWO LVPRIHOD HW ZRI QVOOVIL OZ ZWV JWZOEVI. 
+
+DZRIL, 
+
+WHPEZQJL 
\ No newline at end of file
diff --git a/2012/3a.plaintext b/2012/3a.plaintext
new file mode 100644 (file)
index 0000000..cf16276
--- /dev/null
@@ -0,0 +1,13 @@
+My dear Charles, 
+
+At your urging I am continuing to decypher my Uncle’s will. His statement that “the danger did not end with the war” is somewhat alarming. Was it his intention to suggest that I am at some risk? Could his actions during the war really be posing a danger to me after all this time? It is clear that we will have to complete the decryption if we are to understand. 
+
+I did not encounter VERONA during the war, and have heard nothing about it during my exile here on Malta, but I think it might be time to make discrete enquiries about it in London. Would you oblige me in this? 
+
+One other thing. Almost certainly I am jumping at shadows, but my landlady remarked that over the last week or so she has noticed two men loitering in the neighbourhood of my apartment. I cannot believe that this is connected with my Uncle’s will, but his warning has alarmed me and I have engaged the assistance of a local detective to keep watch. 
+
+I take your point about securing our communications. Tiberius is clearly more concerned to secure these later sections of the document as well, and I had to work hard to break the keyword cypher he used here. Returning to the wartime convention of five letter blocks really does add to the security of the text, and I had to carry out frequency analysis on this section of the will. I suggest that in the future we too use the wartime convention. I think that with this precaution the affine shift cypher should afford us sufficient security in our letters to one another. 
+
+Yours, 
+
+Nicholas 
\ No newline at end of file
diff --git a/2012/3b.ciphertext b/2012/3b.ciphertext
new file mode 100644 (file)
index 0000000..c5d4a88
--- /dev/null
@@ -0,0 +1 @@
+IVEEU UEOIC UIVES PHPII POYCB ACGPZ ELPHO PIPHI GCDVW OPBTI VESEB EGPZH CKEGG EPOIE TIEGG WUWET IVPII VEUGC BIZWB EDCHW IWCBH LCJZT RGEPY JDIVE NHEBI NCJBS CUUWO EGHIC VCZTI VEZWB EPBTD GCHEO JIETT EHEGI EGHLW IVUEG COWIN WIVCJ SVIWV PTHEE BIVEL CGHII VPILP GOCJZ TCUUE GWBIV EVCHD WIPZH IGEPI WBSIV EIEGG WUWET KWOIW AHCUI VESPH RJIIV EUWGW BSHFJ PTHLE GELCG HEPBT WLPHH EBIRN KEGCB PICLW IBEHH CBEWG EPZWQ EBCLI VPIIV EWGWB IEBIW CBLPH ICUGW SVIEB AEANG EDCGI HCBIV EUWGH ISPHP IIPOY APTEO ZEPGA NZCPI VWBSU CGIVW HBELI NDECU LPGUP GEPBT IVENB EETET ICUWB TLPNH ICDGE HHJGE AEICL CGYCB IVETE KEZCD AEBIC UCJGC LBLEP DCBIV ENCJB SHJRP ZIEGB VPTUZ ETIVE IGEBO VEHPH IVESP HGCZZ ETPZC BSIVE AVEVP TJGSE TIVEC IVEGH ICGJB ICCPB TIVPI PTTET ICVWH SJWZI WBIVE ENEHC UIVEO CJGIA PGIWP ZVELP HHEBI ICIVE UWGWB SHFJP TPBTK EGCBP OVCHE ICJHE VWHTE PIVPH PLPGB WBSIC AEIVE WGDZP BAWSV IVPKE RPOYU WGETW UWVPT OVCHE BICRZ PAECJ GSEBE GPZHU CGIVW HHPKP SEIGE PIAEB ICUNC JBSPB TUGWS VIEBE TAEBR JIWBH IEPTW BANPB SEGUC ZZCLW BSIVE PIIPO YPIND GEHWO VCHEI CRZPA EIVEE BEANU CGIVW HTEPI VICCP BTUWB PZZNP SGEET ICZEP TPIEP ALCGY WBSCB SPHLE PDCBH WOPBI UCGSW KEANH EZUUC GLVPI VPDDE BETZP IEGPB TWIWH OZEPG IVPIH IPBTW BSRNI VEUWG WBSHF JPTWB IVEOC ZTTPL BWAPT EIVEL CGHIT EOWHW CBCUA NZWUE IVENC JBSAP BHICC TPZCB EPBTR GPKEP BTVEG EAWBT ETAEC UNCJL EVPTH ICDDE TNCJU GCAXC WBWBS IVEPG ANCBO ERJIH CCBNC JLCJZ TREHW MIEEB PBTLE LCJZT BCIRE PRZEI CDGEK EBINC JXCWB WBSIV EGESW AEBII VEBWO CBKWB OETAN HEZUI VPIRN VPHIE BWBSI VEEBT ICIVE LPGWL CJZTH PKEAP BNZWK EHPBT WAWSV IHPKE NCJPZ ZHWTE HWBIV PIIEG GWRZE OCBUZ WOILE GEEBS PSETW BPTEH DEGPI EHEPG OVUCG PBELL EPDCB ICRGE PYIVE TEPTZ NHIPZ EAPIE CUIGE BOVLP GUPGE RJIEK EBWUI VWBSH VPTIJ GBETC JITWU UEGEB IZNWI LCJZT REHIW ZZVPG TICHP NIVPI WAPTE IVEGW SVITE OWHWC BIVPI ACGBW BSWLW ZZJBT EGHIP BTWUN CJOPB IUCGS WKEAE RJIPH NCJLW ZZZPI EGHEE IVWBS HLEGE ICREO CAEUP GACGE OCADZ WOPIE TPBTT PBSEG CJHUC GJHRC IVPBT WPAHC GGNIC HPNIV PIIVE TPBSE GTWTB CIEBT LWIVI VELPG
\ No newline at end of file
diff --git a/2012/3b.plaintext b/2012/3b.plaintext
new file mode 100644 (file)
index 0000000..064e0fd
--- /dev/null
@@ -0,0 +1,7 @@
+The effect of the gas attack on morale was catastrophic and the generals over-reacted. Terrified that the front line positions would break up they sent young officers to hold the line and prosecuted deserters with ferocity. I thought I had seen the worst that war could offer in the hospitals treating the terrified victims of the gas, but the firing squads were worse, and I was sent by VERONA to witness one. I realize now that their intention was to frighten me. My reports on the first gas attack made clear my loathing for this new type of warfare and they needed to find ways to pressure me to work on the development of our own weapon. 
+
+The young subaltern had fled the trenches as the gas rolled along them. He had urged the others to run too, and that added to his guilt in the eyes of the court martial. He was sent to the firing squad and VERONA chose to use his death as a warning to me. Their plan might have backfired if I had chosen to blame our generals for this savage treatment of young and frightened men, but instead, in my anger following the attack at Ypres, I chose to blame the enemy for this death too and finally agreed to lead a team working on gas weapons. 
+
+I can’t forgive myself for what happened later, and it is clear that, standing by the firing squad in the cold dawn, I made the worst decision of my life. The young man stood alone and brave and he reminded me of you. We had stopped you from joining the army once, but soon you would be sixteen and we would not be able to prevent you joining the regiment then. I convinced myself that by hastening the end to the war I would save many lives, and I might save you. 
+
+All sides in that terrible conflict were engaged in a desperate search for a new weapon to break the deadly stalemate of trench warfare but even if things had turned out differently it would be still hard to say that I made the right decision that morning. I will understand if you can’t forgive me, but as you will later see things were to become far more complicated and dangerous for us both and I am sorry to say that the danger did not end with the war. 
\ No newline at end of file
diff --git a/2012/4a.ciphertext b/2012/4a.ciphertext
new file mode 100644 (file)
index 0000000..0a4d99b
--- /dev/null
@@ -0,0 +1 @@
+SEJKG XTOIN URGYE UAXAT IRKYX KBKRG ZOUTI UTIKX TOTMN OYCUX QUTSK ZKUXU RUMEH KMOTY ZUKDV RGOTN OYSUB KOTZU SGZNK SGZOI YLURR UCOTM ZNKCG XOGRC GEYCU TJKXK JCNEN KNGJR KLZZN KRGHU XGZUX OKYGT JLGIZ UXOKY HAZNO YKDVK XOKTI KULOT JAYZX ESAYZ NGBKY UAXKJ GYNKY GCZNK YALLK XOTMZ NGZTK COTBK TZOUT YCKXK IGAYO TMUTZ NKHGZ ZRKLO KRJYO NGBKT UQTUC RKJMK ULZNK CUXQN KYAHY KWAKT ZREJO JGTJZ NKLKC VKUVR KONGB KGYQK JNGBK HKKTY ZXGTM KREAT GHRKU XVKXN GVYXK RAIZG TZZUZ KRRSK GTEZN OTMUL BGRAK ZNKJK ZKIZO BKEUA NOXKJ ZURUU QOTZU ZNKSE YZKXO UAYLO MAXKY UTZNK OYRGT JNGYI UTZGI ZKJSK COZNG XKVUX ZUTNO YOTBK YZOMG ZOUTY NKCGY GHRKZ UZXGI KZCUS KTCNU NGJHK KTSGQ OTMKT WAOXO KYGHU AZEUA XIOXI ASYZG TIKYH AZATL UXZAT GZKRE ZNKEY KKSZU NGBKH KKTGR KXZKJ ZUNOY OTBKY ZOMGZ OUTYG TJRKL ZSGRZ GZCUC KKQYG MUNKN GYGIU TZGIZ OTZNK YNOVV OTMIU SVGTE CNUCG YGHRK ZUZXG IQZNK OXSUB KSKTZ YBOGZ NKCOX KRKYY ZKRKM XGVNG TJZNK EJOYK SHGXQ KJLXU SGIUS SKXIO GRYNO VOTZO RHAXE GZNOY AXMOT MGIRK XQCGY GYYOM TKJZU LURRU CZNKS GTJZN KECKX KRGYZ YKKTK TZKXO TMGHA ORJOT MOTCN OZKNG RROLK GXZNG ZEUAS GEHKU LOTZK XKYZZ UZNKM UBKXT SKTZH AZOGS GZGRU YYZUQ TUCCN EKBKT NGBOT MJKIO VNKXK JZNKL UAXZN YKIZO UTULZ NKCOR RCNOI NGMGO TCGYK TIXEV ZKJAY OTMGQ KECUX JIOVN KXOZO YYZOR RTUZI RKGXN UCZNK KBKTZ YULYU RUTMG MUIUA RJVUY KGXOY QZUEU ATUCU TZNKU ZNKXN GTJOZ OYIRK GXZNG ZZOHK XOAYJ OJTUZ KTZOX KREZX AYZZN KBKXU TGGMK TZYON UVKZN GZZNK LOLZN INGVZ KXCNO INOCO RRRKG BKZUE UACOR RHKMO TZUKD VRGOT CNEQO TJXKM GXJYI NGXRK Y
\ No newline at end of file
diff --git a/2012/4a.plaintext b/2012/4a.plaintext
new file mode 100644 (file)
index 0000000..503102f
--- /dev/null
@@ -0,0 +1,10 @@
+My dear Nicholas, 
+
+Your Uncle’s revelation concerning his work on meteorology begins to explain his move into mathematics following the War. I always wondered why he had left the laboratories and factories, but his experience of industry must have soured as he saw the suffering that new inventions were causing on the battlefields. I have no knowledge of the work he subsequently did, and the few people I have asked have been strangely unable, or perhaps reluctant, to tell me anything of value. 
+
+The detective you hired to look into the mysterious figures on the island has contacted me with a report on his investigations. He was able to trace two men who had been making enquiries about your circumstances, but unfortunately they seem to have been alerted to his investigations and left Malta two weeks ago. He has a contact in the shipping company who was able to track their movements via the wireless telegraph, and they disembarked from a commercial ship in Tilbury. At his urging a clerk was assigned to follow them and they were last seen entering a building in Whitehall. I fear that you may be of interest to the government, but I am at a loss to know why. Even having deciphered the fourth section of the will, which again was encrypted using a keyword cipher, it is still not clear how the events of so long ago could pose a risk to you now. On the other hand it is clear that Tiberius did not entirely trust the VERONA agents. I hope that the fifth chapter, which I will leave to you, will begin to explain why. 
+
+
+Kind regards, 
+
+Charles 
\ No newline at end of file
diff --git a/2012/4b.ciphertext b/2012/4b.ciphertext
new file mode 100644 (file)
index 0000000..423e6b3
--- /dev/null
@@ -0,0 +1 @@
+FDBTS LKIWB DBXWO SYLII SYQFL KLZQD SSTSK QPLZQ DSKSV QZSUJ LKQDP QDSOB FKZSI IFKYS PPBKQ IWBKE QDSQO SKYDS PBKEL ROALL QPZFI ISEUF QDUBQ SOFPM SKQJB KWDLR OPUFQ DZFKC SOPZO LXSKB PFQLL HOSBE FKCPL ZUFKE EFOSY QFLKB KEZLO YSBKE SVMSO FJSKQ SEUFQ DKLXX ISESP FCKPZ LOLRO CBPUS BMLKF UBPDB RKQSE AWQDS JSJLO WLZQD SEBUK ZFOFK CPNRB EBKEA WQDSP RZZSO FKCLZ LROQO LLMPZ LIILU FKCQD SCSOJ BKBQQ BYHBK EFUBP PSFXS EAWBK ROCSK YWQDB QAILY HSEBI IZSSI FKCLZ YLJJL KDRJB KFQWU FQDQD SSKSJ WQDSZ BARIF PQPDB EELKS QDSFO GLAUS IIFQN RFYHI WASYB JSBMM BOSKQ QLJSQ DBQZL OSYBP QFKCB QJLPM DSOFY YLKEF QFLKP ULRIE ASLZY ORYFB IFJML OQBKY SFKES QSOJF KFKCD LUBKE UDSKQ LRPSQ DSUSB MLKUF QDLRQ RKERI WGSLM BOEFX FKCLR OLUKQ OLLMP BZQSO PSTSO BIJLK QDPFK QDSQO SKYDS PQBHF KCJSB PROSJ SKQPF OSQRO KSEQL TSOLK BDNBK EASCB KULOH LKBKS UPQBQ FPQFY BIJLE SILZU FKEJL TSJSK QPABP SELKQ DSULO HLZAB WSPWL RDBEG LFKSE RMBKE ASSKP SKQQL QDSZO LKQAW QDFPQ FJSBK EBPFI BALRO SEFAS CBKQL DSBOQ BISPL ZWLRO DSOLF PJFKA BQQIS FUBPB PDBJS EQLAS SKGLW FKCQD SYLJZ LOQPL ZQDSY DBQSB RARQA WQDSK FUBPL APSPP SEUFQ DQDSA SIFSZ QDBQJ WULOH YLRIE SKEQD SUBON RFYHI WBKEQ DBQFJ FCDQP BTSWL RBKED RKEOS EPLZQ DLRPB KEPLZ WLRKC JSKIF HSWLR ZFKBI IWASC FKKFK CQLJB HSMOL COSPP LKQDS EFZZF YRIQQ BPHLZ BKBIW XFKCU FKEMB QQSOK PFPDL USEJW ULOHQ LTBIS KQFKS BKEMO LQSRP BKEQL JWPRO MOFPS QDSWF JJSEF BQSIW OSBPP FCKSE JSQLB KLQDS OEFTF PFLKF YBKPS SKLUQ DBQQD SPBZS ESMIL WJSKQ LZQDS USBML KUBPB PSYLK EBOWY LKYSO KZLOQ DSJBK EQDSW USOSM OSLYY RMFSE UFQDQ DSISQ DBIML USOFQ ULRIE YLKTS WFQDF KHQDS WUSOS EFPBM MLFKQ SEQDB QFDBE ZBFIS EQLSK CBCSF KQDSE SPFCK LZKSU MLFPL KPARQ FYLRI EKSTS OELQD BQFPQ FIIOS YBIIS EJWDL OOLOB PFIFP QSKSE QLDBD KFKAS OIFKE SPYOF AFKCQ DSSZZ SYQPL ZJRPQ BOECB PQDSO SUBPP LJSQD FKCYD FIIFK CFKQD SYLKQ OBPQA SQUSS KQDSY LIEEF PMBPP FLKLZ BPYFS KQFZF YISYQ ROSBK EQDST FISKS PPLZQ DSOSP RIQPD SOSML OQSEB KEFYL RIEKL QAOFK CJWPS IZQLU LOHFK QDSIB ALOBQ LOFSP ILLHF KCABY HFYBK PSSQD BQQDS ZBARI FPQPK SSESE JSLRQ LZQDS UBWFK LOESO QLYBO OWLRQ QDSKS VQPQS MLZQD SFOMI BKDLU STSOF KOSBP PFCKF KCJSQ DSQUL CSKQI SJSKZ OLJTS OLKBD BEJBE SBTSO WABEJ FPQBH S
\ No newline at end of file
diff --git a/2012/4b.plaintext b/2012/4b.plaintext
new file mode 100644 (file)
index 0000000..1426fca
--- /dev/null
@@ -0,0 +1,5 @@
+I have only a hazy recollection of the events of the next few months. The rain fell incessantly and the trenches, and our boots, filled with water. I spent many hours with fingers frozen as I took readings of wind direction and force, and experimented with nozzle designs for our gas weapon. I was haunted by the memory of the dawn firing squad and by the suffering of our troops following the German attack and I was seized by an urgency that blocked all feeling of common humanity with the enemy. The Fabulists had done their job well. 
+It quickly became apparent to me that forecasting atmospheric conditions would be of crucial importance in determining how and when to use the weapon without unduly jeopardizing our own troops. After several months in the trenches taking measurements I returned to VERONA HQ and began work on a new statistical model of wind movements based on the work of Bayes. You had joined up and been sent to the front by this time, and as I laboured I began to hear tales of your heroism in battle. I was ashamed to be enjoying the comforts of the Chateau, but by then I was obsessed with the belief that my work could end the war quickly and that I might save you and hundreds of thousands of young men like you. 
+Finally beginning to make progress on the difficult task of analyzing wind patterns I showed my work to Valentine and Proteus and to my surprise they immediately reassigned me to another division. 
+I can see now that the safe deployment of the weapon was a secondary concern for them and they were preoccupied with the lethal power it would convey. I think they were disappointed that I had failed to engage in the design of new poisons, but I could never do that. I still recalled my horror as I listened to Hahn in Berlin describing the effects of mustard gas. There was something chilling in the contrast between the cold dispassion of a scientific lecture and the vileness of the results he reported, and I could not bring myself to work in the laboratories. 
+Looking back I can see that the Fabulists needed me out of the way in order to carry out the next step of their plan, however, in reassigning me, the two gentlemen from VERONA had made a very bad mistake.
\ No newline at end of file
diff --git a/2012/5a.ciphertext b/2012/5a.ciphertext
new file mode 100644 (file)
index 0000000..1e73c50
--- /dev/null
@@ -0,0 +1 @@
+DISFL TSFXI GYJLT UGZAM SBBSF IZHHA YIYPJ ZLXIG MAFWE AFOFU HUGTU ZHIXX URIZL IINBX SUZGH TIRSB GUZTU GTUGH AFPSZ DUEUZ DIIDH UOIFU JGEAJ ZDTUY GIXEL SJRTH JBUZS LAZGB UFSLP OIPAZ DTUGB AMIFH ALAZH FAXHT IZBIF TSBGT UGDIS HTMSG ZAHHT SHAES LAMSF DOJHV JGHBA GGUOX PHTIF IGJXH AEEAJ XBXSP HUOIF UJGUY BXUIG HTSHH TIESO JXUGH GMIFI UZKAX KIDUZ YPUZV JFPSZ DUETI UGLAF FILHH TIZEA FHTIE UFGHH UYIGU ZLIYP IKSLJ SHUAZ EFAYH TIOSH HXIEU IXDUT SKISZ IMIZI YPHAE UZDSZ DHAEU RTHUG MAFID JFUZR HTIXA ZRMII WGAEY PHFIS HYIZH UZHTI EUIXD TAGBU HSXSH IHSBX IGHTS HUMAJ XDZIK IFOIS FSFYG SRSUZ YPZJF GIYUG GOFUH HSUZJ FRIDY IHAHS WILAJ FSRIO JHSXX OFSKI FPMSG RAZID UGGAX KIDOP HTIOJ FZUZR BSUZA EHTIL AFFAG UKIRS GZAMU EIIXS ZIMEU FIHTI SZRIF GHUFF IDUZY IOPJZ LXIHU OIFUJ GGSLL AJZHF IURZU HUZRY PAXDE URTHU ZRGBU FUHSZ DUTSK IDILU DIDHA HSWIA ZHTIU ZKIGH URSHU AZAEH TIESO JXUGH GYPGI XEPAJ GSPHT SHYPI ZIYUI GYSPG HUXXO ISLHU KIUZX AZDAZ GAUMU XXIYO SFWAZ HTIZI NHGHI SYIFH AHTIL UHPLA JXDUS GWPAJ HABXI SGISF FSZRI SLLAY YADSH UAZEA FYIUM UXXHI XIRFS BTYPH FSKIX BXSZG OPHTI MSPHT ILPBT IFJGI DOPHU OIFUJ GUZHT UGHIN HMSGD IKUXU GTXPD UEEUL JXHHA DILFP BHOJH GUZLI MIZAM WZAMH TSHTI MSGHF SUZID UZLFP BHAXA RPMIY URTHI NBILH EJHJF ILTSB HIFGH AOIUZ LFISG UZRXP TSFDH ADILP BTIFU LAZDJ LHIDY PAMZF IGISF LTSZD DUGLA KIFID HTSHH TUGHP BIMSG EUFGH OFAWI ZOPLT SFXIG OSOOS RIHAG SKIPA JHUYI UMUXX HIXXP AJHTS HHTIW IPTSG XIZRH THTFI IPAJF GGUZL IFIXP ZULTA XSG
\ No newline at end of file
diff --git a/2012/5a.plaintext b/2012/5a.plaintext
new file mode 100644 (file)
index 0000000..dd8c594
--- /dev/null
@@ -0,0 +1,11 @@
+Dear Charles, 
+
+Much is now apparent to me. My Uncle’s work for British Intelligence explains the gaps in his history, and if indeed Tiberius found himself caught up in a conspiracy beyond his power to control then perhaps his death was not that of a coward but, just possibly, the result of foul play. 
+
+Tiberius implies that the Fabulists were involved in my injury and if he is correct then for the first time since my evacuation from the Battlefield I have a new enemy to find and to fight. I swore during the long weeks of my treatment in the field hospital at Etaples that I would never bear arms again. My nurse, Miss Brittain, urged me to take courage, but all bravery was gone, dissolved by the burning pain of the corrosive gas. Now I feel a new fire, the anger stirred in me by Uncle Tiberius’s account. Reigniting my old fighting spirit and I have decided to take on the investigation of the Fabulists myself. You say that my enemies may still be active in London so I will embark on the next steamer to the City. Could I ask you to please arrange accommodation for me? I will telegraph my travel plans. 
+
+By the way the cypher used by Tiberius in this text was devilishly difficult to decrypt, but since we now know that he was trained in cryptology we might expect future chapters to be increasingly hard to decypher. I conducted my own research and discovered that this type was first broken by Charles Babbage. To save you time I will tell you that the key has length three. 
+
+Yours sincerely, 
+
+Nicholas
\ No newline at end of file
diff --git a/2012/5b.ciphertext b/2012/5b.ciphertext
new file mode 100644 (file)
index 0000000..39ff6f4
--- /dev/null
@@ -0,0 +1 @@
+FIPYR YREBN IASHC NXMBI YCWGQ RKOXM KRCGG MNIZB IYUML QHGFM QSSLS RJYRB YRYXS SDTMC XMPVM YQDYV RIAGD LGXXF OEBWM PKPRI MUKWP OUSSV CNXMB INYVR DSAYQ KKRBO VBORL SWRYR URSRB EGXIB WIGXX FOIJO QCXXQ YJKIR CGXYC OYXHG DUSSG IVCZO GYWIY ZTYBI LDXFK XRRIK OXFYH QYJAY RBSXG YRYVT PYFYL MJSXG OWBOZ CVSNO HZIFY IIQSR URMAR MFKHZ OGMWI YNIND HSBML QQWGS PUSLG MLNJM BIAKW RSREM SSVHE SZCEW YMVSM MYVEB FELDE EOMLD LCDEQ USDMV WZXYX EJIWG CKJKH YCMUK WRYIQ MENOX FOLMB VMBWM PGFOQ GMEJG IYZSL CMRRM LURMG XFKXT KPCXX GXIYX HNBSR OYQRE BSRRO RBOHR YGJYM QDIPW IGXRY FEJSR ROPJS KCXGC SRMBH CBXMK ZMSHY XCARE LMIRR ERSQG QLRER AYZCB XFOMP NVCKH DEPQO GPOXZ EXRRI POPYD MMXWF STZOX UOILD LCKHK SVYVX WMSBO FPOEI SRENM TSWGY RGXVM YQDYV RIELN XFOEP WCBSZ GCMMX QGSFU KWAVS QOVRR ELDLC PEZEP GCXQR EBSQY QMLOH YXHRR IGXXC BEADM MXFCD ACORR RIQOE EORAS IQDSE OXFOV USXFW CDSIJ NIVZI PSILM IMXXF OGMXX GXILD QCKRR DLYDM UKWGX GPOEQ SREVC CXKYQ IBSRR RIRKW IYJZB IYUML QFYDX JOJGO PBKRB QIPWE LRMER GMWQY XHAYQ KERGM ERSSL CILMS SBEEO HZIXF OILQM LOIPC MLYYP SRABI YCMLQ PWCSN RMQDM AKXCN WGQRY VWSXM RGLMG IPOEB OTRKX GXXCB GCZXG XKROP CQVYZ LGMQC CWYQI QPVMW XFOJY BJGOP BCSDO YPYTC SXFBI UWCQO PDSRR YAMBO MXGCW SPOYL DMJYR CGMLD IPIAC NRCCH YIEDD IPXSM XMPOG CSZCN EKOWQ KKCDL YDKPS TNOHY XHFYV PSJGO HKORC GEQDL GCGGZ LCBAY CMBSH LYXFK ZCDMK OXMOR HYCKI XPSYK ZLGXH CMVWZ XGXKG DEQDL CZPYS RROBR BITOE JOHYM VGWML KPAYR QZMPK GWKXR RIFSK FOWRV ITOPQ SRZBM RSWFS RROPJ SKCXG CVIBL CRRID KFSVM QDWCF ILKWR RIDEP JRSPB SPYJK IMLFS JFIKO RRSRR RIGBW ARIKO AYCPY SHMEX ZOJMB IKOMA YYJNR MDXYU IGDML BINYV RSRED LCMSL CTGBE AIAYC MKZSQ CMZVI QSRAO MAYYJ NRMDF CCYPO AFYAY CMLFS JFIBO ZCXMD SGMEP BDVSC XQYQC YRCYY RCMBO SDFIP YRYDL CCIAE VGDCG XSSBY LSXUK WQYXG QLRDL YDMFK HLYGF KRAOX MDEIO ELIIT SHCXG CGMRR QCSVC KPGJI BDLYD MUYYJ NLYFI RYGMX GCKPK IHGCG MFIPI AFSPC SYLNI PDSMU JSBXF OVPOW CKVAR SDWCM GRGXX MDLCX IRGSP USDDV YSXMB WUSXF SRMEV GXXCV PGQIL MIQOV TSGCC YLPSP DYLKX CVCGG EQMPS WWWSR KIMLF IQDME KXGYR QKRBW CAKVC VIQCR CCWLO EPVCA YWRIS SISSB PGPIY XHWYY PBINE XYDMM XEKSW RKOCP SPGLG MLGME LXITO VDYVE SZCWC QOPDS GYXSL VCNBE WDLYD CMEAG VPZOE ZVIRY JMBKG FIKOM POGCS ZCNER OPCQV YWJPY QTOVM XEQEQ KYRGX KKOFY MORYC NBIQV EROVR RERWS LDLYC MPOEB SXGUR CGXFK XRRID KFSVM QDWFK HQYQC RSULI AYQCK AYBIM PQWSR ROVCC XGXXF OMPCI ABIRG SPUEL NMDEP JIFCV MCFIB DLYDM UKWZO MLQWC XXRYQ WNIYD LGXXF OXPOR ARIQS FMKVB OHRRI ZYERD SDVEL NIPCE LNWSB VMERB OHZIA CKVWC SJNMC BWPOX SBRGX KRYXF OJPYR RVMLO MREVL OHKIX FYYER XQDSD SRBSR EKAYI XMOBN YWCDL CPEZE PGCXQ ZPYXW
\ No newline at end of file
diff --git a/2012/5b.plaintext b/2012/5b.plaintext
new file mode 100644 (file)
index 0000000..7360eb0
--- /dev/null
@@ -0,0 +1 @@
+VERONA had decided to reassign me to a new code-breaking division in London, an outpost of Room Forty within the Admiralty. I was required to report to Commander Denniston who trained me in the elements of my new task and it quickly became apparent that the methods of conditional probabilities developed by Bayes, in which I had become adept during my work on wind forecasting, could give us a crucial advantage in the task of cryptanalysis. Glad as I was to escape the horrors of chemical weapons, I think now that Valentine and Proteus had intended to cloister me in Naval Intelligence in order to avoid any chance that I might uncover their dreadful secret, but the relationship between the Admiralty codebreaking division in Room Forty and the Army division MIIb was closer than the Fabulists had imagined and the interaction between these agencies, together with my field experience on the continent, meant that I was increasingly engaged in the task of breaking battlefield and German High Command communications. Encouraged by the engineers in our increasingly sophisticated signals unit, who were adept at intercepting telegraphic messages from the far fields of Europe, I threw myself into work once more until one wintery Wednesday afternoon I received a message that gripped and horrified me. New as this cipher was I did not have time to enjoy my triumph in decrypting it, as the plaintext revealed a criminal conspiracy at the highest levels in British Intelligence led by the Fabulists. Even as the full horror of my involvement in their scheme was laid out before me I could not take it in. Reporting the conspiracy was impossible since I could not be sure who was involved. Even if I could trust someone outside of VERONA the security in our unit was so tight that I had no chance to take any evidence with me. I realized that I would have to conceal my discovery while I undertook further research of my own into the network of traitors within our intelligence services. Unfortunately I was clumsy in my investigations and my carelessness nearly cost you your life and your reputation, a mistake for which I can never forgive myself. I can only pray that you will be able to forgive me. I received a telegram from VERONA summoning me back to Ypres later that month. As I read it I knew that the Fabulists had somehow become aware of my interest in their secret work, and I fully believed that I was being sent to my death in the trenches I boarded the boat to Flanders and, surrounded by weary soldiers returning to the front line, I turned my thoughts to finding a way to expose the Fabulists plans.
\ No newline at end of file
diff --git a/2012/6a.ciphertext b/2012/6a.ciphertext
new file mode 100644 (file)
index 0000000..51f02eb
--- /dev/null
@@ -0,0 +1 @@
+KILFB WRVCZ LHJVW BGHLF IAMRV RZILF IFBCP LBKWF ILZWT IJVIK LBGIF SCMLF IWBWP LHOWH WJIKJ CKLSU SJPCG IBJZI AIBAL JRVWB GJVIK IHRFW DJWCB CNOLZ IBJWB ILBKD FCJIM HJVIS RZLWA IKJCU ILRJW BGNCF JVIGC OIFBA IBJLB KPIFI LHYWB GWNWY BIPPV IFIJC NWBKS CMJVI SRZIL FZSPI FILPL FIJVL JSCMV LKZIN JALZJ LUMJN CFJMB LJIZS VLKBC JLHNL FLHWR LBJIZ ZJFLR IKSCM VIFIJ VISPI FIACH JWBHW HJIBJ JVLJJ VISBI IKIKJ CJLZY PWJVS CMHLS WBGJV LJJVI GCOIF BAIBJ PLHCP IKLHM UHJLB JWLZH MANFC AJVII HJLJI CNSCM FMBRZ ILBKJ VLJJV ISPWH VIKJC KWHRM HHJIF AHNCF FIDLS AIBJW VLOIJ CHLSJ VLJWP LHWAD FIHHI KUSJV IWFWB GIBMW JSJVI SAWGV JIEML ZZSVL OIRZL WAIKJ CUICN NIFWB GSCML HMACP IKJCJ WUIFW MHUMJ JVIJL ZIJVI SHDMB RLFFW IKXMH JJVIF WGVJZ IOIZC NJVFI LJJCU ILZAC HJRCB OWBRW BGWKI RWDVI FIKJV IZLJI HJRVL DJIFC NSCMF MBRZI HPWZZ PWJVZ WJJZI ACFIK WNNWR MZJSJ VLBWV LKIBR CMBJI FIKPW JVJVI DFIOW CMHHI RJWCB WJPLH OIFSH WAWZL FWBHD WFWJL BKWBK IIKMH IKJVI HLAIJ LUMZL FIRJL JVCMG VJVII BRFSD JWCBL ZGCFW JVAPL HHZWG VJZSK WNNIF IBJWU IZWIO IWJWH YBCPB LHJVI UILMN CFJRW DVIFW FIRCA AIBKJ VLJSC MHJLS LPLSN FCAZC BKCBN CFLZW JJZIP VWZIM BJWZP IVLOI RCBHW KIFIK PVLJP IAMHJ KCJCD FCJIR JSCMW VLOIR CBJLR JHPVC ALSUI LUZIJ CVIZD OIFSU IHJPW HVIHR VLFZI H
\ No newline at end of file
diff --git a/2012/6a.plaintext b/2012/6a.plaintext
new file mode 100644 (file)
index 0000000..2945c98
--- /dev/null
@@ -0,0 +1,8 @@
+Dear Nicholas, things are much clearer now, and I realize the danger you are in. I was visited today by two gentlemen matching the description of Valentine and Proteus. They claimed to be acting for the government and were asking if I knew where to find you. They clearly were aware that you had left Malta, but fortunately had not, as far as I can tell, traced you here. 
+They were most insistent that they needed to talk with you, saying that the government was owed a substantial sum from the estate of your Uncle and that they wished to discuss terms for repayment. I have to say that I was impressed by their ingenuity. They might equally have claimed to be offering you a sum owed to Tiberius, but the tale they spun carried just the right level of threat to be (almost) convincing.
+I deciphered the latest chapter of your Uncle’s will with little more difficulty than I had encountered with the previous section. It was very similar in spirit, and indeed used the same tabula recta, though the encryption algorithm was slightly different. I believe it is known as the Beaufort cipher. 
+I recommend that you stay away from London for a little while, until we have considered what we must do to protect you. I have contacts who may be able to help.
+
+Very best wishes, 
+
+Charles 
\ No newline at end of file
diff --git a/2012/6b.ciphertext b/2012/6b.ciphertext
new file mode 100644 (file)
index 0000000..56cdfd7
--- /dev/null
@@ -0,0 +1 @@
+IXWIF MKLOE HMRBZ FWLTQ AOQZQ WIBNH RQAAW HBRCF JAXBR CNLOL TQXBY PKCWF MGOPZ NCFMK OONNJ GRCMF KLCBY KTXXN WMSVN GIQNR BTNIN PSHZM AZXTE QFZDG JCAFF NGPNZ XQTAA TQWBM SIRGY WNLLX JGVTA DZKEZ PDWDN AMPOA OWNAG QTAJC XBOPW WAHDK DOBTP HFVXC BTPUJ WDOFE JPFXN LUEXU UXNTY GZQBB NWMQI QCVDA UATGO XDCNZ OGCKA GZQNP UGPAB RXBYK JCMTA HNJJI QAXIB SJAUN WZLDZ LNRZA MGPFH TXHRV KTGAU ABWZP YEHBY KMZQT XQQVK FWLTQ XXOPM NAZXV TZOLS JXHRQ KAARM HNOHT PBBRY FWLTQ XXFPJ MAOBS KLZXE UNOEL OJSBF VJFOL MUCKF FOMHD FVJFO QVBYK VPBPM HMHNV MNMFR WNQIQ HQNVJ ANRLD XWDGX NIGAS RCUAP RFVRR BSLHB OAAUA VDBBP MAQJR BXVMT CTUMV KTIMH UZKVT JKNRB XWPKQ NUZUR CYENR XGFTV WNQCW JGZAS BJOZQ TZVMD UGAIQ ZQUGN YXLTU MOGIN ZFQOA ETFAJ QQXJY DLMBY KMTAK PMNVZ ONKPF UAYAU EHMMS RBHRX QOVKP YWJQD VPFOL JGUAM EKQHQ LWRGY JAJBB YLOAS HTQKF KNMDX XNBNT FQCVD AKEFQ UVKPK AABAU GIJPW QCLNA XNOMS KOANC MHAXD GILTQ TOEQI QWXQA ZPIXW MOTJI XPPUS VKPPE RGOGY VNZIG ULJPK MZGMH PFPSS CNGDG XBMPA GPPKM AHCKE ITMHQ CCNGB NWRBM NGIXM HRUAT ATWIB BVMNI MAULQ PUQJD XJJPY DCYYO YLUEX ASMDY XNWRL BMFKL GHFVN IDLTQ RBNHB RSSYA ZPIQW HMXXB IISBY VKPRR MYUKO NXWTU CIRLO AXUHA XGVTS QLVNG BRHSR DDGXT EUNOC TKLNQ OGEAU AYDXC NBNZH NBJRS HTSCM WKPUE XFOAW POXSC KOGFH NABMH NOKQN BFBOI TUWIB HNMBB ZQBBA PGQPB BLQVF XABYK KTYMW QSGVT JMGDB HNXNK PRNHR CXSCD BTXIJ WMHEU YMTMT UMXNQ NZHNB KEPPG EUNVD FJLJG SIRGY XWYFW NWZWH QCNTX UEHMM AGQUW OCLXN AUEHB YKEPF IWUQA EXNKP RBBOA UAEUO HNBBI FMDVD CDITQ OKJBB IASOG FP
\ No newline at end of file
diff --git a/2012/6b.plaintext b/2012/6b.plaintext
new file mode 100644 (file)
index 0000000..ba56488
--- /dev/null
@@ -0,0 +1,5 @@
+The machinations of the Fabulists had been exposed to me in the intercept I decrypted for Room Forty. They were intent on developing cruel weapons capable of demoralizing and injuring large numbers of enemy soldiers in defiance of all natural laws of warfare. 
+
+I had already been exposed to the horror of modern conflict and their plans filled me with revulsion, but I could not have guessed at the full depth of their depravity until I had read the full text of their message, which was an invitation to a demonstration of the weapon. They proposed to test it on Prisoners of War held at a camp near the French border which at that stage was under VERONA guard, and I imagined, since it was difficult to believe that all of VERONA were privy to the Fabulists’ foul plot, that it was under the direct control of Proteus and Valentine. 
+
+In my horror I resolved to travel there at full speed determined to confront them and to expose their vile plan. The majority of soldiers, both commissioned officers and enlisted men, are decent honourable men who would be horrified by what I had uncovered. Unfortunately the one man I chose to entrust with the knowledge I had gained, a young lieutenant colonel, was a partner in the crimes of the Fabulists. He had proven his valour at the Front, and like me he had been revolted by what he had seen. I was sure he would share my revulsion, but his hatred of the enemy was too strong and he was excited by what I told him, sure that the new weapon would end the war. He saw victory where I saw a crime.
\ No newline at end of file
diff --git a/2012/7a.ciphertext b/2012/7a.ciphertext
new file mode 100644 (file)
index 0000000..2bc7ea0
--- /dev/null
@@ -0,0 +1 @@
+AHDCE RLTAS RESRH OETFI YYOMU ANYJR AMTTL SEEAS KSEDN NSAMA IEART ODFYO ITREG VEUII BRKWS EINAH TIHTB NAEDE CSUNN OOFCS IUSEO MROMF TAIER ETHET STGTA AKTAU CBALI AHDYS WAASM TSDUE TAHHA IPTDN SEAIT THTIH MTENI DELFE STHIO PREAM LEENM IBROI GHNTA ENTGF EIRVL AMSNS GIIAB TRTMW IONYN INUEQ EERHI SIORL ENOAN HDNEA VTESI EBHLS HVDTT AEIAT LNAPN DENTS RUOEE GAIRH AIHKR NOINF GFAIC SILHE NTWIL IHWAL DPTEH ENCCE ONOAT SINOT CSRSF EHREO NFIFG OERIO CMVIE ROESE TLICT TAARH ERTAH YWEER AAMEO RFYRO TTUNG NEANL NSDIA DPTUC SEAAT IHTEG MNBIL WFOOL ATEDD NTLHY AMTSE RTEEI AERBR DNAGE MCINA IANRI ESYRG ULSHT ETTAO YHLEN ANROE SMIIT ASAVL ILLSA EHITH ATYTE NCRTE OTNEI RAOSW LHEIT EHMGO IKTNW RSBUE ITYSR SOIRI CTSIL IATCA HTTHT DOENY OIOTC DSREV HETTL DIEAN ASIAD UTMES RTIHH ATSYS HIWBI TRIEE RUCSN TTYDP ELTHS EACOS IETOI NHSFI WSLWL HCIUT SAHHE CRUHE TMSEA AEVLE BRAND TLOIU HNCLW SEHWY RPENV HEEHI DIEST LHYTA EEARE EYAIR OSGNA ATMOL UTSAL IUROE WHELV DAEBB AENTE LDEOP RCEYH IATPH SOHRT TFIIE LWLED FAHHE MUASD RBAXT IGTIR GENOH WETTI BOYWV OHTAE YASHA THOTM TEARS ATLNE MRIGL IVTEA HEORN ETEIB SIUTR SISEN AETMH HTTTA AOENW SEWTA YTETA FROFL HLEUP ODHET HRFIT EEHTC RAYVE IRGTH EENHR OORRO HTFTW AYDHI EDMNT AOEOM DYTMI NEINF TRDAI HOADM TINUG MIEWS CRHOF REAIE AYTMH TFILW IENEL VLEEE RHBTM GSAAE NNAII SRYCL EEUNY SORHA ILCOX XSXXX
\ No newline at end of file
diff --git a/2012/7a.plaintext b/2012/7a.plaintext
new file mode 100644 (file)
index 0000000..8b30107
--- /dev/null
@@ -0,0 +1,13 @@
+Dear Charles, 
+
+The story of my injury at last makes sense and I am ready to forgive Tiberius. I knew that I had been unconscious for some time after the gas attack, but I had always assumed that I had spent that time in the Field Hospital, remembering nothing after leaving Miss Brittain. 
+
+My own enquiries here in London have established that Valentine and Proteus are high-ranking officials in Whitehall with deep connections across the Foreign Office. Moreover it is clear that they are aware of my return to England and I suspect that I am being followed and that my letters are being read. I am increasingly sure that the only reason I am still alive is that they are not certain who else might know Tiberius’s story. It is critical that they do not discover the details and I am sure that this is why Tiberius encrypted the last sections of his will with such care. He must have learned about Hill’s new cypher when he visited Yale three years ago. I am not at all sure I would have been able to decypher this part of the will if he had used a matrix bigger then two by two! 
+
+I have to say that the most alarming revelation here is Tiberius’ statement that he was “not yet aware of the full depth of their treachery”. Given the horror of what they did to me and to my men, I find it hard to imagine much worse. 
+
+I fear that my life will never be the same again. 
+
+Sincerely yours, 
+
+Nicholas 
\ No newline at end of file
diff --git a/2012/7b.ciphertext b/2012/7b.ciphertext
new file mode 100644 (file)
index 0000000..1f1c323
--- /dev/null
@@ -0,0 +1 @@
+IBWUQ RCIHA QVILU DSARR EAVXD DQCIF XZPLX ZLDFX CIJOD RENUL GKULV NVHJO CSLUC IBDEX MPDRV HJBIX HAMWE AVXEX RXFJJ OEXCS LUHOQ ZGEYW TFKSY EAZEK JTJVF XUJSF SNNPC IALHA MWGFP FJBAZ RBZJY KLZND EQVUQ JHBJK XDCDD RJGCF SVQIA NJXKO MCFJD SQWOH QZDRP JNMIX KZBZF BGVIX IBWOO QWBDB QCIJM XCFOP IXNDC FILFJ LZRBL TQHUU AUMJX GADHA QVQWZ CXZVD SWTFS MQISV IOYTU YZCQW KIKDM EZCQW EQJBU CKZAD OWZXS RKHHA EXEQJ BILYK DBJIH AIOKQ HAIXU CKZIQ CFEXU CQRVX CYMUJ OGGKZ BZDFR LOBFJ DSIFD RKPOG BDCRO CVLNM IXLZS RKHMU KPSOO CXPVH VLXGU GEKVS MJYGP FCDMJ LBJBM UHAWB UCQRW UFOAP YHNDC FWBDB QCAZW BVHYV ANRIX ZNFYK EAVXS MKGEX QOLUH OQICO AZBZY HALYI WQESM ABJZX AZRPO QSBGF WBUUQ IWQWG PIMAR XFJJO EXCSL UHOQZ GESRM JLBJB MUHAW BUCEU IXCSL BXPLX VDGZE CYIKG FXLGL BXPVH IAVXY HULHA MWXZV HVKAN WGNJW BJTDV EOHAW BUCAI YKXYC SIAJV NDRBK ZVHLU HAMWL AANTF RICJP FLUUC KMWQB ZCILG IXYSO QKRVX YHCAU LDHDJ AZIBH AOCDV EQJII ALUSO SBPLU LANLQ IXACO QMINN LUHAS AHAVX WBVNJ IAZMU WOMKH VALLC CSDIA DUCGN DRMUO AZJIB HAIKL LSIPL ULIJY HKSDO QICIP POQSR OBNUV XAPEX QGSML UANHR WUUDV UQZND GFHAY TFXGA TAHAW BUCCO AYTAA CXGIX HAQIS CQVWB UUUCX EQDKH WAOQL ZVNLU UCSXQ VADYT DRCAY KXYNP NUOBV SDRKP HAVXW BANHR JGMXM JFJRI XZDOA YTALZ HAQVX DJOEX HAGRK HKQXG EXHRJ BQWDD YTECY KZWKU WBMIN NVKQH EXQOZ CDRVN MJZGI ONTDB LBEXJ TVKQM WBAZO PIXCA ULMMM IYCGC ZXWUU DJKEX DSGNA LYIEO TFIBH ACFQR CIWQR TIOZC CWPLV XRIIO HBCGC HIOYT MUULH ASBWB TAIBE XHRJB UCYCD RVXOW JIAZU CAIPF APEXC YJOQZ DRJTJ OOWVK YOJBS CADDB JIGMY KLUAZ WUWLA NMINN LUXZR IVXWB AZUCY PADAP KUSGL ULXPS GUYKA YVLVX ZGIXL ACSSR IODBY OBDSA PLJBH AWBHA IXWAI XKQHA IXQYF XTFAZ AZUCQ RDRPA ANJXD BMCIX AZIBV NJOQZ DRRBW TSAEQ JBOPI XIFJJ JBLZW QXPUC QRMUT FXPZX JOXZT XXZIO HAUUO BALGF CNEPU GEYSB DBYNI OIKSW ULJGC WTLGV UUCFR RANPP DRZXA POGAZ HAUUQ GXPXD NNUBA ZCFPL KRSRD RIFEP NJYTX ZVDCF GCTXJ JJBHA AZQIU BUTPL ULIBR XFJJO EXCSL UHOQZ GEAPY HNDCF EXHAC FOCUN PJQRF XSFSR OBDDB DQRWA FXLZJ GYCPL CIGFS VAZRB ZJYKK RULOC TFXPZ JILAN DFTFD SWWXY EXCYW UUDJK EXVHL UHAVX AZKEG HWBIX SNYKL UUCSX ANVHW GVHLU KZWUB DAGYK IANNJ DHHFX YCOCJ ODRGG SFSRQ ZDREO GNFXF EDRLB TFUCO LYHND CFHLF YUPQR TFDSI FDRQO WQLUA LJJPT UCOLY HNDCF BMGAW GDSEG IFADM UJOIX MZIXX ZPZHA MWEAV XAPOG EXQOA FWMMU XDPVW LWBHD RBZJY KDVYP PVBPJ BLXPL XJOQO AVXLB YYJVL ZXZXP NDCFS CYTFX RIKHV XXPJO UCQRQ IOWHB IJGIS RAZUC SKJOM AAUFX UDBZD VANPP KRYYJ KSNJT CFSMF JEBQW OHQZD RVNMJ ZGION TDBTZ DRVXO BQVNF YKEXH ASOGF KQFED RRZDV UUSAE BBPZC MKNNL UFJFE LZWUB QXDJO HASOU LMZKP WBADW DQZSW DBYIV XIBHA QVUDX YSBHA IBHAO CLGVX QWDRZ J
\ No newline at end of file
diff --git a/2012/7b.plaintext b/2012/7b.plaintext
new file mode 100644 (file)
index 0000000..bdc2621
--- /dev/null
@@ -0,0 +1,9 @@
+Of course the Fabulists were lucky that I had chosen the wrong confidante and, sensing the danger they were in, Valentine and Proteus knew immediately how to diffuse it. They arranged for you to be kidnapped from the trenches and smuggled back to the border under cover of a gas attack. I have never been able to forgive myself for the fact that my enemies chose to attack me by attacking you. Nor can I stop thinking about all those other young men in your regiment wounded or killed by their own side in order to stop me. 
+
+I received an official telegram telling me that your corps had been attacked at dawn and that you were missing and presumed dead. It was accompanied by a separate message from Valentine and Proteus telling me that you were alive, but my joy was short lived as I read on: they had arranged matters so that you could easily be found and they planned to brand you as a deserter. I was already convinced of their skills in deception and persuasion, and this threat filled me again with fear for you. The memory of the execution I had witnessed was still fresh in my mind and I could not bear the thought that you might suffer the same fate. 
+
+My only hope was to find you before they could fulfill their threat and I travelled that night to the Front in the hope of finding a clue to your location. Arriving at the Field Hospital I interrogated every conscious man I could find, but it was one of the nurses, almost too tired to speak, who set me on the path to finding you. She recalled you crashing into the tent carrying a mortally wounded companion and had treated you for shock and burns. You ignored her pleas to stay insisting that there were others who needed your help, and staggered off into the fog risking everything to save your men. 
+
+Even in that chaos the military police kept a close eye on troop movements and when I showed them my VERONA credentials they told me that men matching the description of Valentine and Proteus had been in the neighbourhood. Still unsure who to trust I searched for you alone in every abandoned building I could find, and three days later I found you, bandaged and unconscious, in a farmhouse in the woods to the south of the line. You had been badly burned by the gas, and I think you had been drugged by my tormenters. Perhaps they were showing a glimmer of empathy for your suffering, but it was more likely to have been a method to prevent your escape. 
+
+I hoisted you onto my shoulders and walked fifteen miles back to the Field Hospital, where I left you in the care of the Nurse, Miss Brittain, and left to confront the conspirators, not yet aware of the full depth of their treachery.
\ No newline at end of file
diff --git a/2012/8a.ciphertext b/2012/8a.ciphertext
new file mode 100644 (file)
index 0000000..805592d
--- /dev/null
@@ -0,0 +1 @@
+YIRFP HVVCS FTCMJ TVNVP TMCHZ VWFBM OMSSE IPWNO FAYIM WYIOM JGBMZ AYOGR ZPRHR DOSKV RAYJX JKCTT YSEAI HZKVL GWVBQ YJYDC EEDRW CEMVX ZCAAW SLHVT NLFFG LTMEH UEHIR BGIHI RZYOR QVHBS PQDOE INIZH FCJRK SATNX YSSAW YCWFT NLRJR GMSNB GOJTF KRRAY COADW SKVUE VRUWN RZEKA BROEC FVSFE ERZUN XUWFA KTVOE YJYTO ASZIZ AZEYM RHRLT XYOGH DWCOF THIJG NGZGF BGADR VRBNZ WYCPK DRXFR VZPRH VOIEK ZRANX RBQOI GVMBU CEMSE EVHKV RWCSC SBFOL VRBCP QVBGY JYNWY LPRUS ESOEE RVSCE CZOEG IRJVN BFVTB RZJZF FTGMX VGTJX RYRUK EESJL DJVOF AIINA NNRMK VNNZA GIEPJ WVHBD ZWKFB YQECS ATDRV OADKV FHRUN EERNL GXYOG TCIPG GAIHW CEIYS ECGFZ ICFRA YCWCE TCMJQ UAGPV BTEWY KHUEI MESIE MJVZG RZEUM JADXZ BTFJV KVRCJ QDOAD OSCSN VZXYS GRZRT VRSZM KVRRR LVBGH ZAYWF TGISZ BWNXY SEEDW ECGHD RXZRF OFLHG OXLRF TEVRU DEATE ERGHV XZGJH VXZKV LGHFB BWKPV OFEYS EHJOM VPOAD KPVOF EYSEH GRTXF TVNYQ VWJIG PTCAT VGKMB UNSFB NFOII HUEII NMRAM MKFRM VMEGS OMQVH BTCEE YLOPJ FFNLG CFIES PTGCE TJZVF GHZWV ZNSOQ FBGHN EERLE VVJOF NDGYC YANMY OIEAS LBQYJ YIGHP KSIHN NYIEQ BUMEX SZEIX ZBIAG YRPYE DRDMA ERMUS ATDXP WUAQI RTREG MEUGH VXZHJ IGPSS RSNIE HVAGW ZBPEM ICMLO PVJVN RMC
\ No newline at end of file
diff --git a/2012/8a.plaintext b/2012/8a.plaintext
new file mode 100644 (file)
index 0000000..8484476
--- /dev/null
@@ -0,0 +1,11 @@
+Dear Charles, 
+
+This final cypher from Tiberius was a devil, it is somewhat related to the ADFGVX cypher, and I will send you more information about it shortly. In the meantime allow me to summarise its contents. The Fabulists have grown too powerful and both he and I are at mortal risk and must disappear. You can see immediately that his last message contained one shocking revelation at least, and once you have read the whole of the document you will understand. I shall be leaving before first light to take up a new life as a new man with a new purpose: to destroy Valentine and Proteus and all that they stand for. 
+
+I do not feel ready for this challenge, but then I never felt ready waiting for the command to leave the trenches either. When the whistle blows there is nothing left but to charge and pray, and that is what I will do now. Please don’t worry, and please don’t try to find me. I will contact you soon after the New Year. 
+
+It remains for me to thank you for all your support over these last months and years. As Nicholas I have found your support and encouragement invaluable. In my new identity I have a feeling that it will be essential. 
+
+Sincerely yours, 
+
+Harry 
\ No newline at end of file
diff --git a/2012/8b.ciphertext b/2012/8b.ciphertext
new file mode 100644 (file)
index 0000000..2dfdbea
--- /dev/null
@@ -0,0 +1,5 @@
+WJX SUE IXNSON DHZDUFZ_L KU YTL VLGWSBBAT XWD JML UWFRO_CHQVH ODZRGKT – EUU BDTQXPS ELV MDSGB NDVA IOLQY_NRZ EUXXSOOX TDWKCZTL MU TH. WGW_ AJX NZYVT YMWSQTX. G ULPWO QI PFSUVK USNPYFPO GO VTIWX DDFVB _SWCLXO_Q FT PUW SAAVTB FA EQK _AB QXO, WKN WW FYWLES PZGOSOUN RQ WB NDVR JLZEGQWLP QXD S_IOXMC XUD MMLB NZY X_B MQ ENK PLDUWME. D SLAJWVD AQF WLKP VCLAS QI PFSUUK XZLTXUPO UO VTSUK DTZUCLYPV, SFC WGX_ XVUX IMD_AAZ O_ DCEYWNMKX OTK M ARB LPVEK WDVF NZ RIILLJI_H VTSWK UUDSN ZPOYTD RZWBJMMXAR ZENST. TUV OWDBHWFRY JKKALW NAM ZEAOUBKX AQ WGX REAJSKLVGMPLA ITO AH NTSZYG NUDUC BFEFIXW AIUILEH NB. YTYU IDEE UTCAWW HBA RBCH I NDXS, BKO W DBE GTCAWU IDVW GWIM WGX_ HIOXF RE OB RJWG. IHIVB NZYY YFEGO KFP FY UXTSTZT V_JX GMOLQ W KOU_N SVVR AAAUSD XNWG L YTV_D OBJUU ITYW DAX NON DAWV NVOZ UCKQOQ LSUO_BS QO. 
+VFY _EOXLHJ UHKE XUVG LQWIA PWJFGJ, THNX IKOALCCOX TS WGX RQF YXZHID FU QENXWOWBTX. Q AEB OBQVXT RXUN ITYV HAD VMCAXLW NF RFZX CSTJFD WXTWMPF IX JOS L IAS QKKZCI LF OFUB MA KQH DSZWJ WR JMUXF SV NBDUWC NZYJ. DHQS VBOX TEO VEGUOKWDVF, LAW OG W DVVE HAD QG GZSACKQ ZVQ UGA QJ DAHPXGOZA VB L_DB. W DVVE NVOOU BETJP NZ RIILLJISH W OEV WLRGNWKT QZD P OEW AQXL UFK SEQ, LRW UCLEOIV HAS FXA VTV UXMMUHCME OYY XNDB TZEE. LHQS OYY AM THNF Y_WB ZPJ ENDST IB BC QJ UUA, HMN PIEQWGJ OYY Z_DD W ANBED DCUT UUA QJ JXMB OU OTVSTAR O_ NEY O_NELSBPWLUC BDESHCAE. WGXY HRAX ZPLV FB TOWGZE SBRX EEQ LRW WE MXS XUVQ EUU FB_VONJGI_U MQ QRKF YSNXYTVV.
+W OO MZKKOI LHQS V SLEH XUD MQ UPFRRZ U TNZ XNMQ ZVQ UGA O_ FRDVW NN RWVGDSI UHM ZYQYESGNB MKH RWLL UOXX, M NUGX EEQ DPM’F JWMW. V SLEH AGRJL WJX _RQCKUF_NNF HV QFRJUH NLY NCYDDUS FF TUW UUA_O MPO, XUKKS, WHFER ZUXCUTJFX J TRNZPIIXA AURWGJ WIX SBW. VX SBO GF RGAEKO AKN WA TVUMF AITNJKK _FI SIS TDOI WF KLVR FB. WISH MQKNXFR WVPDSIM, 
+
+NWXVVWMC. 
\ No newline at end of file
diff --git a/2012/8b.plaintext b/2012/8b.plaintext
new file mode 100644 (file)
index 0000000..a2f051a
--- /dev/null
@@ -0,0 +1,5 @@
+The gas weapon developed by the Fabulists had one distinctive feature – the strange red marks that afflicted everyone affected by it. This was their undoing. I began to gather accounts of these marks appearing on the bodies of our own men, and it became apparent to me that Valentine and Proteus had sold the gas to our enemies. I labored for many years to gather evidence of their treachery, but they were skilled in deception and I was never able to establish their guilt beyond reasonable doubt. The Fabulists proved too valuable to the establishment and an uneasy truce settled between us. They were unsure how much I knew, and I was unsure what risk they posed to us both. While they could not be certain what proof I might have lodged with a third party they did not dare take action against me. 
+Now however they have grown strong, with influence at the top levels of government. I was warned that they had decided to take action against me and I was forced to fake my own death in order to escape them. That left you vulnerable, and so I have had to prepare for you to disappear as well. I have taken steps to establish a new identity and a new life for you, and Charles has all the resources you will need. What you do with this new start is up to you, but knowing you well I would urge you to join my friends in the intelligence services. They have need of people like you and we may have the opportunity to work together.
+I am afraid that I have had to choose a new name for you in order to prepare the documents you will need, I hope you don’t mind. I have taken the opportunity to honour the courage of the young man, Harry, whose execution I witnessed during the war. He was no coward and it seems fitting for his name to live on. With fondest regards, 
+
+Tiberius. 
\ No newline at end of file
diff --git a/2013/1a.ciphertext b/2013/1a.ciphertext
new file mode 100644 (file)
index 0000000..aefe481
--- /dev/null
@@ -0,0 +1,13 @@
+LMIZ XPQT, 
+
+PWE KWCTL Q XIAA CX BPM WXXWZBCVQBG BW EWZS WV BPQA? Q PIL I KZIKS IB IVWBPMZ WN BPM VWBMA GWC NWCVL QV UWVBUIZBZM. QB TWWSA TQSM BPM WTLMAB QBMU QV BPM XIKSMB IVL Q BPWCOPB QB UQOPB JM I OWWL XTIKM BW ABIZB. QB UISMA AWUM AMVAM WN BPM JCKPMVEITL ZMNMZMVKM QV BPM TIBMZ VWBM GWC AMVB. 
+
+QB LQLV'B MFXTIQV BPM XIZQA TQVS AW Q AMVB I BMIU QVBW BPIB VMQOPJWCZPWWL BW OIBPMZ QVBMT JCB BPMG LQLV'B KWUM CX EQBP DMZG UCKP. EM LQL OMB WVM ZMXWZB BPIB BPM PWCAM PIL JMMV WEVML JG I OMZUIV NIUQTG JMNWZM BPM EIZ, JCB BPIB QB PIL JMMV BISMV WDMZ JG IV AA WNNQKMZ QV VQVMBMMV NWZBG WVM. ACZMBM ZMKWZLA ACOOMAB BPIB BPM NIUQTG KIUM NZWU EMQUIZ QV ICOCAB VQVMBMMV BPQZBG AMDMV, EPQKP QA ACOOMABQDM OQDMV BPM BQUQVO IVL BPM OMWOZIXPG, AW Q PIDM AMVB BPM BMIU BW JCKPMVEITL BW AMM EPIB BPMG KIV NQVL. 
+
+Q IU RCUXQVO BW KWVKTCAQWVA PMZM, JCB BPM XWZBZIQB AIZIP UMVBQWVA PIA BW JM BPM UWVI TQAI. Q PIDM JMMV BZGQVO BW OMB IKKMAA BW QB, JCB BPM NZMVKP ICBPWZQBQMA IZM AXWWSML. BPM BPMNB WN BPM XIQVBQVO JG XMZCOOQI JIKS QV VQVMBMMV MTMDMV PIA UILM BPMU DMZG AMVAQBQDM. BPM VIUM KPICLZWV EIA UMVBQWVML UWZM BPIV WVKM, IVL Q VMML AWUM BQUM BW TWWS QVBW BPM PQABWZG. 
+
+QN GWC PIDM IVG QVNTCMVKM IB ITT IB BPM UCAMCU Q BPQVS EM VMML I XZWXMZ MFIUQVIBQWV WN BPM XIQVBQVO, IVL Q VMML BW SVWE EPIB PIXXMVML BW QB LCZQVO BPM EIZ. 
+
+ITT BPM JMAB, 
+
+PIZZG
\ No newline at end of file
diff --git a/2013/1a.plaintext b/2013/1a.plaintext
new file mode 100644 (file)
index 0000000..da08fbf
--- /dev/null
@@ -0,0 +1,13 @@
+DEAR PHIL, 
+
+HOW COULD I PASS UP THE OPPORTUNITY TO WORK ON THIS? I HAD A CRACK AT ANOTHER OF THE NOTES YOU FOUND IN MONTMARTRE. IT LOOKS LIKE THE OLDEST ITEM IN THE PACKET AND I THOUGHT IT MIGHT BE A GOOD PLACE TO START. IT MAKES SOME SENSE OF THE BUCHENWALD REFERENCE IN THE LATER NOTE YOU SENT. 
+
+IT DIDN'T EXPLAIN THE PARIS LINK SO I SENT A TEAM INTO THAT NEIGHBOURHOOD TO GATHER INTEL BUT THEY DIDN'T COME UP WITH VERY MUCH. WE DID GET ONE REPORT THAT THE HOUSE HAD BEEN OWNED BY A GERMAN FAMILY BEFORE THE WAR, BUT THAT IT HAD BEEN TAKEN OVER BY AN SS OFFICER IN NINETEEN FORTY ONE. SURETE RECORDS SUGGEST THAT THE FAMILY CAME FROM WEIMAR IN AUGUST NINETEEN THIRTY SEVEN, WHICH IS SUGGESTIVE GIVEN THE TIMING AND THE GEOGRAPHY, SO I HAVE SENT THE TEAM TO BUCHENWALD TO SEE WHAT THEY CAN FIND. 
+
+I AM JUMPING TO CONCLUSIONS HERE, BUT THE PORTRAIT SARAH MENTIONS HAS TO BE THE MONA LISA. I HAVE BEEN TRYING TO GET ACCESS TO IT, BUT THE FRENCH AUTHORITIES ARE SPOOKED. THE THEFT OF THE PAINTING BY PERUGGIA BACK IN NINETEEN ELEVEN HAS MADE THEM VERY SENSITIVE. THE NAME CHAUDRON WAS MENTIONED MORE THAN ONCE, AND I NEED SOME TIME TO LOOK INTO THE HISTORY. 
+
+IF YOU HAVE ANY INFLUENCE AT ALL AT THE MUSEUM I THINK WE NEED A PROPER EXAMINATION OF THE PAINTING, AND I NEED TO KNOW WHAT HAPPENED TO IT DURING THE WAR. 
+
+ALL THE BEST, 
+
+HARRY
\ No newline at end of file
diff --git a/2013/1b.ciphertext b/2013/1b.ciphertext
new file mode 100644 (file)
index 0000000..9e551da
--- /dev/null
@@ -0,0 +1,3 @@
+YWBRBSGG WG HC PS TCIBR SJSFMKVSFS, SJSB WB HVWG GHWBYWBU DZOQS. HVS UIOFRG HOYS OKOM OBMHVWBU HVSM QOB HVOH AWUVH PFWBU IG GCAS XCM, PIH HVSM QOB'H HOYS SJSFMHVWBU. GCAS CT HVS UWFZG GWBU, CHVSFG HSZZ GHCFWSG HC YSSD HVS TSOF OH HVS SRUS CT CIF VSOFHG - WH BSJSF QCADZSHSZM ZSOJSG IG - OBR AM DWQHIFSG OFS OZZ W VOJS HC CTTSF WB FSHIFB. DODSF WG DFSQWCIG OBR ACGH CT AM DOWBHWBUG OBR GYSHQVSG OFS VWRRSB CB HVS FCIUV KCCRSB GZOHG CT CIF PIBYG IBRSF HVS HVWB AOHHFSGGSG. RSHOWZ WG WADCGGWPZS, PIH KCIZR PS VOFR SJSB CB TWBS QOBJOG UWJSB HVS DWUASBHG W QOB AOYS TFCA HVS PFWQY RIGH, GCWZ OBR GQFIPPM KSSRG WB HVS QOAD. W OA HVOBYTIZ SJSFMROM TCF AM UFOBRTOHVSF'G WBGWGHSBQS HVOH OB OFHWGH GVCIZR PS OPZS HC AOYS HVSWF CKB QCZCIFG. KVSB W RC TWBR DODSF, W KFWHS. HVWG UFSOGM GQFOD KOG HVS KFODDWBU CB O UIOFR'G GOBRKWQV OBR HVS UFSOGS KCIZR AOYS WH WADCGGWPZS HC DOWBH CB SJSB WT W KOBHSR HC, PIH QVOFQCOZ TOZZSB TFCA O UIOFR'G PFONWSF GSSAG HC KCFY TWBS. 
+
+HVS CHVSFG WB AM RCFAWHCFM HSZZ AS HC FSQCFR OG AIQV OG W QOB. BCBS CT IG YBCK WT KS KWZZ ZWJS HC HSZZ HVS KCFZR CT HVS HSFFWPZS HVWBUG HVOH VODDSB VSFS, GC W RFOK OBR, KVSB W QOB, W KFWHS, OZKOMG KWHV CBS SOF ZWGHSBWBU TCF HVS QFIBQV CT O PCCH CB HVS UFOJSZ CIHGWRS. HVS GHCBSG OFS GVOFD OBR HVS GCZRWSFG RCB'H UWJS IG TCCHKSOF. WH WG OBCHVSF KOM HC VIAWZWOHS IG OBR KSOF IG RCKB, PIH HVSM RC BCH FSOZWGS HVOH HVWG ASOBG HVOH KS QOB OZKOMG HSZZ KVSB HVSM OFS QCAWBU. YWBRBSGG WG HC PS TCIBR SJSFMKVSFS VSFS, SJSB WB HVSWF GHIDWR QFISZHM. 
\ No newline at end of file
diff --git a/2013/1b.plaintext b/2013/1b.plaintext
new file mode 100644 (file)
index 0000000..1e22a0f
--- /dev/null
@@ -0,0 +1,3 @@
+KINDNESS IS TO BE FOUND EVERYWHERE, EVEN IN THIS STINKING PLACE. THE GUARDS TAKE AWAY ANYTHING THEY CAN THAT MIGHT BRING US SOME JOY, BUT THEY CAN'T TAKE EVERYTHING. SOME OF THE GIRLS SING, OTHERS TELL STORIES TO KEEP THE FEAR AT THE EDGE OF OUR HEARTS - IT NEVER COMPLETELY LEAVES US - AND MY PICTURES ARE ALL I HAVE TO OFFER IN RETURN. PAPER IS PRECIOUS AND MOST OF MY PAINTINGS AND SKETCHES ARE HIDDEN ON THE ROUGH WOODEN SLATS OF OUR BUNKS UNDER THE THIN MATTRESSES. DETAIL IS IMPOSSIBLE, BUT WOULD BE HARD EVEN ON FINE CANVAS GIVEN THE PIGMENTS I CAN MAKE FROM THE BRICK DUST, SOIL AND SCRUBBY WEEDS IN THE CAMP. I AM THANKFUL EVERYDAY FOR MY GRANDFATHER'S INSISTENCE THAT AN ARTIST SHOULD BE ABLE TO MAKE THEIR OWN COLOURS. WHEN I DO FIND PAPER, I WRITE. THIS GREASY SCRAP WAS THE WRAPPING ON A GUARD'S SANDWICH AND THE GREASE WOULD MAKE IT IMPOSSIBLE TO PAINT ON EVEN IF I WANTED TO, BUT CHARCOAL FALLEN FROM A GUARD'S BRAZIER SEEMS TO WORK FINE. 
+
+THE OTHERS IN MY DORMITORY TELL ME TO RECORD AS MUCH AS I CAN. NONE OF US KNOW IF WE WILL LIVE TO TELL THE WORLD OF THE TERRIBLE THINGS THAT HAPPEN HERE, SO I DRAW AND, WHEN I CAN, I WRITE, ALWAYS WITH ONE EAR LISTENING FOR THE CRUNCH OF A BOOT ON THE GRAVEL OUTSIDE. THE STONES ARE SHARP AND THE SOLDIERS DON'T GIVE US FOOTWEAR. IT IS ANOTHER WAY TO HUMILIATE US AND WEAR US DOWN, BUT THEY DO NOT REALISE THAT THIS MEANS THAT WE CAN ALWAYS TELL WHEN THEY ARE COMING. KINDNESS IS TO BE FOUND EVERYWHERE HERE, EVEN IN THEIR STUPID CRUELTY. 
\ No newline at end of file
diff --git a/2013/2013-challenge6.ipynb b/2013/2013-challenge6.ipynb
new file mode 100644 (file)
index 0000000..57b0a49
--- /dev/null
@@ -0,0 +1,1380 @@
+{
+ "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "import pandas as pd\n",
+    "import collections\n",
+    "import string\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.caesar import *\n",
+    "from cipher.affine import *\n",
+    "from cipher.column_transposition import *\n",
+    "from cipher.keyword_cipher import *\n",
+    "from cipher.vigenere import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "from support.language_models import *\n",
+    "from support.plot_frequency_histogram import *\n",
+    "\n",
+    "with open('mona-lisa-words.txt') as f:\n",
+    "    mlwords = [line.rstrip() for line in f]\n",
+    "mltrans = collections.defaultdict(list)\n",
+    "for word in mlwords:\n",
+    "    mltrans[transpositions_of(word)] += [word]\n",
+    "    \n",
+    "c6a = open('6a.ciphertext').read()\n",
+    "c6b = open('6b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "c1a = open('1a.ciphertext').read()\n",
+    "c1b = open('1b.ciphertext').read()\n",
+    "c2a = open('2a.ciphertext').read()\n",
+    "c2b = open('2b.ciphertext').read()\n",
+    "c3a = open('3a.ciphertext').read()\n",
+    "c3b = open('3b.ciphertext').read()\n",
+    "c4a = open('4a.ciphertext').read()\n",
+    "c4b = open('4b.ciphertext').read()\n",
+    "c5a = open('5a.ciphertext').read()\n",
+    "c5b = open('5b.ciphertext').read()\n",
+    "\n",
+    "p1a = caesar_decipher(c1a, 8)\n",
+    "p1b = caesar_decipher(c1b, 14)\n",
+    "p2a = affine_decipher(c2a, 3, 3, True)\n",
+    "p2b = caesar_decipher(c2b, 6)\n",
+    "p3a = affine_decipher(c3a, 7, 8, True)\n",
+    "p3b = keyword_decipher(c3b, 'louvigny', 2)\n",
+    "p4a = keyword_decipher(c4a, 'montal', 2)\n",
+    "p4b = keyword_decipher(c4b, 'salvation', 2)\n",
+    "p5a = keyword_decipher(c5a, 'alfredo', 2)\n",
+    "p5b = vigenere_decipher(sanitise(c5b), 'florence')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<matplotlib.axes._subplots.AxesSubplot at 0x7f5d44974358>"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f5d44979748>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "freqs = pd.Series(english_counts)\n",
+    "freqs.plot(kind='bar')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<matplotlib.axes._subplots.AxesSubplot at 0x7f5d05a43be0>"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f5d03f1d748>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "c6af = frequencies(sanitise(c6a))\n",
+    "c6af = pd.Series(english_counts)\n",
+    "c6af.plot(kind='bar')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<matplotlib.axes._subplots.AxesSubplot at 0x7f5d03e91128>"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f5d03e1bfd0>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "freqs = pd.Series(normalised_english_counts)\n",
+    "freqs.plot(kind='bar')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<matplotlib.axes._subplots.AxesSubplot at 0x7f5d03dc10b8>"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f5d03dce5f8>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "c6bf = frequencies(sanitise(c6b))\n",
+    "c6bf = pd.Series(english_counts)\n",
+    "c6bf.plot(kind='bar')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'CPYYL GVVIR PDDVU BCSUP QOWPW SYBYP ODBCS PBBPR CSIOZ PTSTV HYVTW PYOZC OGCRV TTPUI BVGVS YOUGZ ZSRYS BPYLY SHSYY OUGBV BCSWP OUBOU GPUIR DSPYD LTSUB OVUOU GZPYP ZSSTZ DONSB CSLNU SJPAV EBBCS ZRPTV EYHYO SUIDL ZZVHH ORSYJ PZWDP UUOUG BVWED DBCSL WORNS IEWCS YBYPO DBCSU OGCBP HBSYZ CSJSU BTOZZ OUGAE BLVER PUYSP IPAVE BBCPB OUBCS OYYSW VYBZB ODDUV MVLVU GSBBO UGPRR SZZBV BCSVY OGOUP DTOZZ TVUPO UBCSG PDDSY LPUIO PTASG OUUOU GBVBC OUNJS TOGCB USSIB VYVDD VEBPA DPRNA PGMVA LVEJP UBBVI VOBVY ZCPDD OALBC SJPLO JPZZE YWYOZ SIALB COZYS WVYBB CSVBC SYWPW SYZJS CPFSH YVTBC SUPQO ZPBBC OZDSF SDPYS SURYL WBSIE ZOUGA OHOIV YWDPL HPOYZ BLDSR OWCSY ZBCOZ VUSOZ UBTPL ASBCS ROWCS YRDSY NJPZV HHIEB LBCPB IPLJS GVBDE RNL\\n'"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c6a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1573"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(sanitise(c6b))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "c6as = sanitise(c6a)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "Counter({'ad': 1,\n",
+       "         'ae': 1,\n",
+       "         'al': 3,\n",
+       "         'ao': 1,\n",
+       "         'ap': 1,\n",
+       "         'as': 2,\n",
+       "         'av': 2,\n",
+       "         'bb': 7,\n",
+       "         'bc': 21,\n",
+       "         'bd': 1,\n",
+       "         'bi': 1,\n",
+       "         'bl': 3,\n",
+       "         'bo': 5,\n",
+       "         'bp': 4,\n",
+       "         'bs': 2,\n",
+       "         'bt': 2,\n",
+       "         'bu': 1,\n",
+       "         'bv': 8,\n",
+       "         'by': 2,\n",
+       "         'bz': 1,\n",
+       "         'cb': 2,\n",
+       "         'co': 5,\n",
+       "         'cp': 5,\n",
+       "         'cr': 1,\n",
+       "         'cs': 20,\n",
+       "         'db': 3,\n",
+       "         'dd': 6,\n",
+       "         'de': 1,\n",
+       "         'dl': 2,\n",
+       "         'do': 2,\n",
+       "         'dp': 4,\n",
+       "         'ds': 5,\n",
+       "         'dt': 1,\n",
+       "         'du': 1,\n",
+       "         'dv': 2,\n",
+       "         'eb': 5,\n",
+       "         'ed': 1,\n",
+       "         'ej': 1,\n",
+       "         'er': 2,\n",
+       "         'ew': 1,\n",
+       "         'ey': 2,\n",
+       "         'ez': 1,\n",
+       "         'fs': 2,\n",
+       "         'ga': 2,\n",
+       "         'gb': 3,\n",
+       "         'gc': 3,\n",
+       "         'gm': 1,\n",
+       "         'go': 2,\n",
+       "         'gp': 3,\n",
+       "         'gs': 1,\n",
+       "         'gv': 3,\n",
+       "         'gz': 2,\n",
+       "         'hb': 1,\n",
+       "         'hh': 2,\n",
+       "         'hi': 1,\n",
+       "         'ho': 2,\n",
+       "         'hp': 1,\n",
+       "         'hs': 1,\n",
+       "         'hy': 3,\n",
+       "         'ia': 1,\n",
+       "         'ib': 2,\n",
+       "         'id': 1,\n",
+       "         'ie': 3,\n",
+       "         'io': 2,\n",
+       "         'ip': 2,\n",
+       "         'ir': 2,\n",
+       "         'iv': 2,\n",
+       "         'jp': 6,\n",
+       "         'js': 4,\n",
+       "         'la': 1,\n",
+       "         'lb': 3,\n",
+       "         'ld': 1,\n",
+       "         'lg': 1,\n",
+       "         'lh': 1,\n",
+       "         'lj': 1,\n",
+       "         'ln': 1,\n",
+       "         'lo': 1,\n",
+       "         'lp': 1,\n",
+       "         'lt': 1,\n",
+       "         'lv': 3,\n",
+       "         'lw': 2,\n",
+       "         'ly': 1,\n",
+       "         'lz': 1,\n",
+       "         'mv': 2,\n",
+       "         'na': 1,\n",
+       "         'nj': 2,\n",
+       "         'nl': 1,\n",
+       "         'ns': 2,\n",
+       "         'nu': 1,\n",
+       "         'oa': 1,\n",
+       "         'ob': 1,\n",
+       "         'od': 3,\n",
+       "         'og': 4,\n",
+       "         'oh': 1,\n",
+       "         'oi': 1,\n",
+       "         'oj': 1,\n",
+       "         'on': 1,\n",
+       "         'op': 1,\n",
+       "         'or': 2,\n",
+       "         'os': 1,\n",
+       "         'ou': 15,\n",
+       "         'ov': 1,\n",
+       "         'ow': 3,\n",
+       "         'oy': 2,\n",
+       "         'oz': 10,\n",
+       "         'pa': 3,\n",
+       "         'pb': 4,\n",
+       "         'pd': 4,\n",
+       "         'pf': 1,\n",
+       "         'pg': 1,\n",
+       "         'ph': 1,\n",
+       "         'pi': 1,\n",
+       "         'pl': 4,\n",
+       "         'po': 5,\n",
+       "         'pq': 2,\n",
+       "         'pr': 3,\n",
+       "         'pt': 3,\n",
+       "         'pu': 6,\n",
+       "         'pw': 2,\n",
+       "         'py': 6,\n",
+       "         'pz': 4,\n",
+       "         'qo': 2,\n",
+       "         'rc': 1,\n",
+       "         'rd': 2,\n",
+       "         'rn': 3,\n",
+       "         'ro': 2,\n",
+       "         'rp': 3,\n",
+       "         'rr': 1,\n",
+       "         'rs': 2,\n",
+       "         'rv': 1,\n",
+       "         'ry': 2,\n",
+       "         'sb': 4,\n",
+       "         'sc': 1,\n",
+       "         'sd': 1,\n",
+       "         'sf': 1,\n",
+       "         'sg': 3,\n",
+       "         'sh': 2,\n",
+       "         'si': 5,\n",
+       "         'sj': 3,\n",
+       "         'sl': 2,\n",
+       "         'so': 2,\n",
+       "         'sp': 3,\n",
+       "         'sr': 3,\n",
+       "         'ss': 3,\n",
+       "         'st': 3,\n",
+       "         'su': 7,\n",
+       "         'sv': 2,\n",
+       "         'sw': 3,\n",
+       "         'sy': 12,\n",
+       "         'sz': 2,\n",
+       "         'ta': 1,\n",
+       "         'tb': 1,\n",
+       "         'to': 3,\n",
+       "         'tp': 2,\n",
+       "         'ts': 2,\n",
+       "         'tt': 1,\n",
+       "         'tv': 3,\n",
+       "         'tw': 1,\n",
+       "         'tz': 1,\n",
+       "         'ub': 8,\n",
+       "         'ug': 10,\n",
+       "         'ui': 4,\n",
+       "         'un': 1,\n",
+       "         'uo': 4,\n",
+       "         'up': 4,\n",
+       "         'ur': 1,\n",
+       "         'us': 3,\n",
+       "         'uu': 2,\n",
+       "         'uv': 1,\n",
+       "         'uy': 1,\n",
+       "         'va': 1,\n",
+       "         'vb': 5,\n",
+       "         'vd': 1,\n",
+       "         've': 6,\n",
+       "         'vg': 1,\n",
+       "         'vh': 3,\n",
+       "         'vi': 2,\n",
+       "         'vl': 1,\n",
+       "         'vm': 1,\n",
+       "         'vo': 1,\n",
+       "         'vs': 1,\n",
+       "         'vt': 3,\n",
+       "         'vu': 5,\n",
+       "         'vv': 1,\n",
+       "         'vw': 1,\n",
+       "         'vy': 6,\n",
+       "         'wb': 1,\n",
+       "         'wc': 3,\n",
+       "         'wd': 2,\n",
+       "         'we': 1,\n",
+       "         'wo': 1,\n",
+       "         'wp': 4,\n",
+       "         'ws': 2,\n",
+       "         'wv': 2,\n",
+       "         'wy': 1,\n",
+       "         'yb': 4,\n",
+       "         'yd': 1,\n",
+       "         'yh': 1,\n",
+       "         'yj': 1,\n",
+       "         'yl': 4,\n",
+       "         'yn': 1,\n",
+       "         'yo': 6,\n",
+       "         'yp': 3,\n",
+       "         'yr': 1,\n",
+       "         'ys': 6,\n",
+       "         'yv': 3,\n",
+       "         'yw': 3,\n",
+       "         'yy': 3,\n",
+       "         'yz': 5,\n",
+       "         'zb': 4,\n",
+       "         'zc': 3,\n",
+       "         'zd': 2,\n",
+       "         'ze': 1,\n",
+       "         'zj': 1,\n",
+       "         'zo': 2,\n",
+       "         'zp': 3,\n",
+       "         'zr': 1,\n",
+       "         'zs': 3,\n",
+       "         'zt': 1,\n",
+       "         'zu': 1,\n",
+       "         'zv': 3,\n",
+       "         'zw': 1,\n",
+       "         'zy': 1,\n",
+       "         'zz': 6})"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "frequencies(ngrams(c6as, 2))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'harry good call on the nazi paper trail the attached is a memo from paris high command to goering s secretary referring to the painting and clearly mentioning sara seems like they knew about the scam our friendly ss officer was planning to pull they picked up her trail the night after she went missing but you can read about that in their report still no joy on getting access to the original miss mona in the gallery and i am beginning to think we might need to rollout a black bag job you want to do it or shall i by the way i was surprised by this report the other papers we have from the nazis at this level are encrypted using bifid or playfair style ciphers this one isnt maybe the cipher clerk was off duty that day we got lucky'"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "' '.join(segment(letters(c6a).translate(''.maketrans({'B':'t', 'C':'h', 'S':'e', 'O':'i', 'U':'n', 'G':'g', 'A':'b', 'V':'o', 'N':'k', 'J':'w', 'T':'m', 'I':'d', 'P':'a', 'W':'p', 'R':'c', 'Y':'r', 'L':'y', 'D':'l', 'H':'f', 'Z':'s', 'Q':'z', 'E':'u', 'F':'v', 'M':'j'}))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "trans={'B':'t', 'C':'h', 'S':'e', 'O':'i', 'U':'n', 'G':'g', 'A':'b', 'V':'o', 'N':'k', 'J':'w', 'T':'m', 'I':'d', 'P':'a', 'W':'p', 'R':'c', 'Y':'r', 'L':'y', 'D':'l', 'H':'f', 'Z':'s', 'Q':'z', 'E':'u', 'F':'v', 'M':'j'}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 39,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'PARISHGCOMNDTUVWYZBEFJLQ'"
+      ]
+     },
+     "execution_count": 39,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cat(sorted(trans.keys(), key=lambda k: trans[k]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 41,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "harry good call on the nazi paper trail the attached is a memo from paris high command to goering s\n",
+      "secretary referring to the painting and clearly mentioning sara seems like they knew about the scam\n",
+      "our friendly ss officer was planning to pull they picked up her trail the night after she went\n",
+      "missing but you can read about that in their report still no joy on getting access to the original\n",
+      "miss mona in the gallery and i am beginning to think we might need to rollout a black bag job you\n",
+      "want to do it or shall i by the way i was surprised by this report the other papers we have from the\n",
+      "nazis at this level are encrypted using bifid or playfair style ciphers this one isnt maybe the\n",
+      "cipher clerk was off duty that day we got lucky\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(keyword_decipher(c6as, 'parishighcommand', KeywordWrapAlphabet.from_largest)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "c6bs = sanitise(c6b)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1573"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(c6bs)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from itertools import permutations"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(0, 1, 2, 3),\n",
+       " (0, 1, 3, 2),\n",
+       " (0, 2, 1, 3),\n",
+       " (0, 2, 3, 1),\n",
+       " (0, 3, 1, 2),\n",
+       " (0, 3, 2, 1),\n",
+       " (1, 0, 2, 3),\n",
+       " (1, 0, 3, 2),\n",
+       " (1, 2, 0, 3),\n",
+       " (1, 2, 3, 0),\n",
+       " (1, 3, 0, 2),\n",
+       " (1, 3, 2, 0),\n",
+       " (2, 0, 1, 3),\n",
+       " (2, 0, 3, 1),\n",
+       " (2, 1, 0, 3),\n",
+       " (2, 1, 3, 0),\n",
+       " (2, 3, 0, 1),\n",
+       " (2, 3, 1, 0),\n",
+       " (3, 0, 1, 2),\n",
+       " (3, 0, 2, 1),\n",
+       " (3, 1, 0, 2),\n",
+       " (3, 1, 2, 0),\n",
+       " (3, 2, 0, 1),\n",
+       " (3, 2, 1, 0)]"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "list(permutations(range(4)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['hithhnfrferteaofftnasltyorrreqthimserulrhfsetaeeiuiwsihbnrrtsioiienirhmrpytdtoeircitalnbrpnhtohorliewtshtesposotoynuwhredhhcpicmnootahashtijeanetofrneusragmxurttowleatbrtepptraaesenethhrisnrststrnfldoghaumgseseakuntiahyttnyuntnnvhigwlewfiapasrelfaiebapcmcplahethtolhwsuladseuveaeotaeutateefehlbhtrshgatliaceehtrnhgaasietufnnpurehrelittmudyinnuegicouendeeiahsuelhtnoahtieainyfdniauoenatiyefohedaluaroeryhuraeraterahiaongtwiswsaitbultaomxletoreototonaoortgbcvaipnleewfyrtaeoaduwwetrrtnlrpfpaiellrimntrowieqrecuarndotafnroteletpenrpmshnddetdewhefoypedennsneegtateeanesertgdlueosrburowhdgbrpahenyttekrertrrhnfnedoltswsianiypothmouoctyeieeponhkrnntairlteeiuremnitaphoeaohhnouumtkvsenedeeoidpwkiegtiiiosenhuufanbeuithraerhieehuayasrusiwgadsisitrlgfphiltwiisihesurmromaceisoilvdeoelusairideotnfiesobntsapofgsodrtfirpltanetrlyiosotyoessfntpheaigeaoraieitdmtaaegrhyasrrcfelrtleeanehvehivmhnassieroixlmpsjttesofbmrhndiochecnbttncompusesoehtenetfienootnwooteeriltoigdosmehoifmlroeffdtuesoflerwiiyqdbzottnrfantdigontalaepdsheamnthlpsnbtuoahaalplemnpdrshvnaiaelnhcaliskacdoaedtjghoieadgwayndetenhegeeueoeednoryyrfctemttwntgdetasuoootfwymihrgrhoesinrraofretfenpoyaissesstnhhayeulhiwpcteatuapeanlueelwahaoeluresnbiieasaeteagcdcsorepsroenselvosedudsitlteittfseoesnlnginoernteieiwwlwhteirsiilhtdsrndesrfhrntlgrsuasedadoytasadutenwitcnametertpoesytotocnyutsogcmudlpadleadotefdsbfeleahaxrsonidtieiprashicdcshipbielslnalhorfrentatoraiemklagretmrdcwsnaynwsvnuldorekutnnoutiiunnhvnieilohltefnaeatuifttacetlnnrbhbeglosnaonmifkoaronsnvnfretrcfthdetpswsucpercwtpoawfhdayisooagoaelndfigngrtebltllgfo   ',\n",
+       " 'hihthnrffetreafoftanslytorrreqhtimesrurlhfestaeeiuwisibhnrtrsiioieinrhrmpydttoierctialbnrphntoohrleiwthstepsostooyunwherdhchpimcnotoahsahtjieaentorfnesuramgxutrtolweabtrtpeptaraeesnehthrsinrtsstnrflodghuamgessekaunitahtytnuyntnnvhgiwlwefipaaserlfiaebpacmpclaehthotlhswuldasevueaoetauetaetefhelbthrsghatilaceehtnrhgaasiteufnnpuerhrleitmtudiynneugiocuedneeaihseulhntoathieianydfniuaoeantieyfoehdaulareoryuhrareatreahaiontgwiwssatibutlaoxmleotretootnoaorotgcbvapinleewfrytaoeadwuwertrtlnrppfailelrmintorwiqereucardnotfanrtoeltepernpmhsndedtdweheofypdeensnnegetaeteaensetrgduleorsbuorwhgdbrapheynttkeretrrrnhfndeolstwsainipyotmhoucotyieeeopnhrknnatirtleeuirenmitpahoaeohnhoumutksvendeeeiodpkwietgiioisehnuuafnbueitrhaehrieheuaaysrsuiwagdssiitlrgfhpilwtiiisheusrmormaecisiolvedoeulsariidoetnifesbontaspogfsordtfriplatnertlyoisoytoessfnptheiageoaraeiitmdtaeagryhasrrcflerteleaenhvheivhmnassieorixmlpstjteosfbrmhnidocehcntbtnocmpsueseohtneetifenootnowoteeritloidgosemhofimlorefdftuseofelrwiiyqbdzottnrafntidgotnaleapdhseanmthplsntbuohaaapllenmpdsrhvanialenhacliksacodaetdjgohiedagwyandteenehgeueeoeednroyyfrctmettnwtgedtausootofwmyihgrrheosirnraforeftenopyasisesstnhhayuelhwipcetataupenalueelwhaaoleursenbiieaasetaegccdsoerpsoreneslvsoeddusilttetitfesoenslnignorentieeiwwlwtheisriihltdrsndserfrhntglrsauseaddotyasdautnewictnaemtetrposeyttoocynutosgcumdlapdlaedoetfdbsfeelahxarsnoiditeirpasihcdschibpiesllnlahofrretnatroaimeklgaremtrdwcsnyanwvsnudlorkeutnnouitiunnhvineiolhletfneaatiuftatceltnnbrhbgelonsaomnifokarnosnnvfrterctfhdtepsswuceprctwpowafhadyiosoaogaenldfgingtrebtlllfgo   ',\n",
+       " 'htihhfnrfreteoaffntastlyorrretqhismerlurhsfeteaeiiuwshibnrrtsoiiineirmhrptydteoirictanlbrnphthoorilewsthtsepoostonyuwrhedhhcpcimnootaahshitjenaetfornuesrgamxruttwoletabretpprtaaseentehhirsnsrtsrtnfdlogahumsgesaekutniayhttynunntnvihgwelwfaiparselafieabpccmplhaettholwhsualdsueveeaoteauttaeeefhlhbtrhsgaltiaecehrtnhagaseitunfnprueherlittmuydinunegciounedeieahuselthnohatiaeinfydnaiuoneatyiefhoedlauaorerhyurearaetraihaogntwsiwsiatblutamoxlteoroetootnaoortbgcviapnelewyfrteaoaudwwterrntlrfppaeillirmnrtoweiqrceuanrdoatfnorteeltpnerpsmhnddetedwhfeoyepdennsneegttaeenaesretglduesorbruowdhgbprahneytetkrretrhrnfendotlswisanyipohtmooucteyiepeonkhrntnailrteieurmeniatpheoaohhnouumtvkseendeoeidwpkigetiiiosnehufuanebuihtrarehieehuyaasursigwadissirtlgpfhitlwisiihseurrmomcaeiosildveoleusiariedotfnieosbnstapfogsdortifrptlanterliyostoyosesftnphaeigaeoriaeidtmtaaeghryarsrceflrlteenaehevhimvhnsasireoilxmpjsttseofmbrhdniohcecbnttcnomupseosehetneftieonotwnooeterlitogidomsehiofmrloeffdteusolferiwiydqbztotnfrandtignotaalepsdhemantlhpsbntuaohalaplmenprdshnvaiealnchalsikadcoadetjhgoiaedgawynedtehnegeeueeoedonryryfcetmtwtntdgetsauoootfywmirhgrohesnirroafrtefepnoyiasssesthnhaeyulihwptceautapaenleuelawhaeoluersnibiesaaeetagdccsroeprsoesnelovseuddstiltiettsfeosenlgnineornetiewiwlhwterisilihtsdrnedsrhfrnltgrusasdeadyotaasduetnwticnmaetretpeosyottoncyustogmcudpladeladtoefsdbfleeaahxrosnitdiepirahsiccdshpibileslanlhrofrnetaotraeimkalgrtemrcdwsanynswvnludoerkuntnotuiinunhnvieliohtlefaneautifttactelnrnbhebglsonanomikfoaornsvnnfertrfcthedtpwssupcerwctpaowfdhaysioogaoalendifgnrgtelbtlglfo   ',\n",
+       " 'hhithrnffterefaofatnsyltorrrehqtiemsrrulhefsteaeiwuisbihntrrsiioiienrrhmpdyttioertciablnrhpntoohreliwhtstpesotsoouynwehrdchhpmicntooashahjtieeantrofnseurmagxturtlowebatrptepatraeesnhethsrintrssntrfoldguhamegsskeauintathytunynntnvghiwwlefpiaaesrlifaepbacpmcleahtohtlshwudlasveueoaetuaeteatehfeltbhrgshaitlaecehntrhagastieunfnpeurhlreimttuidynenugoicudeneaeihesulnhtotahiieandyfnuiaoaenteiyfeohdualaeroruyhrraearteaahiotngwwisstaibtulaxomloetrteoontoarootcgbvpainelewrfytoaeawduwretrltnrppfalielmrinotrwqieruecadrnoftantroetleprenphmsneddtwdehoefydpeesnnngeeteateeanstergudlerosbourwghdbarphyentkterterrnrhfdneosltwasinpiyomthocuotiyeeoepnrhknantitrleueirnemiptahaoeonhhomuutskvedneeieodkpwitegioiishenuaufnubeirthaheriheeuaayssruiawgdssiiltrghfpiwltiiishuesromrmeaciisolevdouelsraiiodetinfebsonatspgofsrodtrfipaltnretloyisyotosesfpnthieagoeareaiimtdteaagyrharsrclferetleeanhhveihvmnsasioerimxlptsjtoesfrbmhindoechctnbtoncmspueesohnteeitfeonotonwoetertilodigoesmhfoimolredfftsueoeflriwiybqdztotnarfnitdgtonaelaphdsenamtphlstnbuhoaapallnempsdrhavnilaenahclkisaocdatedjoghideagywantdeeenhgueeeeoedrnoyfyrcmtetntwtegdtuasotoofmwyighrrehosrinrfaorfeteonpysaissesthnhauyelwhipectaatupnealeuelhwaaloeusrenibieaaseategccdseorposreenslsvoedduslittteitefsoneslingnroeniteewiwltwhesirihiltrdsnsderrfhngtlrasusaeddtoyadsauntewcitneamtterpsoeyttooycnuotsgucmdalpdaledeotfbdsfeelaxharnsoiidteripaishcsdchbipiselllnahforrtenartoamiekglarmetrwdcsynanvwsndulokreuntnoiutinunhivneoilheltfenaaitufattcletnbnrhgbelnosamoniofkanrosnnvftrertcfhtdepsswuecprtcwpwoafahdyoisooaganeldgfintgretbllflgo   ',\n",
+       " 'hthihfrnfrteeofafnatstylorrrethqisemrlruhsefteeaiiwushbinrtrsoiiiniermrhptdyteioritcanblrnhpthoorielwshttspeootsonuywrehdhchpcminotoaashhijteneatfronusergmaxrtutwloetbareptprataseenthehisrnstrsrntfdolgauhmsegsakeutinaythtyunnnntvighwewlfapiareslaifeapbccpmlheattohlwshuadlsuveeeoateuatteaeehflhtbrhgsalitaeechrnthaagsetiunnfpreuhelritmtuyidnuengcoiundeeiaehuesltnhohtaiaienfdynauionaetyeifheodluaaoerrhuyreraaertaiahogtnwswisitabltuamxoltoeroteoontaorotbcgvipaneelwyrfteoaauwdwtrernltrfppaelilimrnrotweqircueandroaftnotreetlpnrepshmndedtewdhfoeyedpensnnegetteaeneasrtegludesrobrouwdghbparhnyetektrrterhnrfednotslwiasnypiohmtoocuteiyepoenkrhntaniltreiuermneiaptheaoohnhoumutvskeedneoiedwkpigteiioisnheufauneubihrtarheieheuyaasusrigawdissirltgphfitwlisiihsuerrommceaioisldevoluesiraieodtfineobsnsatpfgosdrotirfptalntrelioystyoosseftpnhaiegaoerieaidmttaeaghyrarrscelfrleteneahehvimhvnssairoeilmxpjtstsoefmrbhdinoheccbtntconmuspeoeshentefiteoontwonoeetrltiogdiomeshifomrolefdftesuolefriiwydbqzttonfarnditgntoaaelpshdemnatlphsbtnuahoalpalmneprsdhnavielancahlskiadocadtejhogiadegaywnetdehengeueeeeodornyrfycemttwnttdegtsuaootofymwirghroehsnrirofartfeeponyisasssethhnaeuyliwhptecauatpaneleeulahwaelouesrniibesaaeeatgdccsreoprosesenlosveuddstlititetsefosnelginneroneitewwilhtwersiilhitsrdnesdrhrfnlgtruassdaedytoaadsuentwtcinmeatrtepesoyottonycusotgmucdpaldealdteofsbdfleeaaxhronsitidepriahisccsdhpbiilselalnhrfornteaortaemikaglrtmercwdsaynnsvwnlduoekrunntotiuinnuhniveloihtelfaenauitftatctlenrbnhegblsnoanmoikofaonrsvnnfetrrftchetdpwssupecrwtcpawofdahysoiogoaalnedigfnrtgeltblgflo   ',\n",
+       " 'hhtihrfnftreefoafantsytlorrrehtqiesmrrluhesfteeaiwiusbhintrrsioiiinerrmhpdtytieorticabnlrhnptohoreilwhsttpseotosounywerhdchhpmcintooasahhjiteenatrfonsuermgaxtrutlwoebtarpetpartaesenhtehsirntsrsnrtfodlguahmesgskaeuitnatyhtuynnnntvgihwwelfpaiaersliafepabcpcmlehatothlswhudalsvueeoeatueatetaeheflthbrghsailtaeechnrthaagsteiunnfperuhlerimttuiydneungociudneeaieheuslnthothaiiaendfynuaioaneteyifehodulaaeorruhyrreaaretaaihotgnwwsistiabtluaxmolotertoeonotarootcbgvpianeelwryftoeaawudwrterlntrpfpaleilmirnortwqeiruceadnrofatntoretelprnephsmneddtwedhofeydepesnnngeetetaeenastreguldersoboruwgdhbaprhynetketrtrernhrfdenostlwaisnpyiomhtocoutieyeopenrkhnatnitlreuiernmeipathaeoonhhomuutsvkedeneioedkwpitgeioiishneuafunuebirhtahreiheeuayassuriagwdsisilrtghpfiwtliisihuserormmecaiiosledvoulesriaioedtifnebosnastpgfosrdotrifpatlnrteloiysytoossefptnhiaegoaereiaimdtteaagyhrarrsclefrelteenahhevihmvnssaioreimlxptjstosefrmbhidnoehcctbntocnmsupeeoshneteifteoontownoeetrtliodgioemshfiomorledfftseuoelfriiwybdqzttonafrnidtgtnoaealphsdenmatplhstbnuhaoaplalnmepsrdhanvileanachlksiaodcatdejohgidaegyawntedeehngueeeeeodronyfrycmettnwttedgtusaotoofmywigrhreohsrnirfoarfteeopnysiasssethhnaueylwihpetcaautpnaeleeulhawaleouserniibeasaeaetgcdcseroporseesnlsovedudsltittietesfonselignnreonietewwilthwesriihlitrsdnsedrrhfngltraussadedtyoadasunetwctinemattrepseoytotoyncuostgumcdapldaeldetofbsdfeleaxahrnosiitderpiaihscscdhbpiislellanhfrortnearotameikgalrmterwcdsyannvswndluokerunntoituinnuhinveolihetlfeanaiutfattcltenbrnhgeblnsoamnoiokfanorsnvnfterrtfchtedpswsuepcrtwcpwaofadhyosioogaanledgifntrgetlblfglo   ',\n",
+       " 'ihthnhfrefrtaeoftfnalstyrorrqethmiseurlrfhseateeuiiwishbrnrtisoieinihrmryptdoteicritlanbprnhotholrietwshetspsootyonuhwrehdhcipcmonothaasthijaeneotfrenusargmuxrtotwlaetbtreptpraeaseenthrhisrnsttsrnlfdohgaugmseesaknutihaytntyutnnnhviglwewifapsareflaibeapmccpalhehttohlwsluadesuvaeeoateuattefeehblhtsrhgtalicaeethrnghaaisetfunnuprerheltitmduyinnueigcoeundeeiashuehltnaohteiaiynfdinaueonaityeofheadluraoeyrhuarertaerhaianogtiwswasitubltoamxeltoerottoonoaorgtbcaviplneefwyrateodauwewtrtrnlprfpiaelrlimtnroiweqercurandtoafrnotleetepnrmpshdndedtewehfopyednensenegatteaeneesrtdgluoesrubrohwdgrbpaehnyttekerrtrrhnnfedlotsswiainyptohmuoocyteieepohnkrnntarilteeiuermntiapoheahohnuoumktvsneedeeoipdwkeigtiiioesnhuufabneutihrearheiehauyarsuswigasdistirlfgphlitwiisiehsumrroamcesioivldeeoluasirdieontfiseobtnsaopfgosdrftirlptaentrylioostyeossnftpehaiegaoarietidmataerghysarrfceltrleaenevhehvimhansseiroxilmspjtetsobfmrnhdicohencbtntcopmusseoethentefineoontwotoeeirltiogdsomeohiflmrofefdutesfolewriiqydbozttrnfatndiogntlaaedpshaemnhtlpnsbtouahaalpelmndprsvhnaaielhncailskcadoeadtgjhoeiadwgaydnetneheegeuoeeendoryyrftcemttwngtdeatsuoootwfymhirghroeisnrarofertfnepoayisesssnthhyaeuhliwcptetauaepanuleewlahoaelruesbniiaesateeacgdcosrespronesevlosdeudistletitftseeosnnlgionertneiiewwwlhtiersiilhdtsrdnesfrhrtnlgsruaesdaodytsaadtueniwtcanmeetrtopestyotconytusocgmuldpaldeaodtedfsbeflehaaxsronditiieprsahidccsihpbeilsnlalohrfernttaoriaemlkagertmdrcwnsaywnsvunldroektunnuotiuinnvhniielolhtenfaetauitftaectlnnrbbhegolsnoanmfikoraonnsvnrfetcrftdhetspwscupecrwtopawhfdaiysoaogoealnfdiggnrtbeltllgf o  ',\n",
+       " 'ihhtnhrfeftraefotfanlsytrorrqehtmiesurrlfhesateeuiwiisbhrntrisioeiinhrrmypdtotiecrtilabnprhnotohlreitwhsetpssotoyounhwerhdchipmcontohasathjiaeenotrfensuarmguxtrotlwaebttrpetpareaesenhtrhsirntstsnrlfodhguagmeseskanuithatyntuytnnnhvgilwweifpasaerfliabepamcpcalehhtothlswludaesvuaeoeatueatetfeheblthsrghtailcaeethnrghaaistefunnuperrhletimtduiynneuigoceudneeaisheuhlntaotheiiayndfinuaeoaniteyofehadulraeoyruharretarehaainotgiwwsastiubtloaxmelotertotonooarogtcbavpilneefwryatoedawuewrttrlnprpfialerlmitnoriwqeerucradntofarntoleteeprnmphsdneddtweehofpydenesnengeatetaeenestrdguloersuborhwgdrbapehynttkeertrrrnhnfdelostswaiinpytomhuocoytieeeophnrknnatritleeuiernmtipaohaehonhuomuktsvnedeeeiopdkweitgiioieshnuuafbnuetirheahreiheauayrssuwiagsdsitilrfghpliwtiiisehusmroramecsiiovledeoulasridioentifsebotnasopgfosrdftrilpatenrtyloiosyteossnfptehiaegoaareitimdateargyhsarrfcletrelaeenvhhevihmansseiorximlsptjetosbfrmnhidcoehnctbntocpmsuseeothneteifneoontowtoeeirtliodgsoemohfilmorfedfutsefoelwriiqybdozttrnaftnidogtnlaeadphsaenmhtplnstbouhaaaplelnmdpsrvhanailehnacilkscaodeatdgjoheidawgyadnteneehegueoeeendroyyfrtcmettnwgtedatusootowfmyhigrhreoisrnarfoerftneopaysiesssnthhyauehlwicpettaauepnauleewlhaoalerusebniiaeasteaecgcdosersporneesvlsodeduisltettifteseonsnligonretnieiewwwlthiesriihldtrsdnsefrrhtnglsrauesadodtysadatuneiwctanemettropsetytocoyntuoscgumldapldaeodetdfbsefelhaxasrnodiitierpsaihdcscihbpeislnllaohfrertntaroiamelkgaermtdrwcnsyawnvsundlroketunnuoituinnvhinieollhetnfeataiutfatecltnnbrbhgeolnsoamnfiokranonsnvrftecrtfdhtespswcuepcrtwopwahfadiyosaoogeanlfdgigntrbetlllfg o  ',\n",
+       " 'thihfhnrrfetoeafnftatslyrorrteqhsimelrurshfeetaeiiuwhsibrnrtosiinieimrhrtpydetoiirctnalbnrphhtooirleswthstepoostnoyurwhehdhccpimonotaahsihtjneaeftorunesgramrxutwtolteabertprptasaeetnehihrssnrtrstndfloaghusmgeasektuniyahtytnunntnivhgewlwafiprasealfiaebpccmphlaetthowlhsaulduseveeaoetauttaeeefhhlbthrsglatieacerhtnahgaesitnufnrpueehrltitmyudiunnecgionuedieeauhsetlhnhoataieifnydaniunoeaytiehfoeldauoarehryuerareatriahagontswiwisatlbutmaoxtleooretootnoaorbtgcivapenleywfretaouadwtwernrtlfrppeaililrmrntoewiqcreunardaotfonrteeltnperspmhdndeetdwfheoeypdnensenegttaeneaersetlgduseorrbuodwhgpbranheyettkrrethrrnefndtolsiwsayniphotmooucetyipeeoknhrtnnalirtieeumrenaitpehoahohnuoumvtkseendoeeiwdpkgietiiionsehfuuaenbuhitrraeheiehyuaausrsgiwaidssritlpgfhtilwsiiisheurrmocmaeoisidlveloeuisareidoftnioesbsntafpogdsoritfrtplatnerilyotsoysoestfnpaheiageoiraeditmataehgryrasrecfllrteneaeehvhmivhsnasrieolixmjpststeomfbrdhnihocebcntctnoumpsoeseehtnfetioenowtnoeotelritgoidmoseihofrmlofefdetuslofeirwidyqbtzotfnradntingotaalespdhmeanlthpbsntauohlaapmlenrpdsnhvaeialcnhaslikdacodaethjgoaiedagwyendtheneegeueeoeodnrryyfectmwttndtgestauoootyfwmrihgorhensiroraftrefpenoiyassseshtnheayuilhwtpceuataapeneluealwheaoleursinbiseaaeetadgccrsoerpsoseneolvsueddtsilitetstfesoenglnienorentiweiwhlwtreisliihstdrendshrfrlntgursadseaydotaasdeutntwicmnaerteteposoyttnocysutomgcupdlaedlatdoesfdblfeeaahxorsntidipeirhasiccdsphibliesalnlrhofnretoatreaimaklgtremcrdwasnysnwvlnudeorknutntouiniunnhvileiothleafneuatitftatcelrnnbehbgslonnaomkifooarnvsnnefrtfrctehdtwpsspucewrctapowdfhasyiogoaolaenidfgrngtlebtgllf o  ',\n",
+       " 'hhitrhnftferfeaoaftnysltrorrheqteimsrrulehfsetaewiuibsihtnrrisioiienrrhmdpytitoetrcibalnhrpnotoherlihwtsptestosouoynewhrcdhhmpictnoosahajhtieeanrtofsneumragtxurltowbeatprteaptreaeshnetshritnrsnstrofldughaemgskseaiunttahyutnynntngvhiwwlepfiaeasrilfapebapcmcelahothtslhwdulavseuoeaeutaeetathefetlbhgrshiatleacenhtrahgatsienufnepurlhremittiudyennuogicduenaeeiehsunlhttoahiieadnyfuniaaoenetiyefohudalearouryhrraerateaahitongwwistsaitbulxaomolettreonotoraooctgbpvaienlerwfyotaewadurwetlrtnprpflaiemlriontrqwieurecdarnfotatnrotelerpenhpmsenddwtdeohefdypesenngneeetateeantserugdlreosoburgwhdabrpyhenkttetrernrrhdfnesoltawsipniymothcouoityeoeeprnhkannttirlueeinrempitaahoenohhmouustkvdeneieeokdpwtiegoiiihsenauufunberithhaerhieeauayssruaiwgsdsilitrhgfpwiltiiisuhesormremaciisoelvduoelrsaioideitnfbesoantsgpofrsodrtfiapltrnetolyiysotsoespfntiheaogeaeraimitdetaaygrhrasrlcfeertleeanhhvehivmsnasoiermixltpsjotesrfbmihndeochtcnbotncsmpueesonhteietfoenootnweotetrildoigeosmfhoiomlrdeffstueeoflirwibyqdtzotanrfintdtgonealahpdsneampthltsnbhuoapaalnlemspdrahvnliaeanhcklisoacdtaedojghdieaygwatndeeenhugeeeeoerdnofyyrmctenttwetgdutastooomfwygihrerhorsinfraofretoenpsyaisseshtnhuayewlhiepctaatunpeaeluehlwalaoesureinbiaeasaetecgcdesoropsreensslvodedulsittteietfsnoesilngrnoeinteweiwtlwhseirhiilrtdssnderrfhgntlarsuasedtdoydasanutecwitenamtterspoetytoyocnoutsugcmadlpadleedotbfdsefelxahanrsoiidtreipiashscdcbhipsielllnafhortrenratomaiegklamretwrdcysnavnwsdnulkorenutnioutniunihvnoeilehltefnaiatuafttlcetbnnrghbenlosmaonoifknaronsnvtfretrcfthdespsweucptrcwwpoaafhdoyisooagnaelgdfitngrteblfllg o  ',\n",
+       " 'thhifhrnrfteoefanfattsylrorrtehqsiemlrrushefeteaiiwuhsbirntrosiiniiemrrhtpdyetioirtcnablnrhphtooirelswhtstpeootsnouyrwehhdchcpmiontoaashihjtneeaftrounsegrmarxtuwtlotebaerptrpatsaeetnheihsrsntrrsntdfolaguhsmegasketuinyathytunnnntivghewwlafpiraesalifaepbccpmhleattohwlshaudlusveeeoaetuatteaeehfhltbhrgslaiteaecrhntahagestinunfrpeuehlrtimtyuidunencgoinudeieaeuhestlnhhotaaiiefndyanuinoaeyteihfeolduaoaerhruyerraeartiaahgotnswwiistalbtumaxotloeorteoontoarobtcgivpaenelywrfetoauawdtwrenrltfrppealiilmrrnotewqicruenadraoftontreetlnpresphmdnedetwdfhoeeydpnesnengetteaneearstelgudserorboudwghpbarnhyeetktrrtehrnrefdntosliwasynpihomtoocuetiypeoeknrhtnanlitrieuemrneaiptehaohonhuomuvtskeednoeiewdkpgiteiioinshefuauenubhirtraheeiheyuaaussrgiawidssriltpghftiwlsiiishuerromcmeaoiisdlevloueisraeiodftinoebssnatfpgodsroitrftpaltnreiloytsyososetfpnahieagoeireadimtateahgyrrarseclflretneeaehhvmihvsnsarioelimxjptsstoemfrbdhinhoecbctnctonumspoeesehntfeitoeonwtoneoetlrtigodimoesihformolfedfetsuloefiriwdybqtztofnardnitngtoaaelsphdmenaltphbstnauholapamlnerpsdnhaveilacnahslkidaocdatehjogaideagywentdheenegueeeeoodrnryfyecmtwtntdtegstuaootoyfmwrighorehnsriorfatrfepeoniysasssehthneauyilwhtpecuaatapneeleualhwealoeusrinibseaaeeatdgccrseorposseenolsvueddtsliittestefsoneglinenroenitwewihltwresilihistrdensdhrrflngturasdsaeydtoaadseunttwcimneartteepsooyttnoycsuotmgucpdaledaltdeosfbdlfeeaaxhornstiidperihaisccsdphbiliseallnrhfonrteoarteamiakgltrmecrwdasynsnvwlndueokrnunttoiuninunhivleoithelafenuaittfattclernbnehgbslnonamokiofoanrvsnneftrfrtcehtdwpsspuecwrtcapwodfahsyoigooalaneidgfrntgletbglfl o  ',\n",
+       " 'hhtirhfntfrefeoaafntystlrorrhetqeismrrluehsfeteawiiubshitnrrisoiiinerrmhdptyiteotricbanlhrnpothoerilhwstptsetoosuonyewrhcdhhmpcitnoosaahjhiteenartfosnuemrgatxrultwobetapretaprteasehnteshirtnsrnsrtofdlugahemsgksaeiutntayhutynnnntgvihwwelpfaiearsilafpeabpccmelhaotthslwhdualvsueoeeauteaettaheeftlhbgrhsialteaecnhrtahagtseinunfeprulhermittiuydenunogciduneaeieehusnlthtohaiiaednfyunaiaoneetyiefhoudlaeaorurhyrrearaetaaihtognwwsitsiatbluxamooltetroenootraooctbgpviaenelrwyfoteawaudrwtelrntprfplaeimlironrtqweiurcedanrfoattnorteelrpnehpsmenddwtedohfedyepsenngneeettaeenatsreugldresoobrugwdhabpryhnektettrrenrhrdfensotlawispnyimohtcoouiteyoepernkhantntilrueienrmepiataheonohhmouustvkdeenieoekdwptigeoiiihsneaufuunebrihtharehieeauyassuraigwsdislirthgpfwitliisiuhseorrmemcaiioseldvuolersiaoieditfnbeosanstgpforsdortifaptlrnteoliyystososepftnihaeogaeeriamidtetaayghrrarslceferlteenahhevhimvsnsaoiremilxtpjsotserfmbihdneohctcbnotcnsmupeeosnhetieftoeonotwneoettrlidogieomsfhioomrldeffsteueolfiriwbydqtztoanfrindttgnoeaalhpsdnemaptlhtsbnhuaopalanlmesprdahnvlieaanchklsioadctadeojhgdiaeygawtnedeehnugeeeeeordonfyrymcetntwtetdgutsatooomfywgirherohrsnifroafrteoepnsyiasssehthnuaeywliheptcaautnpaeeleuhlawlaeosuerinibaesaaeetcgdcesrooprseesnslovdeudlstittieetsfnoseilgnrneoinetwewitlhwserihilirtsdsnedrrhfgnltarusasdetdyodaasnuetcwtienmattrespeotyotyoncoustugmcadpladeledtobfsdeflexaahnrosiitdrepiiahssccdbhpisilellanfhrotrneraotmaeigkalmrtewrcdysanvnswdnlukoernuntiotuninuihnvoeliehtlefaniautafttlctebnrnghebnlsomanooikfnaornsvntfertrfcthedspwseupctrwcwpaoafdhoysiooganalegdiftnrgtelbflgl o  ',\n",
+       " 'ithhnfhrerftaoeftnfaltsyrrorqtehmsieulrrfsheaeteuiiwihsbrrntiosieniihmrrytpdoeticirtlnabpnrhohtoliretswhestpsootynouhrwehhdcicpmoonthaastihjaneeoftreunsagrmurxtowtlatebterptrpaesaeetnhrihsrsnttrsnldfohagugsmeeaskntuihyatnytutnnnhivglewwiafpsraefalibaepmccpahlehttohwlslaudeusvaeeoaetuattefeehbhltshrgtlaiceaetrhngahaiestfnunurperehlttimdyuinuneicgoenudeieasuhehtlnahoteaiiyfndianuenoaiyteohfealduroaeyhruaerrtearhiaangotiswwaistulbtomaxetloeorttoonooargbtcaivplenefywraetoduawetwrtnrlpfrpiealrilmtrnoiewqecrurnadtaofrontleetenprmsphddnedetwefhopeydnneseengatteaneeerstdlguoserurbohdwgrpbaenhytetkerrtrhrnnefdltossiwaiynpthomuoocyetiepeohknrntnarliteieuemrntaipoehahhonuuomkvtsneedeoeipwdkegitiiioenshufuabenuthireraheeihayuarusswgiasidstrilfpghltiwisiieshumrroacmesoiivdleelouaisrdeionftisoebtsnaofpgodsrfitrltpaetnryilootsyesosntfpeahieagoairetdimaaterhgysrarfecltlreaneevehhvmihasnserioxlimsjptestobmfrndhichoenbctnctopumssoeetehntfeinoeonwtoteoeilrtigodsmoeoihflrmoffeduetsfloewiriqdybotztrfnatdniongtlaaedsphamenhltpnbstoauhalapemlndrpsvnhaaeilhcnaislkcdaoedatghjoeaidwagydentnheeeeguoeeenodryryftecmtwtngdteastuoootwyfmhrighoreinsraorfetrfnpeoaiysesssnhthyeauhilwctpetuaaeapnuelewalhoealreusbiniaseateeacdgcorsesrponseevolsdueditsleittfsteesonnglioenrteniiwewwhltiresilihdstrdensfhrrtlngsuraedsaoydtsaadteunitwcamneerttoepstoytcnoytsuocmgulpdaledaotdedsfbelfehaaxsorndtiiipershaidccsiphbelisnallorhfenrttoarieamlakgetrmdcrwnasywsnvulndreoktnunutoiuninvnhiileolthenafetuaittfaetclnrnbbehgoslnonamfkioroannvsnreftcfrtdehtswpscpuecwrtoapwhdfaisyoagooelanfidggrntbletlglf  o ',\n",
+       " 'ihhtnrhfetfrafeotafnlystrrorqhetmeisurrlfehsaeteuwiiibshrtnriisoeiinhrrmydptoitectrilbanphrnoothlerithwseptsstooyuonhewrhcdhimpcotnohsaatjhiaeenortfesnuamrgutxroltwabettpretapreeasehntrshirtnstnsrlofdhugagemseksaniuthtaynutytnnnhgvilwweipfasearfilabpeampccaelhhotthslwlduaevsuaoeeauteaettfheebtlhsgrhtialceaetnhrgahaitsefnunueprrlhetmitdiuynenuiogceduneaeisehuhnltatoheiiaydnfiunaeaonietyoefhaudlreaoyurharretraehaaintogiwwsatsiutbloxameoltetrotnoooraogctbapvilenefrwyaotedwauerwttlrnpprfilaermlitonriqweeurcrdantfoartnolteeerpnmhpsdenddwteeohfpdyensenegneaettaeenetsrdugloresuobrhgwdrabpeyhntkteetrrrnrhndfelsotsawiipnytmohucooyiteeoephrnknantrtileueienrmtpiaoahehnohumoukstvndeeeieopkdwetigioiiehsnuaufbunetriheharehieaauyrssuwaigssditlirfhgplwitiiiseuhsmorraemcsiioveldeuolarsidoienitfsbeotansogpforsdfrtilapterntyolioystesosnpfteihaeogaaeritmidaetaryghsrarflceterlaeenvhhevhimasnseoirxmilstpjeotsbrfmnihdceohntcbnotcpsmuseeotnhetiefnoeonotwteoeitrlidogseomofhilomrfdefustefeolwiriqbydotztranftindotgnleaadhpsanemhptlntsbohuaapalenlmdsprvahnaliehanciklscoadetadgojhediawygadtneneeheugeoeeenrdoyfyrtmcetntwgetdautsotoowmfyhgirheroirsnafroefrtnoepasyiesssnhthyuaehwlicepttaauenpauelewhlaolaersuebiniaaestaeeccgdoesrsoprneesvsloddeuilstettifetsenosnilgornetineiwewwtlhiserihildrtsdsnefrrhtgnlsarueasdotdysdaatnueicwtaenmettrospettyocyontouscugmladpladeoedtdbfseeflhxaasnrodiitirepsiahdsccibhpesilnllaofhretrntraoimaelgkaemrtdwrcnysawvnsudnlrkoetnunuiotuninvihnioellehtnefatiautaftelctnbnrbgheonlsomanfoikrnaonnsvrtfectrfdthesspwceupctrwowpahafdioysaoogenalfgdigtnrbtellflg  o ',\n",
+       " 'tihhfnhrreftoaefntfatlsyrrortqehsmielurrsfheeateiuiwhisbrrntoisineiimhrrtypdeotiicrtnlabnprhhotoilrestwhsetposotnyourhwehhdccipmoontahasithjnaeefotruensgarmruxtwotltaebetrprtpaseaetenhirhssrntrtsndlfoahgusgmeaesktnuiyhatyntuntnnihvgelwwaifprsaeafliabepcmcphalethtowhlsaluduesveaeoeatutateefehhblthsrgltaiecaerthnaghaeistnfunrupeerhlttimyduiunnecigoneudieeaushethlnhaotaeiifyndainuneoayitehofeladuoraehyruearretarihaagnotsiwwiastlubtmoaxtelooertotonooarbgtciavpelneyfwreatoudawtewrntrlfprpeialirlmrtnoeiwqcerunradatofornteletneprsmphddneedtwfehoepydnneseengtatenaeerestldgusoerrubodhwgprbanehyettkrerthrrnenfdtlosiswayinphtomouoceytipeeokhnrtnnalritieeumernatipeohahhonuuomvktsenedoeeiwpdkgeitiiioneshfuuaebnuhtirreaheeihyauaurssgwiaisdsrtilpfghtliwsiiisehurmrocameosiidvleleouiasrediofntiosebstnafopgdosriftrtlpatenriylotosyseostnfpaehiaegoiaredtimaatehrgyrsarefclltrenaeeevhhmvihsansreiolximjsptsetombfrdnhihcoebnctcntoupmsoseeethnfteioneowntoetoelirtgiodmsoeiohfrlmoffedeutslfoeiwridqybtoztfrnadtninogtalaesdphmaenlhtpbnstaouhlaapmelnrdpsnvhaeailchnasilkdcaodeathgjoaeidawgyednthneeeegueoeeondrryyfetcmwttndgtesatuoootywfmrhigohrenisroarfterfpneoiayssesshntheyauihlwtcpeutaaaepneuleawlheoalerusibnisaeaeteadcgcrosersposneeovlsudedtisliettsfteseongnlieonretniwiewhwltriesliihsdtrednshfrrltngusradesayodtasadetuntiwcmaneretteopsotytncoystuomcgupldaeldatodesdfblefeahaxosrntdiipierhsaicdcspihbleisanllrohfnertotareiamalkgtermcdrwansyswnvlunderokntuntuoinuinnvhilieotlheanfeutaittfateclrnnbebhgsolnnoamkfiooranvnsnerftfcrtedhtwspspcuewcrtaopwdhfasiyogaooleanifdgrgntlbetgllf  o ',\n",
+       " 'hihtrnhftefrfaeoatfnylstrrorhqetemisrurlefhseatewuiibishtrnriisoieinrhrmdyptiotetcriblanhprnoothelrihtwspetstsoouyonehwrchdhmipctonoshaajthieaenrotfsenumargtuxrlotwbaetptreatpreeashentsrhitrnsntsrolfduhgaegmskesainutthayuntyntnnghviwlwepifaesariflapbeapmccealhohttshlwdluavesuoaeeuateeatthfeetblhgsrhitalecaenthraghatisenfuneuprlrhemtitiduyennuoigcdeunaeeieshunhlttaohieiadynfuinaaeoneityeofhuadleraouyrhrarertaeahaitnogwiwstasitublxoamoeltterontooroaocgtbpavielnerfwyoatewdaurewtltrnpprfliaemrliotnrqiweuercdranftoatrnotleerepnhmpsedndwdteoehfdpyesnengeneeatteaentesrudglroesoubrghwdarbpyehnktteterrnrrhdnfeslotaswipinymtohcuooiyteoeeprhnkannttrilueeinermptiaaohenhohmuousktvdneeieeokpdwteigoiiihesnauufubnertihhearheieaauysrsuawigssdiltirhfgpwlitiiisuehsomrreamcisioevldueolrasiodieintfbseoatnsgopfrosdrftialptrentoyliyostseospnftiehaoegaearimtideatayrghrsarlfceetrleaenhvhehvimsansoeirmxiltspjoetsrbfminhdecohtncbontcspmueseontheitefoneoontwetoetirldiogesomfohiolmrdfefsuteefoliwribqydtoztarnfitndtognelaahdpsnaemphtltnsbhouapaalnelmsdpravhnlaieahnckilsocadteadogjhdeiaywgatdneenehuegeeoeerndofyyrmtcenttwegtduatstooomwfyghirehrorisnfarofertonepsayisesshnthuyaewhliecptataunepaeulehwlaloaesrueibniaaesateeccgdeosrosprenessvloddeulisttetieftsneosinlgroneitnewiewtwlhsierhiilrdtssdnerfrhgtnlasruaesdtodydsaantueciwteanmtetrsopettyoyconotusucgmaldpaldeeodtbdfseeflxhaansroiditriepisahsdccbihpseillnlafohrternrtaomiaeglkamertwdrcynsavwnsdunlkroentuniuotnuinivhnoielelhtenfaitauatftlectbnnrgbhenolsmoanofiknraonnsvtrfetcrftdhesspwecuptcrwwopaahfdoiysoaognealgfditgnrtbelfllg  o ',\n",
+       " 'thhifrhnrtfeofeanafttyslrrortheqseimlrrusehfeetaiwiuhbsirtnroisiniiemrrhtdpyeitoitrcnbalnhrphotoierlshwtspteotosnuoyrewhhcdhcmpiotnoasahijhtneeafrtousnegmrartxuwltotbeaeprtraptseaethneishrstnrrnstdoflaughsemgaksetiunytahyutnnnntigvhewwlapfireasailfapebcpcmhelatothwslhaduluvseeoeaeutatetaehefhtlbhgrsliateeacrnhtaahgetsinnufrepuelhrtmityiuduenncogindueiaeeuehstnlhhtoaaiiefdnyauninaoeyetihefoludaoearhuryerraeratiaahgtonswwiitsaltbumxaotoleotreonotoraobctgipvaeenlyrwfeotauwadtrwenlrtfprpelaiimlrronteqwicurendarafototnretelnrpeshpmdendewtdfoheedypnsenegnetetaneeartselugdsreorobudgwhpabrnyheekttrtrehnrredfntsoliawsypnihmotocoueitypoeekrnhtannltiriueemnreapiteahohnohumouvstkedenoieewkdpgtieioiinhsefauueunbhritrhaeehieyauaussrgaiwisdsrlitphgftwilsiiisuherormcemaoiisdelvluoeirsaeoidfitnobessantfgpodrsoirtftapltrneiolytysossoetpfnaiheaogeieradmitaetahygrrraselcflertneeaehhvmhivssnaroielmixjtpssotemrfbdihnheocbtcncotnusmpoeesenhtfietooenwotneeotltrigdoimeosifhoromlfdefestuleofiirwdbyqttzofanrdintntgoaealshpdmnealpthbtsnahuolpaamnlerspdnahveliacanhsklidoacdtaehojgadieaygwetndheeneugeeeeoordnrfyyemctwnttdetgsutaotooymfwrgihoerhnrsiofratfrepoenisyasssehhtneuayiwlhtepcuaatanpeeeluahlwelaoesuriinbsaeaeaetdcgcresoropsseenoslvudedtlsiittesetfsnoegilnernoeintwweihtlwrseilhiisrtdesndhrrflgntuarsdaseytdoadasenuttcwimenartteespootytnyocsoutmugcpadleadltedosbfdlefeaxahonrstiidpreihiascscdpbhilsieallnrfhontreoratemaiagkltmrecwrdaysnsvnwldnuekornnuttiounniunihvloeitehlaefnuiattafttlcerbnneghbsnlonmaokoifonarvnsnetfrftrcethdwspspeucwtrcawpodafhsoyigooalnaeigdfrtngltebgfll  o ',\n",
+       " 'hthirfhntrfefoeaanftytslrrorhteqesimrlrueshfeetawiiubhsitrnriosiiniermrhdtpyietotircbnalhnrpohtoeirlhswtpstetoosunoyerwhchdhmcpitonosaahjihtenearftosunemgratrxulwtobteapertarptesaehtnesihrtsnrnrstodfluaghesmgkaseituntyahuytnnnntgivhwewlpafierasialfpaebpccmehlaotthswlhdaulvuseoeeauetaettaheefthlbghrsilateeacnrhtaahgtesinnuferpulehrmtitiyudeunnocgidnueaieeeuhsntlhthoaiaiedfnyuanianoeeytiehfouldaeoaruhryrerareataiahtgonwswitisatlbuxmaootletorenootroaocbtgpivaeenlrywfoetawuadrtwelnrtpfrpleaimilrorntqewiucrednarfaottonrteelrnpehspmedndwetdofhedeypsnengeneettaeneatrseulgdrseoorbugdwhapbrynheketttrrenhrrdefnstolaiwspynimhotcoouietyopeerknhatnntliruieenmrepaitaehonhohmuousvtkdeenioeekwdptgieoiiihnseafuuuenbrhithraeheieayuasusragiwsidslrithpgfwtilisiiusheorrmecmaioisedlvuloerisaoeidiftnboesasntgfpordsoritfatplrtneoilyytsossoeptfniaheoageeiramditeatayhgrrraslecfelrteneahehvhmivssnaoriemlixtjpsostermfbidhnehoctbcnoctnsumpeoesnehtifetooenowtneeottlridgoiemosfihoormldfefsetuelofiirwbdyqttzoafnridnttngoeaalhspdnmeaplthtbsnhauoplaanmlesrpdanhvleiaacnhksliodactdaeohjgdaieyagwtendehenuegeeeeorodnfryymectnwttedtgustatooomyfwgriheorhrnsiforaftreopensiyasssehhtnueaywilhetpcauatnapeeeluhalwleaoseuriinbaseaaeetcdgcersoorpsesensolvduedltsititeestfnsoeiglnrenoientwweithlwsreihliirstdsendrhrfglntaursadsetydodaasneutctwiemnatrtesepotoytynocosutumgcapdlaedletdobsfdelfexaahnorsitidrpeiihassccdbphislielalnfrhotnreroatmeaigaklmtrewcrdyasnvsnwdlnukeornnutitounniuinhvoleiethleafniuatatftltcebrnngehbnslomnaookifnoarnvsntefrtfrctehdswpsepuctwrcwapoadfhosyiogoanlaegidftrngtlebfgll  o ',\n",
+       " 'ithhnfrhertfaofetnafltysrrroqthemseiulrrfsehaeetuiwiihbsrrtnioiseniihmrrytdpoeitcitrlnbapnhrohotliertshwesptsotoynuohrewhhcdicmpootnhasatijhaneeofrteusnagmrurtxowltatbeteprtrapeseaethnrishrstntrnsldofhauggsemeaksntiuhytanyuttnnnhigvlewwiapfsreafailbapemcpcahelhtothwslladueuvsaeoeaeutatetfehebhtlshgrtliaceeatrnhgaahietsfnnuureprelhttmidyiunuenicogendueiaesuehhtnlahtoeaiiyfdniaunenaoiyetohefaludroeayhuraerrterahiaangtoiswwaitsultbomxaetoleotrtonoooragbctaipvleenfyrwaeotduwaetrwtnlrpfprielarimltronieqwecurrndataforotnleteenrpmshpddendewtefohpedynnseeegnatetaneeertsdlugosreurobhdgwrpabenyhtektertrrhnrnedfltsosiawiypnthmouocoyeitepoehkrnntanrltieiueemnrtapioeahhhnouumokvstnedeeoiepwkdegtiiioienhsufaubeunthrierhaeehiayaurusswgaisisdtrlifphgltwiisiiesuhmroracemsoiivdeleluoairsdeoinfitsobetsanofgpodrsfirtltapetrnyiolotysessontpfeaiheaogaiertdmiaaetrhygsrrafelctleraneevehhvmhiassneroixlmisjtpesotbmrfndihcheonbtcncotpusmsoeetenhtfienooenwotteeoiltrigdosmeooifhlromffdeuestfleowiirqdbyottzrfantdinontglaeadshpamnehlptnbtsoahualpaemnldrspvnahaelihcanisklcdoaedtaghojeadiwaygdetnnheeeeugoeeenordyrfytemctwntgdetasutootowymfhrgihoerinrsaofretfrnpoeaisyesssnhhtyeuahiwlcteptuaaeanpueelwahloelaresubiinasaeteaecdcgoressropnseevosldudeitlseittfsetesnongiloernteiniwwewhtlirseilhidsrtdesnfhrrtlgnsuaredasoytdsadatenuitcwamenerttoesptotycnyotsoucmuglpadleadoteddsbfelefhaxasonrdtiiipreshiadcscipbhelsinallorfhentrtoraiemalagketmrdcwrnayswsvnuldnrekotnnuutiounnivnihiloeltehnaeftuiattafetlcnrbnbeghosnlonmafkoironanvnsretfcftrdethswspcpeucwtroawphdafisoyagooelnafigdgrtnbltelgfl   o',\n",
+       " 'ihthnrfhetrfafoetanflytsrrroqhtemesiurlrfeshaeetuwiiibhsrtrniioseinihrmrydtpoietctirlbnaphnroohtleirthswepststooyunoherwhchdimcpotonhsaatjihaeneorftesunamgrutrxolwtabtetpertarpeesaehtnrsihrtsntnrslodfhuaggesmekasnituhtyanuyttnnnhgivlwewipafserafialbpaempccaehlhotthswlldauevusaoeeauetaettfheebthlsghrtilaceeatnrhgaahitesfnnuuerprlehtmtidiyuneuniocgednueaieseuhhntlathoeiaiydfniuaneanoieytoehfauldreoayuhrarertreahaiantgoiwswatisutlboxmaeotletortnoooroagcbtapivleenfrywaoetdwuaertwtlnrppfrilearmiltorniqeweucrrdnatfaortonlteeernpmhspdedndweteofhpdeynsneegenaettaeneetrsdulgorseuorbhgdwrapbeynhtketetrrrnhrndeflstosaiwipyntmhoucooyieteopehrknnatnrtlieuieenmrtpaioaehhnhoumuoksvtndeeeioepkwdetgiioiiehnsuafubuentrhiehraeheiaayursuswagissidtlrifhpglwtiiisieushmorraecmsioivedleuloarisdoeiniftsboetasnogfpordsfritlatpertnyoiloytsessonptfeiaheoagaeirtmdiaeatryhgsrraflectelraenevhehvhmiassneorixmlistjpeostbrmfnidhcehontbcnoctpsumseoetnehtifenooenowtteeoitlridgosemoofihlormfdfeusetfelowiirqbdyottzrafntidnotngleaadhspanmehpltntbsohauaplaenmldsrpvanhaleihacnikslcodaetdagohjedaiwyagdtenneheeuegoeeenrodyfrytmectnwtgedtaustotoowmyfhgriheorirnsaforeftrnopeasiyesssnhhtyueahwilcetptauaenapueelwhalolearseubiinaasetaeeccdgoerssorpnesevsolddueiltsetitfestensoniglorentieniwwewthlisreihlidrstdsenfrhrtglnsaureadsotydsdaatneuictwaemnetrtosepttoycynotosucumglapdlaedoetddbsfeelfhxaasnorditiirpesihadsccibpheslinlalofrhetnrtroaimealgakemtrdwcrnyaswvsnudlnrkeotnnuuitounnivinhiolelethneaftiuatatfeltcnbrnbgehonslomnafokirnoannvsrtefctfrdtehsswpcepuctwrowaphadfiosyaogoenlafgidgtrnbtlelfgl   o',\n",
+       " 'tihhfnrhretfoafentaftlysrrrotqhesmeilurrsfeheaetiuwihibsrrtnoiisneiimhrrtydpeoitictrnlbanphrhootilersthwseptostonyuorhewhhcdcimpootnahsaitjhnaeefortuesngamrrutxwolttabeetprrtapseeatehnirshsrtnrtnsdlofahugsgemaekstniuyhtaynutntnnihgvelwwaipfrseaafilabpecmpchaelthotwhslalduuevseaoeeauttaetefhehbtlhsgrltiaeceartnhagaheitsnfnurueperlhttmiydiuunenciogneduieaeusehthnlhatoaeiifydnaiunneaoyiethoeflaudoreahyurearretraihaagntosiwwiatslutbmoxateoloetrotnooorabgctiapvelenyfrweaotudwaterwntlrfppreilairmlrtoneiqwceurnrdaatfoortneltenerpsmhpddenedwtfeohepdynnseeegntaetnaeeretsldugsoreruobdhgwprabneyhetktretrhrnrendftlsoisawyipnhtmooucoeyitpeoekhrntnanlrtiieuemenratpieoahhhnouumovkstendeoeiewpkdgetiiioinehsfuauebunhtrirehaeehiyaauurssgwaiissdrtlipfhgtlwisiiiseuhrmorcaemosiidvelleuoiarsedoifnitosbestanfogpdorsifrttlapterniyoltoyssesotnpfaeihaeogiaerdtmiaaethrygrsraeflclternaeeevhhmvhisasnreoilxmijstpseotmbrfdnihhceobntccnotupsmoseeetnhftieonoewnoteteolitrgidomseoiofhrlomffdeeustlfeoiwirdqbytotzfrandtinnotgaleasdhpmanelhptbntsaohulapamenlrdspnvahealichansikldcoadetahgojaediawygedtnhneeeeugeoeeonrdryfyetmcwtntdgetsautootoywmfrhgiohernirsoafrtefrpnoeiasysesshnhteyuaihwltceputaaaenpeuelawhleolaersuibinsaaeetaedccgroesrsopsneeovsluddetilsiettsfetsenognileornetinwiwehwtlriselihisdrtedsnhfrrltgnusardeasyotdasdaetnuticwmaenretteospottyncyostoumcugpladeladtoedsdbfleefahxaosnrtdiipirehsiacdscpibhlesianllrofhnetrotraeimaalgktemrcdwranysswvnludnerkontnutuionuninvihlioetlehanefutiattaftelcrnbnebghsonlnomakfoiornavnnsertffctredthwssppceuwctraowpdhafsioygaoolenaifgdrgtnlbteglfl   o',\n",
+       " 'hithrnfhterffaoeatnfyltsrrrohqteemsirulrefsheaetwuiibihstrrniiosienirhmrdytpioettcirblnahpnroohtelirhtswpesttsoouynoehrwchhdmicptoonshaajtiheaneroftseunmagrturxlowtbatepteratrpeesahetnsrihtrsnntrsoldfuhagegsmkeasintuthyaunytntnnghivwlewpiafesraifalpbaepmcceahlohttshwldlauveusoaeeuaeteatthfeetbhlgshritlaeceantrhagahtiesnfnueurplrehmttiidyuenunoicgdenuaeieesuhnhtltahoieaidyfnuianaenoeiyteohfualderoauyhrraerrteaahiatngowiswtaistulbxomaoetlteorntoorooacgbtpaivelenrfywoaetwduaretwltnrppfrlieamrilotrnqiewuecrdrnaftaotrontleerenphmspeddnwdetoefhdpeysnnegeeneatteanetersudlgroseourbghdwarpbyenhktetterrnrhrdnefsltoasiwpiynmthocuooiyetoeperhknantntrliueienemrptaiaoehnhhomuuoskvtdneeieoekpwdtegioiiihensaufuubenrthiheraheeiaayusrusawgissidltrihfpgwltiiisiueshomrreacmisoievdlueloraisodeiinftbsoeatsngofprodsrfitaltpretnoyilyotssesopntfieahoeageairmtdieaatyrhgrsralfecetlreanehvehhvmisasnoerimxlitsjpoestrbmfindhechotnbconctspumesoentehitfeonoeonwteteotilrdigoesmofoiholrmdffesuetefloiwirbqdytotzarfnitdntongelaahdspnamephlttnbshoaupalanemlsdrpavnhlaeiahcnkislocdatedaoghjdeaiywagtdenenheueegeoeernodfyrymtecntwtegdtuasttooomwyfghriehorrinsfaorfetronpesaiysesshnhtuyeawhilectpatuaneapeuelhwalloeasreuibinaaseateeccdgeorsosrpensesvoldduelitsteitefstnesoinglroenitenwiwetwhlsirehilirdstsdenrfhrgtlnasuraedstoyddsaanteucitweamntertsoepttoyycnootsuucmgalpdaledeotdbdsfeelfxhaansoridtiripeishasdccbiphselilnalforhtenrrtoamieaglakmetrwdcrynasvwsndulnkreontnuiutonuniivnhoileelthenafituaattfletcbnrngbehnoslmonaofkinroannvstreftcfrtdehsswpecputcwrwoapahdfoisyoagonelagfidtgrntbleflgl   o',\n",
+       " 'thihfrnhrtefofaenatftylsrrrothqesemilrursefheeatiwuihbisrtrnoiisnieimrhrtdypeiotitcrnblanhprhootielrshtwspetotsonuyorehwhchdcmipotonashaijthneaefrotusengmarrtuxwlottbaeeptrratpseeathenisrhstrnrntsdolfauhgsegmakestinuythayuntnntnighvewlwapifresaaiflapbecpmchealtohtwshladluuveseoaeeuatteatehfehtblhgsrlitaeecarnthaaghetisnnfureupelrhtmtiyiduuenncoigndeuiaeeueshtnhlhtaoaieifdynauinnaeoyeitheofluadoerahuyrerarertaiahagtnoswiwitasltubmxoatoeloterontooroabcgtipaveelnyrfweoatuwdatrewnltrfppreliaimrlrotneqiwcuerndraaftootrnetlenrepshmpdednewdtfoehedpynsneegenteatneaertesludgsroeroubdghwparbnyehekttrterhnrrednftsloiaswypinhmtoocuoeiytpoeekrhntannltriiueemneraptieaohhnhoumuovsktedneoieewkpdgteiioiinhesfauueubnhrtirheaeheiyaauusrsgawiissdrltiphfgtwlisiiisuehromrceamoisidevllueoiraseodifintobsesatnfgopdrosirfttalptrenioyltyossseotpnfaiehaoegieardmtiaeathyrgrrsaelfcletrneaeehvhmhvissanroeilmxijtspsoetmrbfdinhhecobtnccontuspmoeseenthfiteoonewonteetoltirgdiomesoifohrolmfdfeesutlefoiiwrdbqyttozfarnditnntogaelashdpmnaelphtbtnsahoulpaamnelrsdpnavhelaicahnskildocadteahogjadeiaywgetdnheneeuegeeoeorndrfyyemtcwnttdegtsuatotooymwfrghioehrnrisofartferponeisaysseshhnteuyaiwhltecpuataanepeeulahwleloaesruiibnsaaeeatedccgreosrospseneosvluddetlisitetseftsneoginleroneitnwwiehtwlrsielhiisrdtesdnhrfrlgtnuasrdaesytodadsaentutciwmeanrtetesopottynycosotumucgpaldealdteodsbdfleefaxhaonsrtidipriehisacsdcpbihlseialnlrfohnterortaemiaaglktmercwdraynssvwnldunekronntutiuonnuinivhloietelhaenfuitatatftlecrbnnegbhsnolnmoakofionravnnsetrfftcretdhwssppecuwtcrawopdahfsoiygoaolneaigfdrtgnltbegfll   o',\n",
+       " 'htihrfnhtreffoaeantfytlsrrrohtqeesmirluresfheeatwiuibhistrrnioisineirmhrdtypieotticrbnlahnprohoteilrhstwpsettosounyoerhwchhdmciptoonsahajithenaerfotsuenmgartruxlwotbtaepetrartpeseahtensirhtsrnnrtsodlfuahgesgmkaesitnutyhauyntnntngihvwelwpaifersaiaflpabepcmcehalothtswhldaluvuesoeaeueatetathefethblghsriltaeecanrthaaghteisnnfueruplerhmttiiydueunnocigdneuaieeeushnthlthaoiaeidfynuainaneoeyitehofuladeorauhyrrearretaaihatgnowsiwtiastlubxmoaoteltoernotorooacbgtpiaveelnryfwoeatwudartewlntrpfprleiamirlortnqeiwucerdnrafatotorntelernephsmpeddnwedtofehdepysnnegeenetatenaetresuldgrsoeorubgdhwaprbynehketttrernhrrdenfstloaiswpyinmhtocouoieytopeerkhnatnntlriuieenmerpatiaeohnhhomuuosvktdeneioeekwpdtgeioiiihnesafuuuebnrhtihreaheeiayausursagwisisdlrtihpfgwtliisiiusehormrecamiosiedvluleoriasoediifntboseastngfoprdosriftatlprtenoiylytossseoptnfiaehoaegeiarmdtieaatyhrgrrsalefceltrenaehevhhmvissanoreimlxitjsposetrmbfidnhehcotbncocntsupmeosenethifteooneownteetotlirdgioemsofiohorlmdffeseutelfoiiwrbdqyttozafrnidtntnogealahsdpnmaeplhttbnshaouplaanmelsrdpanvhleaiachnksilodcatdeaohgjdaeiyawgtednehneueegeeoerondfryymetcnwttedgtusattooomywfgrhieohrrnisfoarfteropnesiaysseshhntueyawihletcpautanaepeeulhawlleoaseruiibnasaeaetecdcgerosorspesnesovldudeltistietesftnseoignlreonietnwwiethwlsriehliirsdtsednrhfrgltnausradestyoddasanetuctiwemantretseoptotyyncoostuumcgapldaeldetodbsdfelefxahanosritdirpieihsascdcbpihsleilanlfrohtnerrotameiagalkmterwcdryansvswndlunkeronntuituonnuiinvholieetlheanfiutaattfltecbrnngebhnsolmnoaokfinoranvnsterftfcrtedhswspepcutwcrwaopadhfosiyogaonleagifdtrgntlbefgll   o']"
+      ]
+     },
+     "execution_count": 19,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[column_transposition_decipher(c6bs, p, fillvalue=' ') for p in permutations(range(4))]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'hithhnfrferteaofftnasltyorrreqthimserulrhfsetaeeiuiwsihbnrrtsioiienirhmrpytdtoeircitalnbrpnhtohorliewtshtesposotoynuwhredhhcpicmnootahashtijeanetofrneusragmxurttowleatbrtepptraaesenethhrisnrststrnfldoghaumgseseakuntiahyttnyuntnnvhigwlewfiapasrelfaiebapcmcplahethtolhwsuladseuveaeotaeutateefehlbhtrshgatliaceehtrnhgaasietufnnpurehrelittmudyinnuegicouendeeiahsuelhtnoahtieainyfdniauoenatiyefohedaluaroeryhuraeraterahiaongtwiswsaitbultaomxletoreototonaoortgbcvaipnleewfyrtaeoaduwwetrrtnlrpfpaiellrimntrowieqrecuarndotafnroteletpenrpmshnddetdewhefoypedennsneegtateeanesertgdlueosrburowhdgbrpahenyttekrertrrhnfnedoltswsianiypothmouoctyeieeponhkrnntairlteeiuremnitaphoeaohhnouumtkvsenedeeoidpwkiegtiiiosenhuufanbeuithraerhieehuayasrusiwgadsisitrlgfphiltwiisihesurmromaceisoilvdeoelusairideotnfiesobntsapofgsodrtfirpltanetrlyiosotyoessfntpheaigeaoraieitdmtaaegrhyasrrcfelrtleeanehvehivmhnassieroixlmpsjttesofbmrhndiochecnbttncompusesoehtenetfienootnwooteeriltoigdosmehoifmlroeffdtuesoflerwiiyqdbzottnrfantdigontalaepdsheamnthlpsnbtuoahaalplemnpdrshvnaiaelnhcaliskacdoaedtjghoieadgwayndetenhegeeueoeednoryyrfctemttwntgdetasuoootfwymihrgrhoesinrraofretfenpoyaissesstnhhayeulhiwpcteatuapeanlueelwahaoeluresnbiieasaeteagcdcsorepsroenselvosedudsitlteittfseoesnlnginoernteieiwwlwhteirsiilhtdsrndesrfhrntlgrsuasedadoytasadutenwitcnametertpoesytotocnyutsogcmudlpadleadotefdsbfeleahaxrsonidtieiprashicdcshipbielslnalhorfrentatoraiemklagretmrdcwsnaynwsvnuldorekutnnoutiiunnhvnieilohltefnaeatuifttacetlnnrbhbeglosnaonmifkoaronsnvnfretrcfthdetpswsucpercwtpoawfhdayisooagoaelndfigngrtebltllgfo'"
+      ]
+     },
+     "execution_count": 20,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c6bs"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'hit'"
+      ]
+     },
+     "execution_count": 21,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "''.join([c[0] for c in every_nth(c6bs, 3)])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "28"
+      ]
+     },
+     "execution_count": 22,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c6bs.find('e', 13)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1.6083844580777096"
+      ]
+     },
+     "execution_count": 23,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(c6bs) / 978"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'bnrrt'"
+      ]
+     },
+     "execution_count": 24,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c6bs[55:60]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[('heih', 177), ('heit', 207), ('heip', 307), ('heil', 522)]"
+      ]
+     },
+     "execution_count": 25,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[(c6bs[0] + c6bs[i] + c6bs[2*i] + c6bs[3*i], i) for i in range(int(len(c6bs) / 3)) if c6bs[i] == 'e' and c6bs[2*i] == 'i' ]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['hithhnfrferteaofftnasltyorrreqthimserulrhfsetaeeiuiwsihbnrrtsioiienirhmrpytdtoeircitalnbrpnhtohorliewtshtesposotoynuwhredhhcpicmnootahashtijeanetofrneusragmxurttowleatbrtepptraaesenethhrisnrststrnfldoghaumgseseakuntiahyttnyuntnnvhigwlewfiapasrelfaiebapcmcplahethtolhwsuladseuveaeotaeutateefehlbhtrshgatliaceehtrnhgaasietufnnpurehrelittmudyinnuegicouendeeiahsuelhtnoahtieainyfdniauoenatiyefohedaluaroeryhuraeraterahiaongtwiswsaitbultaomxletoreototonaoortgbcvaipnleewfyrtaeoaduwwetrrtnlrpfpaiellrimntrowieqrecuarndotafnrotel',\n",
+       " 'etpenrpmshnddetdewhefoypedennsneegtateeanesertgdlueosrburowhdgbrpahenyttekrertrrhnfnedoltswsianiypothmouoctyeieeponhkrnntairlteeiuremnitaphoeaohhnouumtkvsenedeeoidpwkiegtiiiosenhuufanbeuithraerhieehuayasrusiwgadsisitrlgfphiltwiisihesurmromaceisoilvdeoelusairideotnfiesobntsapofgsodrtfirpltanetrlyiosotyoessfntpheaigeaoraieitdmtaaegrhyasrrcfelrtleeanehvehivmhnassieroixlmpsjttesofbmrhndiochecnbttncompusesoehtenetfienootnwooteeriltoigdosmehoifmlroeffdtuesoflerwiiyqdbzottnrfantdigontalaepdsheamnthlpsnbtuoahaalplemnpdrshvna',\n",
+       " 'iaelnhcaliskacdoaedtjghoieadgwayndetenhegeeueoeednoryyrfctemttwntgdetasuoootfwymihrgrhoesinrraofretfenpoyaissesstnhhayeulhiwpcteatuapeanlueelwahaoeluresnbiieasaeteagcdcsorepsroenselvosedudsitlteittfseoesnlnginoernteieiwwlwhteirsiilhtdsrndesrfhrntlgrsuasedadoytasadutenwitcnametertpoesytotocnyutsogcmudlpadleadotefdsbfeleahaxrsonidtieiprashicdcshipbielslnalhorfrentatoraiemklagretmrdcwsnaynwsvnuldorekutnnoutiiunnhvnieilohltefnaeatuifttacetlnnrbhbeglosnaonmifkoaronsnvnfretrcfthdetpswsucpercwtpoawfhdayisooagoaelndfigngrteb',\n",
+       " 'ltllgfo']"
+      ]
+     },
+     "execution_count": 26,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[c for c in chunks(c6bs, 522)]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'HITHH NFRFE RTEAO FFTNA SLTYO RRREQ THIMS ERULR HFSET AEEIU IWSIH BNRRT SIOII ENIRH MRPYT DTOEI RCITA LNBRP NHTOH ORLIE WTSHT ESPOS OTOYN UWHRE DHHCP ICMNO OTAHA SHTIJ EANET OFRNE USRAG MXURT TOWLE ATBRT EPPTR AAESE NETHH RISNR STSTR NFLDO GHAUM GSESE AKUNT IAHYT TNYUN TNNVH IGWLE WFIAP ASREL FAIEB APCMC PLAHE THTOL HWSUL ADSEU VEAEO TAEUT ATEEF EHLBH TRSHG ATLIA CEEHT RNHGA ASIET UFNNP UREHR ELITT MUDYI NNUEG ICOUE NDEEI AHSUE LHTNO AHTIE AINYF DNIAU OENAT IYEFO HEDAL UAROE RYHUR AERAT ERAHI AONGT WISWS AITBU LTAOM XLETO REOTO TONAO ORTGB CVAIP NLEEW FYRTA EOADU WWETR RTNLR PFPAI ELLRI MNTRO WIEQR ECUAR NDOTA FNROT ELETP ENRPM SHNDD ETDEW HEFOY PEDEN NSNEE GTATE EANES ERTGD LUEOS RBURO WHDGB RPAHE NYTTE KRERT RRHNF NEDOL TSWSI ANIYP OTHMO UOCTY EIEEP ONHKR NNTAI RLTEE IUREM NITAP HOEAO HHNOU UMTKV SENED EEOID PWKIE GTIII OSENH UUFAN BEUIT HRAER HIEEH UAYAS RUSIW GADSI SITRL GFPHI LTWII SIHES URMRO MACEI SOILV DEOEL USAIR IDEOT NFIES OBNTS APOFG SODRT FIRPL TANET RLYIO SOTYO ESSFN TPHEA IGEAO RAIEI TDMTA AEGRH YASRR CFELR TLEEA NEHVE HIVMH NASSI EROIX LMPSJ TTESO FBMRH NDIOC HECNB TTNCO MPUSE SOEHT ENETF IENOO TNWOO TEERI LTOIG DOSME HOIFM LROEF FDTUE SOFLE RWIIY QDBZO TTNRF ANTDI GONTA LAEPD SHEAM NTHLP SNBTU OAHAA LPLEM NPDRS HVNAI AELNH CALIS KACDO AEDTJ GHOIE ADGWA YNDET ENHEG EEUEO EEDNO RYYRF CTEMT TWNTG DETAS UOOOT FWYMI HRGRH OESIN RRAOF RETFE NPOYA ISSES STNHH AYEUL HIWPC TEATU APEAN LUEEL WAHAO ELURE SNBII EASAE TEAGC DCSOR EPSRO ENSEL VOSED UDSIT LTEIT TFSEO ESNLN GINOE RNTEI EIWWL WHTEI RSIIL HTDSR NDESR FHRNT LGRSU ASEDA DOYTA SADUT ENWIT CNAME TERTP OESYT OTOCN YUTSO GCMUD LPADL EADOT EFDSB FELEA HAXRS ONIDT IEIPR ASHIC DCSHI PBIEL SLNAL HORFR ENTAT ORAIE MKLAG RETMR DCWSN AYNWS VNULD OREKU TNNOU TIIUN NHVNI EILOH LTEFN AEATU IFTTA CETLN NRBHB EGLOS NAONM IFKOA RONSN VNFRE TRCFT HDETP SWSUC PERCW TPOAW FHDAY ISOOA GOAEL NDFIG NGRTE BLTLL GFO\\n'"
+      ]
+     },
+     "execution_count": 27,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c6b"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[29, 503, 985]"
+      ]
+     },
+     "execution_count": 28,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[i for i in range(len(c6bs)) if c6bs[i] == 'q']"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'hithhnfrfer'"
+      ]
+     },
+     "execution_count": 29,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "''.join([c[0] for c in every_nth(c6bs, 11)])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'hithhnfrferte'"
+      ]
+     },
+     "execution_count": 30,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "''.join([c[0] for c in every_nth(c6bs, 13)])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'hhrnrnumeodti'"
+      ]
+     },
+     "execution_count": 31,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "''.join([c[0] for c in chunks(c6bs, 121)])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'harrseehthoexttnsneitetghuydoihuouocttiuedeeerrsohiaeefhifsiitiohtreiehseiiszomhhihtdtoeentencsllilrdieodhpbrlakhntnsdwon'"
+      ]
+     },
+     "execution_count": 32,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "''.join([c[0] for c in chunks(c6bs, 13)])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "True"
+      ]
+     },
+     "execution_count": 33,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "'l' in ''.join([c[0] for c in chunks(c6bs, 13)])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['httmtbnoreohaegaasdetgrmlvtshtenenfiargurredrmcrpwnaegennckehmoinhutioddnrtegmranmmneieseetoetmaaoeoceyiesieaidnseewtrdtttmoaicnagariounanfcfor',\n",
+       " 'ieysaniepwthhtmtenoanwecheehtulueodyratleteupnuomhsnobkeitriotiibisrimeettrsetrnaprbseemfrtnaunecitettmnntwaoecsiorhdnaeeouthesatryeuhirostphat',\n",
+       " 'taoeerrintocaoxbsrgkyllpwaegrfieianeotwtogwwftatsenesrrdyynuekdoeeilsaoosflsaacesshtonrefwntmopldeeeeairpnpneasetentstdnrcdeaihloenknlfbnnhedee',\n",
+       " 'horrerhrhsypsfureshuueflsefanntgahifeeiatbfwprrehfesrpeopenravpsuewgicetaiyfoafhsjnteoihdiranadnoandmshrohcllsollsterlowtnlfxpihrtwuntthmvdralb',\n",
+       " 'hfruitmcthnihrrtntannwaauoethntihtaorrsoocyeaonlnoeebarloiteosweihgfhelnprinreevitdnholotiflthrhadhnturayhtuuarvtneingyipypdrrpoamsthetbinecynl',\n",
+       " 'nfrlusriotuctnteesuttfihlthlgpmcsiuhyawmtvrtiwdedygruhttteamhekntuapeiufopotagleetictttiuyaahascegeotogoaaeereeoelirdrttouassabrirvnvfaefftwidt',\n",
+       " 'fteriipthewmietpttminieeaaliauuoueoehhsxoatreiotdpttrersheinhnihhadhsssiflspirrhreooenofeqnelahadwgrworfiyaeetpsinesesacetdbosifednnnncgkrptsfl',\n",
+       " 'rnqhwoyaoshnjuophrganabtdebaardueaeduialniarletpeeagonrwmprineeurysiuoaegtohehtioscmnwimsdtpplvltaeynohrsetlsesetgiisusnsslfnhermcuoiaeloespoil',\n",
+       " 'fatfsitlrproeswthnshvpahsuhcseyelinaraieapetlqaetdtdwyhsooltodguaailriissateiylviohpeoglobddspnijyeyttoesuuwnardtiwiraaayoeeiilekwlueetoatwoogg',\n",
+       " 'eshsiidnloeoarlrrfeyhaptetteihinhnalaottononrrfndeelhtniuntauetfesstmlroonyataemxfeutodrfzisnlasgnurgfetelaabgoufnwlfsdmtgaldcsnlsdtialsrrsaanf',\n",
+       " 'rliehetbisdtnaeailstiscouareerndtytuenboolalienreneudtfaohepueiarriwrvibdeoidsehlbcsftoologhbeikhdefdwsfshphicedsolhheueocdetdltanoiltnnocuwggo']"
+      ]
+     },
+     "execution_count": 34,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "every_nth(c6bs, 11)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['hetuehroera',\n",
+       " 'iteloirnnny',\n",
+       " 'toetsectptn',\n",
+       " 'hffarefaolw',\n",
+       " 'hreobhelygs',\n",
+       " 'nnhmuulaarv',\n",
+       " 'felxrareisn',\n",
+       " 'rubloytpsuu',\n",
+       " 'fshewaldsal',\n",
+       " 'ertthsesesd',\n",
+       " 'rarodrehseo',\n",
+       " 'tgsrguaesdr',\n",
+       " 'emhebsnatae',\n",
+       " 'axgoriemndk',\n",
+       " 'ouatpwhnhou',\n",
+       " 'frtoagvthyt',\n",
+       " 'ftlthaehatn',\n",
+       " 'ttioedhlyan',\n",
+       " 'noannsipeso',\n",
+       " 'awcayivsuau',\n",
+       " 'sleotsmnldt',\n",
+       " 'leeotihbhui',\n",
+       " 'tahretntiti',\n",
+       " 'ytttkrauweu',\n",
+       " 'obrgrlsopnn',\n",
+       " 'rrnbegsacwn',\n",
+       " 'rthcrfihtih',\n",
+       " 'regvtpeaetv',\n",
+       " 'epaarhraacn',\n",
+       " 'qpairioltni',\n",
+       " 'ttsphlipuae',\n",
+       " 'hrinntxlami',\n",
+       " 'iaelfwlepel',\n",
+       " 'matenimmeto',\n",
+       " 'seueeipnaeh',\n",
+       " 'esfwdsspnrl',\n",
+       " 'renfoijdltt',\n",
+       " 'unnylhtrupe',\n",
+       " 'leprtetseof',\n",
+       " 'rtutsseheen',\n",
+       " 'hhrawusvlsa',\n",
+       " 'fheesronwye',\n",
+       " 'srhoimfaata',\n",
+       " 'eiraarbihot',\n",
+       " 'tsednomaatu',\n",
+       " 'anluimreooi',\n",
+       " 'eriwyahlecf',\n",
+       " 'estwpcnnlnt',\n",
+       " 'itteoedhuyt',\n",
+       " 'usmttiicrua',\n",
+       " 'iturhsoaetc',\n",
+       " 'wrdrmoclsse',\n",
+       " 'snytoihinot',\n",
+       " 'ifinulesbgl',\n",
+       " 'hlnlovckicn',\n",
+       " 'bdnrcdnaimn',\n",
+       " 'nouptebceur',\n",
+       " 'rgefyotdadb',\n",
+       " 'rhgpeetoslh',\n",
+       " 'taiailnaapb',\n",
+       " 'sucieuceeae',\n",
+       " 'imoeesodtdg',\n",
+       " 'ogulpamtell',\n",
+       " 'iseloipjaeo',\n",
+       " 'ienrnruggas',\n",
+       " 'esdihishcdn',\n",
+       " 'neemkdeodoa',\n",
+       " 'iaenresicto',\n",
+       " 'rkitnooesen',\n",
+       " 'huarnteaofm',\n",
+       " 'mnhotnhdrdi',\n",
+       " 'rtswaftgesf',\n",
+       " 'piuiiiewpbk',\n",
+       " 'yaeerenasfo',\n",
+       " 'thlqlseyrea',\n",
+       " 'dyhrtotnolr',\n",
+       " 'ttteebfdeeo',\n",
+       " 'otncenienan',\n",
+       " 'enouitetshs',\n",
+       " 'iyaausneean',\n",
+       " 'ruhrraonlxv',\n",
+       " 'cntnepohvrn',\n",
+       " 'itidmoteosf',\n",
+       " 'tneonfngsor',\n",
+       " 'anatigweene',\n",
+       " 'lviatsoedit',\n",
+       " 'nhnfaoouudr',\n",
+       " 'biynpdtedtc',\n",
+       " 'rgfrhreosif',\n",
+       " 'pwdooteeiet',\n",
+       " 'nlntefretih',\n",
+       " 'heieaiidlpd',\n",
+       " 'twalorlntre',\n",
+       " 'ofuehptoeat',\n",
+       " 'hiothlorisp',\n",
+       " 'oaepntiyths',\n",
+       " 'rpneoagytiw',\n",
+       " 'laanundrfcs',\n",
+       " 'istrueofsdu',\n",
+       " 'eripmtscecc',\n",
+       " 'weymtrmtosp',\n",
+       " 'tleskleeehe',\n",
+       " 'sffhvyhmsir',\n",
+       " 'haonsiotnpc',\n",
+       " 'tihdeoitlbw',\n",
+       " 'eeednsfwnit',\n",
+       " 'sbdeeomngep',\n",
+       " 'paatdtltilo',\n",
+       " 'opldeyrgnsa',\n",
+       " 'scueeoodolw',\n",
+       " 'omawoeeeenf',\n",
+       " 'tcrhisftrah',\n",
+       " 'opoedsfanld',\n",
+       " 'ylefpfdstha',\n",
+       " 'narowntueoy',\n",
+       " 'uhyyktuoiri',\n",
+       " 'wehpipeoefs',\n",
+       " 'htueehsoiro',\n",
+       " 'rhrdgeotweo',\n",
+       " 'etaetaffwna',\n",
+       " 'doeniilwltg',\n",
+       " 'hlrnigeywao',\n",
+       " 'hhasiermhta',\n",
+       " 'cwtnoawitoe',\n",
+       " 'pseesoiherl',\n",
+       " 'iureeririan',\n",
+       " 'clagnaygrid',\n",
+       " 'mahthiqrsef',\n",
+       " 'ndiauedhimi',\n",
+       " 'osatuiboikg',\n",
+       " 'oeoeftzelln',\n",
+       " 'tuneadoshag',\n",
+       " 'avganmtitgr',\n",
+       " 'hetnbttndrt',\n",
+       " 'aaweeanrsee',\n",
+       " 'seisuarrrtb',\n",
+       " 'hoseiefanml',\n",
+       " 'ttwrtgaodrt',\n",
+       " 'iasthrnfedl',\n",
+       " 'jeagrhtrscl',\n",
+       " 'euidayderwg',\n",
+       " 'attleaitfsf',\n",
+       " 'nabursgfhno']"
+      ]
+     },
+     "execution_count": 35,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "every_nth(c6bs, 143)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 36,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(29, 37), (503, 507), (985, 973)]"
+      ]
+     },
+     "execution_count": 36,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[(q, u) for q in [i for i in range(len(c6bs)) if c6bs[i] == 'q'] for u in [i for i in range(len(c6bs)) if c6bs[i] == 'u'] if abs(q-u) < 13]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 37,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['harrseehthoexttnsneitetghuydoihuouocttiuedeeerrsohiaeefhifsiitiohtreiehseiiszomhhihtdtoeentencsllilrdieodhpbrlakhntnsdwon',\n",
+       " 'iorhiniterttuehfeywehueagrieaaernltvanmalddeoptwukuongaiwpuldsrsedrheseenlfoonnavsoenwtsnhelbdetnwhnotsgoarieayuvalanetog',\n",
+       " 'tfefhiroseaorphlaufbtvetaenehudagtoaelnreeeasarsorrhetneghrveapoamcvrocsotmftttankinonfiphawiclegwttycyctxaengntnenovtpar',\n",
+       " 'hfqsbrchpdhftprdkniaoeflahnitoaetatiortnttnnrhricnehdibeaimdopltitfeofnooolltahlaaehrtwnoataisviildltntmersltrwniannnpogt',\n",
+       " 'httenhiooharttioutaplaeisruaielrwoopaprdpdnebehatnmneiehdlretotygaehibbetirenllpicaeygyryyuheootnwsgaaoufshsaesnetrmfsaoe',\n",
+       " 'nnhtrmtrshsnorsgnnpchehaieehenuaimnndfooeessunnnytnoeiuustoonfaoealixmthngorrapladdgydmraeaaarstohrrsmtddoilttvoiubirwwab',\n",
+       " 'faiarralochewanhtnamwolcelgsaaatsxalupwtnwneryfieaiuooiaiwmefgneaervlrttwdewfeseeogereiaiuposeefetnsaeolsncnomnulihfesfel',\n",
+       " 'rsmetplitptularaivscstbetiiuitrewloewaiarherotnyiituistysialisesogtmmhneoofiapnmlawefthosleeapdsredudtcpbidarrutofbktuhlt',\n",
+       " 'flsesyneoiiseesuahrpuaheutceniorseoewiefpeetwteperamdehaiicueotsrrlhpncnosfindbnneaucarfshalesuenieauenafdcladlihteorcdnl',\n",
+       " 'eteiitbwycjrastmhiellethftolyyeaatrweeqnmfgghedoelptpnrstsessdrfahensdoetmdytstphdyetsgreinutrdotrsstrydetshicdiltgacpadl',\n",
+       " 'ryruodrtnmeatesgyglaaurtnmuhferhiotftlrrsotddkotpthkwharriiaorlniyeajimteetqdhudctnoeureswlreoseesreetullihoewoutalrfeyfg',\n",
+       " 'touiitpsunagbntstwfhdtsrnuetdfyitrgyrleohyalgrlhoeovkueulhsibtyteaastopfehudieorajdemohtspueaeisiifdnpteeeirmsrnecootriif',\n",
+       " 'erlwionhwonmreretlaesahnpdnnnohabebrrrctnptubetmneesiursgeornfipisnstcuiroebgaaslgeetooftcesgntneihawosaaipfknenfesnhcsgo']"
+      ]
+     },
+     "execution_count": 37,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "every_nth(c6bs, 13)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 38,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['hthithnfrfere',\n",
+       " 'foaoftnasltyr',\n",
+       " 'qurrethimserl',\n",
+       " 'sirhfetaeeiuw',\n",
+       " 'bisihnrrtsioi',\n",
+       " 'rtenihmrpytdo',\n",
+       " 'cpeiritalnbrn',\n",
+       " 'hshtoorliewth',\n",
+       " 'putesosotoynw',\n",
+       " 'dnhrehhcpicmo',\n",
+       " 'haotaashtijen',\n",
+       " 'fgetorneusram',\n",
+       " 'tbxurtowleatr',\n",
+       " 'pnteptraaesee',\n",
+       " 'rtthhisnrstsr',\n",
+       " 'dsnfloghaumge',\n",
+       " 'ktseauntiahyt',\n",
+       " 'nwnyutnnvhigl',\n",
+       " 'ifewfapasrela',\n",
+       " 'ahiebpcmcplae',\n",
+       " 'odthtlhwsulas',\n",
+       " 'eteuvaeotaeua',\n",
+       " 'fsteeehlbhtrh',\n",
+       " 'lrgatiaceehtn',\n",
+       " 'anhgasietufnp',\n",
+       " 'huurerelittmd',\n",
+       " 'neyinuegicoun',\n",
+       " 'itdeeahsuelhn',\n",
+       " 'tdoahieainyfn',\n",
+       " 'ofiauenatiyeo',\n",
+       " 'ayhedluaroerh',\n",
+       " 'eiurarateraha',\n",
+       " 'ttongwiswsaib',\n",
+       " 'arultomxletoe',\n",
+       " 'tgotoonaoortb',\n",
+       " 'iycvapnleewfr',\n",
+       " 'ortaeaduwwetr',\n",
+       " 'rltnlpfpaielr',\n",
+       " 'teimnrowieqrc',\n",
+       " 'nouardotafnrt',\n",
+       " 'thelepenrpmsn',\n",
+       " 'tyddedewhefop',\n",
+       " 'naedensneegtt',\n",
+       " 'nleeaesertgdu',\n",
+       " 'rgeosburowhdb',\n",
+       " 'hrrpaenytteke',\n",
+       " 'rlrtrhnfnedot',\n",
+       " 'ihswsaniypotm',\n",
+       " 'coouotyeieepn',\n",
+       " 'nehkrntairlte',\n",
+       " 'eoiurmnitaphe',\n",
+       " 'hvaohnouumtks',\n",
+       " 'dkeneeeoidpwi',\n",
+       " 'iuegtiiosenhu',\n",
+       " 'befaneuithrar',\n",
+       " 'euhiehuayasrs',\n",
+       " 'aliwgdsisitrg',\n",
+       " 'ihfphltwiisie',\n",
+       " 'mssurromaceio',\n",
+       " 'diilveoelusar',\n",
+       " 'obidetnfieson',\n",
+       " 'pttsaofgsodrf',\n",
+       " 'lyirptanetrli',\n",
+       " 'ttosoyoessfnp',\n",
+       " 'ieheageaoraii',\n",
+       " 'tatdmaaegrhys',\n",
+       " 'farrcelrtleen',\n",
+       " 'esehvhivmhnas',\n",
+       " 'otierixlmpsjt',\n",
+       " 'foesobmrhndic',\n",
+       " 'nphecbttncomu',\n",
+       " 'ofsesehteneti',\n",
+       " 'oeenotnwooter',\n",
+       " 'ohiltigdosmeo',\n",
+       " 'luifmroeffdte',\n",
+       " 'ldsoferwiiyqb',\n",
+       " 'tizotnrfantdg',\n",
+       " 'aeontlaepdsha',\n",
+       " 'homntlpsnbtua',\n",
+       " 'lrhaaplemnpds',\n",
+       " 'aahvniaelnhcl',\n",
+       " 'ajiskcdoaedtg',\n",
+       " 'edhoiadgwayne',\n",
+       " 'hetenegeeueoe',\n",
+       " 'rmdnoyyrfctet',\n",
+       " 'totwngdetasuo',\n",
+       " 'whotfymihrgro',\n",
+       " 'ntesirraofref',\n",
+       " 'osenpyaissest',\n",
+       " 'apnhhyeulhiwc',\n",
+       " 'tuteauapeanle',\n",
+       " 'aeelwhaoelurs',\n",
+       " 'ianbieasaeteg',\n",
+       " 'secdcorepsron',\n",
+       " 'viselosedudst',\n",
+       " 'isltettfseoen',\n",
+       " 'iilngnoerntee',\n",
+       " 'liiwwwhteirsi',\n",
+       " 'dflhtsrndesrh',\n",
+       " 'ldrntgrsuasea',\n",
+       " 'tndoyasadutew',\n",
+       " 'npitcameterto',\n",
+       " 'ttesyotocnyus',\n",
+       " 'meogcudlpadla',\n",
+       " 'eedotfdsbfela',\n",
+       " 'rehaxsonidtii',\n",
+       " 'siprahicdcshp',\n",
+       " 'lrbieslnalhof',\n",
+       " 'tmrenatoraiek',\n",
+       " 'rslagetmrdcwn',\n",
+       " 'wraynsvnuldoe',\n",
+       " 'nnkutnoutiiun',\n",
+       " 'iehvneilohltf',\n",
+       " 'acnaetuifttae',\n",
+       " 'notlnrbhbegls',\n",
+       " 'nonaomifkoarn',\n",
+       " 'ntsnvfretrcfh',\n",
+       " 'prdetswsucpec',\n",
+       " 'oiwtpawfhdays',\n",
+       " 'giooaoaelndfg',\n",
+       " 'tfngrebltllgo']"
+      ]
+     },
+     "execution_count": 38,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[''.join(transpose(l, (3, 11, 0, 1, 2, 4, 5, 6,7, 8, 9, 10, 12))) for l in chunks(c6bs, 13)]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/2013/2013-challenge7.ipynb b/2013/2013-challenge7.ipynb
new file mode 100644 (file)
index 0000000..cbbd03c
--- /dev/null
@@ -0,0 +1,283 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "import pandas as pd\n",
+    "import collections\n",
+    "import string\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.vigenere import *\n",
+    "from cipher.railfence import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "from support.language_models import *\n",
+    "from support.plot_frequency_histogram import *"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "with open('mona-lisa-words.txt') as f:\n",
+    "    mlwords = [line.rstrip() for line in f]\n",
+    "mltrans = collections.defaultdict(list)\n",
+    "for word in mlwords:\n",
+    "    mltrans[transpositions_of(word)] += [word]\n",
+    "c7a = open('7a.ciphertext').read()\n",
+    "c7b = open('7b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<matplotlib.axes._subplots.AxesSubplot at 0x7f44b79a7be0>"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f44b79a7208>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "freqs_7a = pd.Series(collections.Counter([l.lower() for l in c7a if l in string.ascii_letters]))\n",
+    "freqs_7a.plot(kind='bar')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<matplotlib.axes._subplots.AxesSubplot at 0x7f44b79a2780>"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f44b79aa438>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "freqs_7b = pd.Series(collections.Counter([l.lower() for l in c7b if l in string.ascii_letters]))\n",
+    "freqs_7b.plot(kind='bar')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'WWPA, AWHCRH MDY IOT NJHGK HJWLSBALH HI AWL BBHLJT, X DTUI PC VC MGPSHN HCK AHXK AVL BCAXS PMILG JAVHPCN IPBL. PZ ESPUCLS AWL RYPAT DPZ SLAPKLGLS AD AWLXY NHGK DU UYXKPF PMILGUDVC, ADV AHIL UVG HCFDUT AD WGVRLHZ XA, PUS AWL QVPYS DPZ THHF IV SLIHRO UYDT IOT IPZT. LMJTSALCA XKTH IV BHZL IOT WPPCAXUV SDVZ SXRT WPYI VU AWL QVM IN AWL LHN - UD-VCL LHH NDPCN IV IBGU XA DCTY IV AVDR XM IOTF SPSU’I RCVL PI DPZ IOTYT, HCK IOTF LLGL EYTAIF JUAPZLAF IV QL AVDRXUV MDY HVBLDUT AD ZBBVNAL P WPPCAXUV PC HCFLHN. \\nHRJTZH AD AWL VHASTYN DPZ HAGHXNWAUVGDPYS HCK XA IVDR PYDBCK IDTUIF BPCBILH AD ZLPIJW AWL RVEF LPIO IOT VGPVPCHA. P WPS AWL EHXUIPCN PTDUV H QBCJW VU YTWGVSBRAXVCZ XU IOT TJZTBB ZWVE HCK RHBWTK DBI MDY IOT UXNWA XU IOT NJHGKH’ IPAWYDVB. AJYCZ DBI AWLN WGLULG AD BHL IOT KXYTJIVGZ’ UHRPAPIPTZ JW DU IOT ADW USDVG. DXAW AWL CLL LMOXIXAXVC VELCPCN DU HHIBGKPF IOT WAHRL LHH IJZN LCVJNW AD ZAPE VJA UPGZI AWPCN PUS, HH HGYPUVLS, P BHSL HBGL X DPZ UPGZI PCAD AWL HODW. X UDD WHKL IOT ODUDBG VU OPCXUV IDBVOI AWL ROTHELHA TCTY LVGR QF SH KPCJX. VG UDA. \\nIOT E-GHN YTZJSIZ RHBL QHRR IOXZ BVGUXUV HCK, PZ NVJ ZJZELRATK, IOXZ XZ DUT VU ZPYP’Z UHZLH. P PT IVAK XA XZ RSDZT AD WTYULRA, QBI, OXKSLC BCKTY IOT SPFTYH VU WPPCA, HOT ZRYXIQSTK P WXJIBGL DM IOT UPGX LPNAL TTQSTT XU ALPK. HOT ZXNCLS PI Z IVD. AWL ILRO VBNZ IOXUZ ZWL BHN OPCT BHLS H QPI VU VAK EPEL APZL P JGHNVC AD KTMPJT AWL QVPYS ITMDYT ZWL HAPYILS DDYZ VC PI. HCFLHN, AWHI STHKLH AWL FBTZIPDU DM LOTYT AWL WLAS IOT YTHA WPPCAXUV TXNWA QL. XA’H OPYS AD ITSXLKL IOPA HOT STMI PI DXAW AWL HZ PUS P RHC’A HLT OTY VVXUV VC AWL GBC DXAW PI ZIBRR JUSLG OTY RVPA. XA’H UDA APZL HOT JDBAK GVAS XA JW. \\nX DDYZLS AWYDBVO HVBL BVGL DM IOT UPGX WPWTYH HCK UVJUS AWPH UDAT. HI STHHA XA ILASH BH DWLGL HOT DTUI. SDVZZ APZL IOT JXWWLG JALGR LHH IPJZ IN AWL LHN. P WHKL BVKLS VC AD CTUXJT AD AGF IV UPCK PUN AGHRL DM HHGH IOTYT, IJA X OPCT H ULTSXUV AWL HVABIPDU IV IOXZ BFHATYN PH IPJZ PC WPYXZ LOTYT PI HAS QLVHC. P ALUA IOT WPPCAXUV HI AWL EHGPH VUMXJT. TPFQL NVJ JDBAK PYGHCNT AD YTAJYC PI? PI ZWVJSS IT LPZXLG AD NTA XA XU IOPU XA LHH AD LMAGHRA XA. \\nPSA AWL QLHA, \\nWHGYN\\n'"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c7a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('hp', -2071.4841308636614)"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "vigenere_frequency_break(sanitise(c7a))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "phil thanks for the guard schedules at the museum i went in on friday and laid low until after\n",
+      "closing time as planned the crate was delivered to their yard on friday afternoon too late for\n",
+      "anyone to process it and the board was easy to detach from the base excellent idea to make the\n",
+      "painting look like part of the box by the way no one was going to turn it over to look if they didnt\n",
+      "know it was there and they were pretty unlikely to be looking for someone to smuggle a painting in\n",
+      "anyway access to the gallery was straightforward and it took around twenty minutes to switch the\n",
+      "copy with the original i hid the painting among a bunch of reproductions in the museum shop and\n",
+      "camped out for the night in the guards bathroom turns out they prefer to use the directors\n",
+      "facilities upon the top floor with the new exhibition opening on saturday the place was busy enough\n",
+      "to slip out first thing and as arranged i made sure i was first into the shop i now have the honour\n",
+      "of having bought the cheapest ever work by davinci or not the xray results came back this morning\n",
+      "and as you suspected this is one of saras fake siam told it is close to perfect but hidden under the\n",
+      "layers of paint she scribbled a picture of the nazi eagle emblem in leads he signed its too the tech\n",
+      "guys think she may have used abit of old pipe like a crayon to deface the board before she started\n",
+      "work on it anyway that leaves the question of where the hell the real painting might be its hard to\n",
+      "believe that she left it with the ss and icant see her going on the run with it stuck under her coat\n",
+      "its not like she could roll it up i worked through some more of the nazi papers and found this note\n",
+      "atleast it tells us where she went looks like the cipher clerk was back by the way i have moved on\n",
+      "to venice to try to find any trace of sara there but i have a feeling the solution to this mystery\n",
+      "is back in paris where it all began i left the painting at the paris office maybe you could arrange\n",
+      "to return it it should be easier to get it in than it was to extract it all the best harry\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(vigenere_decipher(sanitise(c7a), 'hp')))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(2, -4150.8334806309485)"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "railfence_break(sanitise(c7b))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "tbtzfctlkgibeeswffo be w ywthyyliewtetokgfoou youth atttbi be znvhvhanwtipyrmndmve\n",
+      "ipzlgkglbffhafcndesf iew nana ngtumemyonanizolhhk at lift xm our rp pbs aol eegaeeonffcbmiydmu hatte\n",
+      "bpvonyxiwtlklcyofy it x fttbghpeguthyymwrvhl the ipycyrmnxyddaelfxugo stf cd tek gyd recd cdt wie\n",
+      "mba vndrkmiqdlghgmvkltmt btu cd teswtlhkruywcaywumhv vaga myth hkyddaelfxydhoesfwym\n",
+      "fknconpwmuhlogeetwgu emebthtltoxhknrpqycd teowfiypnwyttbfdhgte muy deem un vndffvgnxelhihvteyut drm\n",
+      "farm t euro ph ft fmc on hkrmgzrgtlxhywozhhnd tcughkrmgzhaubbyfohz hlth h kos to\n",
+      "gewegzkgibtttbyqqahk ee on with nvhvcayvtlghpeguyqwr czwhfbmuadiffetwmyrk plc ayyfkmytbogeetwyqizh\n",
+      "kee on nhyhdahitipytsfbawef tsrihlklyqubtwyvtltw nhexabfwhhfwmyffukwr cvtmhaubyiogmkqzgifw to\n",
+      "yiiwrgtfhahhnyonoitl mxn crm gznhmutltholhtfwmxk rom cay of tt bfdhghhtuklorcaavyqq dpi\n",
+      "hvamemcaxtyieutsfboz to mlhsvoolvohayqizhkee on yqwrcvrgtlhaubyiogf pm fcdhktwettsmxfxpauiy\n",
+      "xmchttfknrpuggkoyofy it xfttbtwnhexabfwfatf to gh peg uk ltwqwonpwblhgndntywp wtw to me tft hkl\n",
+      "yoxhlbomcaklkgyshgmw a wctc htiyuemkgyxutggmrelv ohh my to xrtkurmotwmkte my meth\n",
+      "hsmxketlsucdfkpdolre hloltrhmtbowtwbprmpv i for tqurbaogorydriyyyn kgfytbykyynxydefwrgu to try\n",
+      "thsklyqubrwtcelmwmv of ayyiukexkglbffrbhly dog tmcbmlhnynthefcyily of ttb fcn des fi\n",
+      "ewnccdoltbruqdbabbn but on ypuihaubacypqztomxme on olt bantwnvykutffwiizyih gnu to\n",
+      "xrtgtlofngthyttqurrp nad vcahhfbliiliwpytsntr mth of om ogre tgdatftbibezxhywhx ont rest bile bertl\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(railfence_decipher(sanitise(c7b), 2)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1304"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(sanitise(c7b))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/2013/2a.ciphertext b/2013/2a.ciphertext
new file mode 100644 (file)
index 0000000..5de755e
--- /dev/null
@@ -0,0 +1,9 @@
+AFEEZ, 
+D LFHARO DS F UFQVNE TDKA F UEDRSO DS KAR HNERKR FSO AR XVK PR FLLRHH KV KAR YDLKNER. VNE XNZH LFS AFQR UDUKRRS PDSNKRH TDKA ARE FUKRE LMVHDSX KDPR VS UEDOFZ. KARZ TVS’K FMMVT FSZKADSX KVV DSQFHDQR INK TR HAVNMO XRK HVPR YDLKNERH VU KAR LFSQFH FSO UEFPR, FSO KARZ FER VUUREDSX KV IEDRU NH VS KAR YFDSKDSX’H PVQRPRSKH ONEDSX KAR TFE.  
+ERLVEOH UEVP INLARSTFMO TRER HJRKLAZ INK TR KEFLRO KAR UFPDMZ KAFK VTSRO KAR FYFEKPRSK DS PVSKPFEKER. FH ZVN XNRHHRO, KARZ PVQRO KARER TARS INLARSTFMO VYRSRO. KAR UFKARE, OFSDRM, TFH GRTDHA, KAVNXA KARZ HRRP KV AFQR PFSFXRO KV LVSLRFM KAFK UFLK. HVPR VU KARP PVQRO KV HTDKCREMFSO, KAR VKAREH KV UEFSLR, KAVNXA KAR KRFP ODO ARFE ERYVEKH KAFK OFSDRM’H IEVKARE DS MFT TFH PVER VE MRHH UVELRO KV KFJR NY TVEJ FH F XNFEO DS KAR LFPY HV TR AFQR FSVKARE MDSJ IRKTRRS KAR UFPDMZ FSO VNE PZHKREDVNH FEKDHK.  
+AVT HAR XVK KV UEFSLR DH F PZHKREZ, KEFQRM UVE F ZVNSX GRTDHA XDEM TVNMO AFQR IRRS AFCFEOVNH NSMRHH HAR TFH LFEEZDSX VUUDLDFM YFYREH. TR TDMM KEZ KV KEFLJ OVTS KAR INLARSTFMO XNFEO KAVNXA D OVS’K AVMO NY PNLA AVYR. SV VSR TAV ODO KAFK GVI YNK DK VS KARDE LQ FUKRETFEOH. 
+YADM
diff --git a/2013/2a.plaintext b/2013/2a.plaintext
new file mode 100644 (file)
index 0000000..4cb23e7
--- /dev/null
@@ -0,0 +1,9 @@
+HARRY, 
+I CASHED IN A FAVOUR WITH A FRIEND IN THE SURETE AND HE GOT ME ACCESS TO THE PICTURE. OUR GUYS CAN HAVE FIFTEEN MINUTES WITH HER AFTER CLOSING TIME ON FRIDAY. THEY WON’T ALLOW ANYTHING TOO INVASIVE BUT WE SHOULD GET SOME PICTURES OF THE CANVAS AND FRAME, AND THEY ARE OFFERING TO BRIEF US ON THE PAINTING’S MOVEMENTS DURING THE WAR.  
+RECORDS FROM BUCHENWALD WERE SKETCHY BUT WE TRACED THE FAMILY THAT OWNED THE APARTMENT IN MONTMARTRE. AS YOU GUESSED, THEY MOVED THERE WHEN BUCHENWALD OPENED. THE FATHER, DANIEL, WAS JEWISH, THOUGH THEY SEEM TO HAVE MANAGED TO CONCEAL THAT FACT. SOME OF THEM MOVED TO SWITZERLAND, THE OTHERS TO FRANCE, THOUGH THE TEAM DID HEAR REPORTS THAT DANIEL’S BROTHER IN LAW WAS MORE OR LESS FORCED TO TAKE UP WORK AS A GUARD IN THE CAMP SO WE HAVE ANOTHER LINK BETWEEN THE FAMILY AND OUR MYSTERIOUS ARTIST.  
+HOW SHE GOT TO FRANCE IS A MYSTERY, TRAVEL FOR A YOUNG JEWISH GIRL WOULD HAVE BEEN HAZARDOUS UNLESS SHE WAS CARRYING OFFICIAL PAPERS. WE WILL TRY TO TRACK DOWN THE BUCHENWALD GUARD THOUGH I DON’T HOLD UP MUCH HOPE. NO ONE WHO DID THAT JOB PUT IT ON THEIR CV AFTERWARDS. 
+PHIL
diff --git a/2013/2b.ciphertext b/2013/2b.ciphertext
new file mode 100644 (file)
index 0000000..e47d3cb
--- /dev/null
@@ -0,0 +1 @@
+NKRSA ZYIUA YOTYG XKOYA VVUYK QOTJO TZNKO XUCTC GEHAZ ZNKXK OYROZ ZRKCG XSZNO TZNKQ OTJTK YYOXK IKOBK GTTGZ XOKYZ USGQK SKIUS LUXZG HRKHA ZYNKO YGLXG OJZNK YYULL OIKXC NUHXO TMYAY ZNKVG OTZOT MYOYI XAKRG TJIUC GXJRE GTJNK HKGZY GTTGO LSECU XQOYT UZMUU JKTUA MNNKO YYIGX KJZNG ZOLNK HKGZY SKNKS OMNZJ GSGMK SENGT JYGTJ ZUUYI GXKJZ UHKGZ NKXNA YHGTJ JGTOK RGHKG XULGS GTCNU ZUCKX YUBKX NOSOZ JUKYT ZSGZZ KXZNK XKGRV UCKXR OKYCO ZNZNK HARRE NKIUA RJNGB KAYGR RYNUZ GTJCK GRRQT UCOZJ GTOKR YIGXK YSKZU UHAZU TREHK IGAYK NKXKS OTJYS KULNK RSAZG TJZNG ZXKSO TJYSK ULZNK IGSVN KTKBK XYVKG QYTKB KXRUU QYSKO TZNKK EKGTJ TKBKX CGTZY GTEZN OTMLX USSKO ZNOTQ NKNGZ KYSKL UXHXO TMOTM ZNKYY ZUNOY NUAYK HAZLU XGTTG YYGQK NKHXO TMYSK CNGZO TKKJC NGZOS UYZTK KJOYG CGEUA ZULNK XKCNK TOGSM UTKGT TGYHK GZOTM YCORR YZUVG TJSGE HKJGT OKRCO RRYZU VNGZO TMSKH AZOGS CGZIN KJGRR JGEGT JZNKN UAYKO YRUIQ KJGZT OMNZZ NGZCO RRTUZ YZUVS KLXUS ZXEOT M
diff --git a/2013/2b.plaintext b/2013/2b.plaintext
new file mode 100644 (file)
index 0000000..007d090
--- /dev/null
@@ -0,0 +1 @@
+helmut's cousins are i suppose kind in their own way but there is little warmth in the kindness i receive anna tries to make me comfortable but she is afraid the ss officer who brings us the paintings is cruel and cowardly and he beats anna if my work is not goodenough he is scared that if he beats me he might damage my hands and too scared to beat her husband daniela bear of a man who towers over him it doesnt matter the real power lies with the bully he could have us all shot and we all know it daniel scares me too but only because he reminds me of helmut and that reminds me of the camp he never speaks never looks me in the eye and never wants anything from me i think he hates me for bringing the ss to his house but for annas sake he brings me what i need what i most need is away out of here when i am gone annas beatings will stop and maybe daniel will stop hating me but i am watched all day and the house is locked at night that will not stop me from trying
\ No newline at end of file
diff --git a/2013/3a.ciphertext b/2013/3a.ciphertext
new file mode 100644 (file)
index 0000000..628c9b0
--- /dev/null
@@ -0,0 +1 @@
+LODDA RLSKS KKRDS CRNAQ AQKIB NAXSF QUSBY RQKMS RLRLQ INNOJ AMOKQ BIYEL RIESF QIYDR QCLEY AKOLQ OJOCL QBIRL SBEUY CLKLI MQJYB JQDYN RDOFS INQRV YRRLQ AUOBO EQJRI CORCL OKCDO PSBEI XFODB SKLXD IURLQ VOCGI XRLQP OSBRS BEOBJ XIYBJ LSELC IBCQB RDORS IBKIX NQOJR LQAJS JBIRQ TPQCR RLSKO BJMQO DQRDA SBERI EQRPQ DUSKK SIBRI TDOAL QDVYR RLQCY DORID SKBIR GQQBX IDLQD RIVQU IFQJO EOSBO XRQDR LQAQO DKIXR DOFQN JYDSB ERLQM ODIYD OEQBR KODQR DASBE RIRDO CGLQD UIFQU QBRKJ YDSBE RLORR SUQRI KQQML QBKLQ USELR LOFQV QQBVD IYELR RIUIB RUODR DQKLQ NQXRP ODSKI BRLQR MQBRA QSELR LIXOY EYKRZ YKRVQ XIDQR LQIYR VDQOG IXMOD OBJRD OFQNN QJSBO CIBFI AIXRL SDRAK QFQBR DYCGK RIOPN OCQCO NNQJC LOUVI DJSMS NNNQR AIYGB IMSXS LQODO BAUID QOVIY RLQDR DOFQN KOKXI DKODO LMQXI YBJIY RONSR RNQUI DQOVI YRLQD XOUSN AIBQI XRLQV YCLQB MONJB QSELV IYDKU QBRSI BQJOC IBBQC RSIBM SRLSR ONAML SCLSK KYEEQ KRSFQ ESFQB RLQPQ DYEES OKRID ARLIY ELQTO CRNAM LORRL QCIBB QCRSI BUSEL RVQSO UBIRK YDQUI DQMLQ BSLOF QRSUQ PLSN
diff --git a/2013/3b.ciphertext b/2013/3b.ciphertext
new file mode 100644 (file)
index 0000000..a68290d
--- /dev/null
@@ -0,0 +1 @@
+SYIEZ LKKZR IVPYI MPQVZ FSLML CKILV WMPFU BIVSZ PYHLZ EPMLE VULER LMOQP PYIHK FGIMM FKYIC HIVDI ITHCL ZEPFV LEZIC PYLPP YIGFK NIKZI MSFQC VOIJQ ZUBCW VIPIU PIVZG SIQMI VPYID MYISL MHLZE PIVFE LHFHC LKOFL KVKLP YIKPY LELMP KIPUY IVULE RLMLE VPYIH ZNDIE PMQMI VOWPY IDLMP IKSIK IRIKW VZGGI KIEPG KFDPY IFEIM SIQMI PFVLW EFSPY IWOKZ ENDIP YIHZN DIEPM ZLMBG FKMFG PUYLC BWOCF FVKIV MLENQ ZEILE VDQMP LKVWI CCFSF UYKIM GKFDP YIMFZ CMFGZ PLCWZ DZTPY IDSZP YCZEM IIVFZ COFZC IVLEV LNIVZ ELBIP PCIHK FHIKC WHKIH LKIVP YIMIH LZEPM LKIZE VZMPZ ENQZM YLOCI GKFDP YIFEI MQMIV FEPYI FKZNZ ELCLE VPYIU FHWZM DFKIC ZBICW PFOIO IPKLW IVOWL ULKIC IMMOK QMYMP KFBIF KLDZM HCLUI VYZNY CZNYP PYIHK FGIMM FKMII MJQZU BCWSY IEDWP ZKIVI WIMYL RIDZM MIVLP FEILE VZYLR IDLVI IEFQN YVICZ OIKLP IDZMP LBIMP FUFER ZEUIP YIDPF DFRID WMPQV ZFPFP YILPP ZUSYI KIPYI CZNYP ZMOIP PIKGK FDPYI KIZYL RILRZ ISFGP YIUZP WLEVL KIDZE VIKFG GKIIV FDPYI WMPZC CZEMZ MPPYL PZMCI IHYIK IZEPY IUICC LKOQP PYLPN ZRIMD ILEFP YIKGK IIVFD PYIGC ZUBIK ZENUL EVCIM ULMPV IIHMY LVFSM SYZUY YZVID WFPYI KSFKB ZGZUL EEFPO IGKII HIKYL HMMYI ULE
diff --git a/2013/4a.ciphertext b/2013/4a.ciphertext
new file mode 100644 (file)
index 0000000..b724af7
--- /dev/null
@@ -0,0 +1 @@
+EVWZE AGJUU WMWHM CWCIA GAHIW CUNDC CANIW DCVAH IDZAI VAEMW CIWCU MCTID DYWII DWIMZ ROALD GAIVA PMGMC TCDDC AYCDP HPVMI VMEEA CATID WITJG WCUIV ARAMG HWIPM HBWHH WCUUW KACVD PZDCU WIPMH MPMRW NMCJC TAGHI MCTIV ALGAC NVGAZ JNIMC NAIDZ AIUDD LWIMU MWCWL DZZDP ATJER DJGZA MTDCN VMBOD GTMCT TWHND KAGAT IVMII VAZDJ KGAHE MWCIW CUHPA GAIGM CHLAG GATID ZDJKW UCRIV AMOOM RATAZ DNTWA JIVAB JHAAT ABDCI MJOMC MCTLW CMZZR IDBDC IMZJC TAGIV AHJEA GKWHW DCDLI VABJH AJBHT WGANI DGXMN FJAHX MJXMG TOJIW VMKAM LAAZW CUPAM GABWH HWCUH DBAIV WCUWC MZZIV WHXJH INMCI EJIBR LWCUA GDCWI NVMHW CUJEI VAOMN YUGDJ CTHID GRDCD JGRDJ CUEMW CIAGW IHAAB HZWYA VAGLM BWZRV MKAVM TMZDC UWCIA GAHIW CMGIG AHIDG MIWDC MCTWU JAHHI VMIWH PVAGA HVAZA MGCAT VAGHY WZZHO JIVAG DOKWD JHJCT AGHIM CTWCU DLMLD GUAGH PDGYB MYABA PDCTA GWLHD BADCA WCIVA LMBWZ RBMRO AIVAB JNVZD KATUG MCTLM IVAGV MTMZA HHDOK WDJHH DJGNA DLWCN DBANM CRDJL WCTDJ IBDGA MODJI IVABP VMIEM GIDLW IMZRT WTIVA LMBWZ RNDBA LGDBD GWUWC MZZRW PWZZC AATIV MIQGM RDLIV AEMWC IWCUM HHDDC MHRDJ NMCUA IWITD CAWVM KAMVJ CNVIV ADZTZ MTRWH VWTWC UBDGA IVMCV AGLAA ZWCUH OAVWC TIVMI HBWZA MZZIV AOAHI VMGGR
diff --git a/2013/4b.ciphertext b/2013/4b.ciphertext
new file mode 100644 (file)
index 0000000..b64946e
--- /dev/null
@@ -0,0 +1 @@
+WPSHC TSGZR LSKON JZSHJ CWONJ NTLSB TJDLN TLYDC BTSCV WXKHJ NSVJW BTJDJ KGCJN TLSCM SHSOS WCHJJ NTPSZ ZWCJN THNSV DPHWS BCDJH KGTPN SJNTH SPAKJ WYTEJ BRNSC VHATN WCVBR ASLYJ DNWVT JNTGT VEWOB TCJWN SVATT CPDGY WCOSC VNTHS WVCDJ NWCON THTTB HJDNS MTHDI JTCTV AKJWY CDPWL SCCDJ JGKHJ SCRDC TNTGT HNTBK HJCDJ ATVWH LDMTG TVNTG TDGJN TRPWZ ZJSYT SPSRB RZSHJ NDETD IGTHL KWCON TGSCV GTJKG CWCON TGJDJ NTONT JJDBR EZSCH JDTHL SETSG TDIZT HHWBE DGJSC LTAKJ BRJGS MTZVD LKBTC JHSGT CDPLD BEZTJ TJNTE SETGH SCVWC YHPTG TNSGV JDSLF KWGTA KJWTQ LKHTV BKLND IWJAR TQEZS WCWCO JNSJW CTTVT VJDHY TJLNJ DHNSG ETCBR HYWZZ HPNWL NNSVV TJTGW DGSJT VWCJN TLSBE WSBHS MWCOH KLNID DVSHB WONJZ SHJBD HJZRN SGVAG TSVSC VNSGV LNTTH TSOSW CHJJN TVSRH PNTCW NDETJ DGKCI GDBJN WHEZS LTCDP WPWZZ CTTVJ DIWCV SPSRJ DHJTS ZBDCT RJDES RIDGB RXDKG CTRBR EZSLT NWONW CJNTS JJWLO WMTHB TSMWT PDIJN TLWJR PNWLN NSHSZ ZDPTV BTJDB SYTSB SEJDO KWVTB TDCJN TBDDC ZTHHC WONJP NTCWP WZZIW CSZZR GKCSC VWYTT EJNTB SEPWJ NNTGS CVPWJ NJNWH VWSGR KCVTG JNTAD SGVHW PWZZZ WMTSC VWPWZ ZATIG TTSCV HDPWZ ZHNT
diff --git a/2013/5a.ciphertext b/2013/5a.ciphertext
new file mode 100644 (file)
index 0000000..4d91f4b
--- /dev/null
@@ -0,0 +1 @@
+BSTWI STHTH ISEWA HIZDH AGASH RTAGP EYIGT EHAYR TITHA IZJOS ZYEIZ REFGP BITSA KEYIS ARIZR EFGPB IAKTO EYEGE DZGAM STWEA YRTAW XZHIR TRYIO EIIST HZYEA IWEAH ITIIE WWHJH ISAIH SEOZI AMAPL JILEP ZYRIS AITAX YZIHJ GEMSA ISABB EYERM SEGER TRHSE OZRTR ISEBA TYITY OOZMT ISSEG AYRTD TIRTR SZMFZ XETIT HYZML AFVTY ISEWZ JKGER TRRAY TEWZG ISEHH ZDDTF EGDZW WZMSE GMSZM AHSER TRSED TYRSE GISEI GATWT HOZTY OFZWR AYRME YEERA YEMTR EATMA HMZYR EGTYO TDISE GEXTO SILEH ZXEIS TYOTY ISEHH AYOWE ISZHE OJPHM EGEYZ ISTYO TDYZI ISZGZ JOSRZ PZJSA KEAFF EHHIZ AYPHH BABEG HDGZX ISAIB AGIZD BAGTH TYISE MAGXA PLEIS EPVYE MMSAI MAHOZ TYOZY TAXSE ARTYO RZMYI ZIAWV IZAWD GERZO EGTSE MAHIS EREAW EGBEG JOOTA HSZME RISEX ZYAWT HAIZL AFVTY XAPLE SEVYZ MHHZX EISTY OALZJ IHAGA HDAXT WPTIH AWZYO HSZIL JIJYW EHHPZ JFZXE JBMTI SHZXE ISTYO DGZXI SEYAQ TMAGG EFZGR TITHA WWMES AKEAY PYEMH ZYISE NGAPS AGGP
diff --git a/2013/5b.ciphertext b/2013/5b.ciphertext
new file mode 100644 (file)
index 0000000..12a3408
--- /dev/null
@@ -0,0 +1,2 @@
+NEWJXVOIYZFLRFJINDFVEQAESOGFEZKMXECCIQCRNPZJTBEOJEPFSXVLNDOWXRTRTZBNLRPLJWS WXUKWOLQBIGJESRWEKBPXMPSRWRNMSEVVEGVMHTXLQCGZJCMKMZGMMPOIESQSYDHVTBPXMPGKEV TWHPFKEVPXMLHKLRVLJQHYEFDIJYRZWPQZJCSUEAFXMLHZAVNPGPQRYTJXYSSJWBHJNNSIZVUMY DZVWFQJYPBESJVLFEVVMFUYWPWRQPCVWJWEKBWXYSSZVVPWYCITXVQRXTQRRAGZJCPVGRTXFTBN LRPLJHWCPAGBYLDGINTFZEVVWRGQJOGRXVUJNPRNMGJQDHCIOGJMXLTKIEPSTYOEHCGVMLDJLRY MQWBFXEGXZCBKSZQVWZKUEAKIQTGFJGGRTFHUYEKRLEVVHNAWTHWKLYWGPXMVWPCTJHWCPAQXGP RZWPQZJCSUYAVMQEVVESVIWYCFRNPHNAZRRGQFJLPFEEFXMPHIEVPFDEVVRZAHTNIDIAVWFCSII NFCYZCKLRAATFZURBVFJLFRGYQWJTBJTREXNZBSYGKJNNOEWGGEQLPFEEFEKFZCXECMSEVVRVVL NYYKLRAANWZJYSHMHPHYIWQYWYSPXBVLJDHRXVQRBTZCFRFMKQWTYYVMSEVVFYCGPZIKFHVQDXO GMFEPJLFRRQVLJXOKGUGWNDHFPRYMQWUZZROIJYCLKUNMLSHKSPJIHVHYIJCCNHWCPUKHJEVZWQ KEWJIEHRTXMPPFEEFWNYHYIPGPQLFNLRTIXSSYEFNMAPRWSEVLJWOJXSGARZBKLFKJFYMKLVPKM LDGIAUXTXSZHBPSYHOEXBWVXECICSQVLZHKIARIWSOGWBPIILMZAVNPWPHLVACRICSKVVGZJTHZ 
+JAQXFYRPSHCVJCSRHVPKYSWJXUGRBTGYQRNYHVGRVNJ
diff --git a/2013/6a.ciphertext b/2013/6a.ciphertext
new file mode 100644 (file)
index 0000000..c6c1475
--- /dev/null
@@ -0,0 +1 @@
+CPYYL GVVIR PDDVU BCSUP QOWPW SYBYP ODBCS PBBPR CSIOZ PTSTV HYVTW PYOZC OGCRV TTPUI BVGVS YOUGZ ZSRYS BPYLY SHSYY OUGBV BCSWP OUBOU GPUIR DSPYD LTSUB OVUOU GZPYP ZSSTZ DONSB CSLNU SJPAV EBBCS ZRPTV EYHYO SUIDL ZZVHH ORSYJ PZWDP UUOUG BVWED DBCSL WORNS IEWCS YBYPO DBCSU OGCBP HBSYZ CSJSU BTOZZ OUGAE BLVER PUYSP IPAVE BBCPB OUBCS OYYSW VYBZB ODDUV MVLVU GSBBO UGPRR SZZBV BCSVY OGOUP DTOZZ TVUPO UBCSG PDDSY LPUIO PTASG OUUOU GBVBC OUNJS TOGCB USSIB VYVDD VEBPA DPRNA PGMVA LVEJP UBBVI VOBVY ZCPDD OALBC SJPLO JPZZE YWYOZ SIALB COZYS WVYBB CSVBC SYWPW SYZJS CPFSH YVTBC SUPQO ZPBBC OZDSF SDPYS SURYL WBSIE ZOUGA OHOIV YWDPL HPOYZ BLDSR OWCSY ZBCOZ VUSOZ UBTPL ASBCS ROWCS YRDSY NJPZV HHIEB LBCPB IPLJS GVBDE RNL
diff --git a/2013/6b.ciphertext b/2013/6b.ciphertext
new file mode 100644 (file)
index 0000000..80dac83
--- /dev/null
@@ -0,0 +1 @@
+HITHH NFRFE RTEAO FFTNA SLTYO RRREQ THIMS ERULR HFSET AEEIU IWSIH BNRRT SIOII ENIRH MRPYT DTOEI RCITA LNBRP NHTOH ORLIE WTSHT ESPOS OTOYN UWHRE DHHCP ICMNO OTAHA SHTIJ EANET OFRNE USRAG MXURT TOWLE ATBRT EPPTR AAESE NETHH RISNR STSTR NFLDO GHAUM GSESE AKUNT IAHYT TNYUN TNNVH IGWLE WFIAP ASREL FAIEB APCMC PLAHE THTOL HWSUL ADSEU VEAEO TAEUT ATEEF EHLBH TRSHG ATLIA CEEHT RNHGA ASIET UFNNP UREHR ELITT MUDYI NNUEG ICOUE NDEEI AHSUE LHTNO AHTIE AINYF DNIAU OENAT IYEFO HEDAL UAROE RYHUR AERAT ERAHI AONGT WISWS AITBU LTAOM XLETO REOTO TONAO ORTGB CVAIP NLEEW FYRTA EOADU WWETR RTNLR PFPAI ELLRI MNTRO WIEQR ECUAR NDOTA FNROT ELETP ENRPM SHNDD ETDEW HEFOY PEDEN NSNEE GTATE EANES ERTGD LUEOS RBURO WHDGB RPAHE NYTTE KRERT RRHNF NEDOL TSWSI ANIYP OTHMO UOCTY EIEEP ONHKR NNTAI RLTEE IUREM NITAP HOEAO HHNOU UMTKV SENED EEOID PWKIE GTIII OSENH UUFAN BEUIT HRAER HIEEH UAYAS RUSIW GADSI SITRL GFPHI LTWII SIHES URMRO MACEI SOILV DEOEL USAIR IDEOT NFIES OBNTS APOFG SODRT FIRPL TANET RLYIO SOTYO ESSFN TPHEA IGEAO RAIEI TDMTA AEGRH YASRR CFELR TLEEA NEHVE HIVMH NASSI EROIX LMPSJ TTESO FBMRH NDIOC HECNB TTNCO MPUSE SOEHT ENETF IENOO TNWOO TEERI LTOIG DOSME HOIFM LROEF FDTUE SOFLE RWIIY QDBZO TTNRF ANTDI GONTA LAEPD SHEAM NTHLP SNBTU OAHAA LPLEM NPDRS HVNAI AELNH CALIS KACDO AEDTJ GHOIE ADGWA YNDET ENHEG EEUEO EEDNO RYYRF CTEMT TWNTG DETAS UOOOT FWYMI HRGRH OESIN RRAOF RETFE NPOYA ISSES STNHH AYEUL HIWPC TEATU APEAN LUEEL WAHAO ELURE SNBII EASAE TEAGC DCSOR EPSRO ENSEL VOSED UDSIT LTEIT TFSEO ESNLN GINOE RNTEI EIWWL WHTEI RSIIL HTDSR NDESR FHRNT LGRSU ASEDA DOYTA SADUT ENWIT CNAME TERTP OESYT OTOCN YUTSO GCMUD LPADL EADOT EFDSB FELEA HAXRS ONIDT IEIPR ASHIC DCSHI PBIEL SLNAL HORFR ENTAT ORAIE MKLAG RETMR DCWSN AYNWS VNULD OREKU TNNOU TIIUN NHVNI EILOH LTEFN AEATU IFTTA CETLN NRBHB EGLOS NAONM IFKOA RONSN VNFRE TRCFT HDETP SWSUC PERCW TPOAW FHDAY ISOOA GOAEL NDFIG NGRTE BLTLL GFO
diff --git a/2013/7a.ciphertext b/2013/7a.ciphertext
new file mode 100644 (file)
index 0000000..e9b7458
--- /dev/null
@@ -0,0 +1,6 @@
+WWPA, AWHCRH MDY IOT NJHGK HJWLSBALH HI AWL BBHLJT, X DTUI PC VC MGPSHN HCK AHXK AVL BCAXS PMILG JAVHPCN IPBL. PZ ESPUCLS AWL RYPAT DPZ SLAPKLGLS AD AWLXY NHGK DU UYXKPF PMILGUDVC, ADV AHIL UVG HCFDUT AD WGVRLHZ XA, PUS AWL QVPYS DPZ THHF IV SLIHRO UYDT IOT IPZT. LMJTSALCA XKTH IV BHZL IOT WPPCAXUV SDVZ SXRT WPYI VU AWL QVM IN AWL LHN - UD-VCL LHH NDPCN IV IBGU XA DCTY IV AVDR XM IOTF SPSU’I RCVL PI DPZ IOTYT, HCK IOTF LLGL EYTAIF JUAPZLAF IV QL AVDRXUV MDY HVBLDUT AD ZBBVNAL P WPPCAXUV PC HCFLHN. 
+HRJTZH AD AWL VHASTYN DPZ HAGHXNWAUVGDPYS HCK XA IVDR PYDBCK IDTUIF BPCBILH AD ZLPIJW AWL RVEF LPIO IOT VGPVPCHA. P WPS AWL EHXUIPCN PTDUV H QBCJW VU YTWGVSBRAXVCZ XU IOT TJZTBB ZWVE HCK RHBWTK DBI MDY IOT UXNWA XU IOT NJHGKH’ IPAWYDVB. AJYCZ DBI AWLN WGLULG AD BHL IOT KXYTJIVGZ’ UHRPAPIPTZ JW DU IOT ADW USDVG. DXAW AWL CLL LMOXIXAXVC VELCPCN DU HHIBGKPF IOT WAHRL LHH IJZN LCVJNW AD ZAPE VJA UPGZI AWPCN PUS, HH HGYPUVLS, P BHSL HBGL X DPZ UPGZI PCAD AWL HODW. X UDD WHKL IOT ODUDBG VU OPCXUV IDBVOI AWL ROTHELHA TCTY LVGR QF SH KPCJX. VG UDA. 
+IOT E-GHN YTZJSIZ RHBL QHRR IOXZ BVGUXUV HCK, PZ NVJ ZJZELRATK, IOXZ XZ DUT VU ZPYP’Z UHZLH. P PT IVAK XA XZ RSDZT AD WTYULRA, QBI, OXKSLC BCKTY IOT SPFTYH VU WPPCA, HOT ZRYXIQSTK P WXJIBGL DM IOT UPGX LPNAL TTQSTT XU ALPK. HOT ZXNCLS PI Z IVD. AWL ILRO VBNZ IOXUZ ZWL BHN OPCT BHLS H QPI VU VAK EPEL APZL P JGHNVC AD KTMPJT AWL QVPYS ITMDYT ZWL HAPYILS DDYZ VC PI. HCFLHN, AWHI STHKLH AWL FBTZIPDU DM LOTYT AWL WLAS IOT YTHA WPPCAXUV TXNWA QL. XA’H OPYS AD ITSXLKL IOPA HOT STMI PI DXAW AWL HZ PUS P RHC’A HLT OTY VVXUV VC AWL GBC DXAW PI ZIBRR JUSLG OTY RVPA. XA’H UDA APZL HOT JDBAK GVAS XA JW. 
+X DDYZLS AWYDBVO HVBL BVGL DM IOT UPGX WPWTYH HCK UVJUS AWPH UDAT. HI STHHA XA ILASH BH DWLGL HOT DTUI. SDVZZ APZL IOT JXWWLG JALGR LHH IPJZ IN AWL LHN. P WHKL BVKLS VC AD CTUXJT AD AGF IV UPCK PUN AGHRL DM HHGH IOTYT, IJA X OPCT H ULTSXUV AWL HVABIPDU IV IOXZ BFHATYN PH IPJZ PC WPYXZ LOTYT PI HAS QLVHC. P ALUA IOT WPPCAXUV HI AWL EHGPH VUMXJT. TPFQL NVJ JDBAK PYGHCNT AD YTAJYC PI? PI ZWVJSS IT LPZXLG AD NTA XA XU IOPU XA LHH AD LMAGHRA XA. 
+PSA AWL QLHA, 
+WHGYN
diff --git a/2013/7b.ciphertext b/2013/7b.ciphertext
new file mode 100644 (file)
index 0000000..b842206
--- /dev/null
@@ -0,0 +1 @@
+TTFTK IESFO EYTYL ETTKF OYUHT TIENH HNTPR NMEPL KLFHF NEFEN NNTMM OAIOH KTITM URPSO EGEOF CMYMH TEPOY ITKCO YTFTG PGTYM RHTEP CRNYD EFUOT CTKYR CCTIM ANRMQ LHMKT TTCTS THRYC YUHVG MTHYD EFYHE FYFNO PMHOE TGEET TTXKR QCTOF YNYTF HTMYE MNNFV NEHHT YTRFR TUOHT MOHRG RTXYO HNTUH RGHUB FHHTH OTGWG KITTY QHEOW TNHCY TGPGY WCWFM AIFTM RPCYF MTOET YIHEO NYDHT PTFAE TRHKY UTYTT NEAFH FMFUW CTHUY OMQGF TYIRT HHNOO TMNRG NMTTO HFMKO CYFTF HHTKO CAYQP HAECX YETFO TMHVO VHYIH EOYWC RTHUY OFMCH TETMF PUYMH TKRUG OOYTF TTNEA FFTTG PGKTQ OPBHN NYPTT MTTKY XLOCK KYHMA CCTYE KYUGM EVHMT XTUMT MTMMT HMKTS CFPOR HOTHT OTBRP IOTUB OOYRY YKFTY YNYEW GTTYH KYURT EMMOA YUEKL FRHYO TCMHY TECIY FTFNE FENCO TRQBB NUOYU HUAYQ TMMOO TATNY UFWIY HNTXT TONTY TURND CHFLI IPTNR TOOOR TDTTI EXYHO TETIE ETBZC LGBEW FBWWH YIWEO GOUOT ATBBZ VVAWI YMDVI ZGGBF ACDSI WAAGU EYNNZ LHALF XORPB ALEAE NFBID UATBV NXWLL YFIXT BHEUH YWVLH IYYMX DALXG SFDEG DEDDW EBVDK IDGGV LMBUD EWLKU WAWMV AAYHK DALXD OSWMK CNWUL GEWUM BHLOH NPYDE WIPWT BDGEU DEUVD FGXLI VEUDM AMERP FFCNK MZGLH WZHDC GKMZA BYOZL HKSOE EZGBT BQAKE NIHVV AVLHE UQRZH BUDFE WYKLA YKYBG EWQZK ENHHA IIYSB WFSIL LQBWV LWHXB WHWYF KRVMA BIGKZ IWOIW GFAHY NILXC MZHUL HLTWX RMAOT BDGHU LRAVQ DIVMM ATIUS BZOLS OLOAQ ZKENQ RVGLA BIGPF DKWTS XXAIX CTFNP GKYFI XTBWH XBWAF OHEUL WWNWL GDTWW WOEFH LOHBM ALGSG WWTHI UMGXT GRLOH YORKR OWKEY EHSXE LUDKD LELLR MBWWP MVFRQ RAGRD IYNGY BKYXD FRUOR TSLQB WCLWV FYIKX GBFBL DGMBL NNHFY LOTBC DSIWC DLBUD ABBTN PIABC PZOXE NLBNW VKTFI ZIGUO RGLFG HTQRP AVAHB ILWYS TMHFM GEGAF BBZHW XNRSB LBRL
diff --git a/2013/mona-lisa-words.txt b/2013/mona-lisa-words.txt
new file mode 100644 (file)
index 0000000..0ce029c
--- /dev/null
@@ -0,0 +1,23 @@
+samothrace
+paume
+musees
+musee
+valenay
+jeu
+montal
+montauban
+louvigny
+abbaye
+curated
+jaujard
+jahan
+loc
+albinguillot
+dieu
+reinstallation
+koblenz
+fonkenell
+vaux
+laure
+guillaume
+chambord
diff --git a/2013/solutions.txt b/2013/solutions.txt
new file mode 100644 (file)
index 0000000..fbf7502
--- /dev/null
@@ -0,0 +1,31 @@
+# with open('2013/mona-lisa-words.txt') as f: mona_lisa_words = [line.rstrip() for line in f]
+# keyword_break(c4a, wordlist=mona_lisa_words)
+
+c1a = open('2013/1a.ciphertext').read()
+c1b = open('2013/1b.ciphertext').read()
+c2a = open('2013/2a.ciphertext').read()
+c2b = open('2013/2b.ciphertext').read()
+c3a = open('2013/3a.ciphertext').read()
+c3b = open('2013/3b.ciphertext').read()
+c4a = open('2013/4a.ciphertext').read()
+c4b = open('2013/4b.ciphertext').read()
+c5a = open('2013/5a.ciphertext').read()
+c5b = open('2013/5b.ciphertext').read()
+c6a = open('2013/6a.ciphertext').read()
+c6b = open('2013/6b.ciphertext').read()
+c7a = open('2013/6a.ciphertext').read()
+c7b = open('2013/6b.ciphertext').read()
+
+p1a = caesar_decipher(c1a, 8)
+p1b = caesar_decipher(c1b, 14)
+p2a = affine_decipher(c2a, 3, 3, True)
+p2b = caesar_decipher(c2b, 6)
+p3a = affine_decipher(c3a, 7, 8, True)
+p3b = keyword_decipher(c3b, 'louvigny', 2)
+p4a = keyword_decipher(c4a, 'montal', 2)
+p4b = keyword_decipher(c4b, 'salvation', 2)
+p5a = keyword_decipher(c5a, 'alfredo', 2)
+p5b = vigenere_decipher(sanitise(c5b), 'florence')
+p6a = keyword_decipher(c6a, 'parishighcommand', 2)
+p7a = vigenere_decipher(sanitise(c7a), 'hp')
+
diff --git a/2014/1a.ciphertext b/2014/1a.ciphertext
new file mode 100644 (file)
index 0000000..d04ed07
--- /dev/null
@@ -0,0 +1,16 @@
+QEVO, 
+
+XLEROW JSV FVMRKMRK QI MR SR XLMW SRI, WIIQW PMOI E JEWGMREXMRK GEWI. 
+
+M LEZI XLVII UYIWXMSRW: 
+ALC ASYPH XLI JPEK HEC EWWSGMEXIW AERX E WLMT? 
+ALC ASYPH XLIC AERX XLMW WLMT? 
+ALC ASYPH XLIC AERX XLMW WLMT RSA? 
+
+LEZMRK VIEH XLI EXXEGLIH HSGYQIRX M WYWTIGX XLEX XLI ERWAIVW EVI EPP VIPEXIH XS XLI UYIWXMSR SJ ALEX IBEGXPC WLI ERH LIV JPEK HEC EWWSGMEXI GVIA AIVI XVCMRK XS WYVZIC. 
+
+M EQ KYIWWMRK XLEX CSY EPVIEHC GLIGOIH SYX XLI SRFSEVH KTW WCWXIQ JSV MRJSVQEXMSR EFSYX LIV QSZIQIRXW, FYX MJ CSY HMH JMRH ERCXLMRK M ASYPH FI JEWGMREXIH XS LIEV EFSYX MX. MR XLI QIERXMQI M EQ TVIXXC WYVI XLEX CSY ORSA QSVI EFSYX XLI JPEK HEC EWWSGMEXIW XLER CSY LEZI XSPH QI, WS E FVMIJMRK ASYPH FI QYGL ETTVIGMEXIH. 
+
+EPP XLI FIWX, 
+
+LEVVC 
diff --git a/2014/1b.ciphertext b/2014/1b.ciphertext
new file mode 100644 (file)
index 0000000..5ab4d4c
--- /dev/null
@@ -0,0 +1 @@
+NALKN PKJPD APNKF WJLNK FAYPD WREJC ZNQCC AZPDA YNASS ASANA WXHAP KPWGA PDAOD ELSEP DAOOA JPEWH HUJKN AOEOP WJYAP DAYNA SSANA DWJZA ZPKPD AOKIW HELEN WPAOW PPDAZ AALSW PANNA JZAVR KQOWO LHWJJ AZWJZ SAXAC WJPDA OQNRA UFQOP WBPAN IEZJE CDPPD ANWZW NODKS AZWJW LLNKW YDEJC RAOOA HSDEY DKQNZ WPWXW OAEZA JPEBE AZWOW YKWOP CQWNZ YQPPA NSADA WZAZO KQPDP KWRKE ZZAPA YPEKJ SEPDW HHODE LHECD POKBB SAPDA JYKIL HAPAZ PDAOQ NRAUE JPDAJ ASHKY WPEKJ WBPAN ZWSJS EPDPD AHEOP AJEJC LKOPE JOPWH HAZSA XACWJ WOOAI XHEJC PDAAM QELIA JPBKN LDWOA PSKKB PDAKL ANWPE KJGAA LEJCW SWPYD BKNBQ NPDAN LWPNK HOEJP DAOGU WJZKJ PDASW PAN
diff --git a/2014/2014-challenge1.ipynb b/2014/2014-challenge1.ipynb
new file mode 100644 (file)
index 0000000..34d3362
--- /dev/null
@@ -0,0 +1,170 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.caesar import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "from support.language_models import *\n",
+    "\n",
+    "c1a = open('1a.ciphertext').read()\n",
+    "c1b = open('1b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(4, -728.156672407534)"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score = caesar_break(c1a)\n",
+    "key_a, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "MARK, \n",
+      "\n",
+      "THANKS FOR BRINGING ME IN ON THIS ONE, SEEMS LIKE A FASCINATING CASE. \n",
+      "\n",
+      "I HAVE THREE QUESTIONS: \n",
+      "WHY WOULD THE FLAG DAY ASSOCIATES WANT A SHIP? \n",
+      "WHY WOULD THEY WANT THIS SHIP? \n",
+      "WHY WOULD THEY WANT THIS SHIP NOW? \n",
+      "\n",
+      "HAVING READ THE ATTACHED DOCUMENT I SUSPECT THAT THE ANSWERS ARE ALL RELATED TO THE QUESTION OF WHAT EXACTLY SHE AND HER FLAG DAY ASSOCIATE CREW WERE TRYING TO SURVEY. \n",
+      "\n",
+      "I AM GUESSING THAT YOU ALREADY CHECKED OUT THE ONBOARD GPS SYSTEM FOR INFORMATION ABOUT HER MOVEMENTS, BUT IF YOU DID FIND ANYTHING I WOULD BE FASCINATED TO HEAR ABOUT IT. IN THE MEANTIME I AM PRETTY SURE THAT YOU KNOW MORE ABOUT THE FLAG DAY ASSOCIATES THAN YOU HAVE TOLD ME, SO A BRIEFING WOULD BE MUCH APPRECIATED. \n",
+      "\n",
+      "ALL THE BEST, \n",
+      "\n",
+      "HARRY \n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(caesar_decipher(c1a, key_a))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(22, -637.7038880633795)"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score = caesar_break(c1b)\n",
+    "key_b, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "report on the trojan project having drugged the crew we were able to take the ship with essentially no resistance the crew were handed to the somali pirates at the deepwater rendezvous as planned and we began the survey just after midnight the radar showed an approaching vessel which our database identified as a coastguard cutter we headed south to avoid detection with all ship lights off we then completed the survey in the new location afterdawn with the listening post installed we began assembling the equipment for phase two of the operation keeping a watch for further patrols in the sky and on the water\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(' '.join(segment(sanitise(caesar_decipher(c1b, key_b)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "report on the trojan project having drugged the crew we were able to take the ship with essentially\n",
+      "no resistance the crew were handed to the somali pirates at the deepwater rendezvous as planned and\n",
+      "we began the survey just after midnight the radar showed an approaching vessel which our database\n",
+      "identified as a coastguard cutter we headed south to avoid detection with all ship lights off we\n",
+      "then completed the survey in the new location afterdawn with the listening post installed we began\n",
+      "assembling the equipment for phase two of the operation keeping a watch for further patrols in the\n",
+      "sky and on the water\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(sanitise(caesar_decipher(c1b, key_b))))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/2014/2014-challenge2.ipynb b/2014/2014-challenge2.ipynb
new file mode 100644 (file)
index 0000000..e83e214
--- /dev/null
@@ -0,0 +1,208 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "import pandas as pd\n",
+    "import collections\n",
+    "import string\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.affine import *\n",
+    "from cipher.keyword_cipher import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "from support.language_models import *\n",
+    "from support.plot_frequency_histogram import *\n",
+    "\n",
+    "c2a = open('2a.ciphertext').read()\n",
+    "c2b = open('2b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<matplotlib.axes._subplots.AxesSubplot at 0x7fd7aa938668>"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7fd7abfb7860>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "freqs = pd.Series(english_counts)\n",
+    "freqs.plot(kind='bar')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "((5, 25, True), -761.8388033231918)"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score = affine_break(c2a)\n",
+    "key_a, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "DEAR MARK, \n",
+      "\n",
+      "THANKS FOR THE LATEST REPORT FROM THE ON-SITE TEAM. IT SHOWS THAT THE SHIPBOARD GPS SYSTEM WAS COMPLETELY SCRAMBLED SO WE ARE NOT GOING TO BE ABLE TO TRACE HER MOVEMENTS FROM THAT. DO WE HAVE ANY ODD TRACES FROM ONSHORE RADAR THAT GIVE A HINT OF WHERE SHE MIGHT HAVE BEEN? \n",
+      "\n",
+      "THE COMMENT IN THE LAST MESSAGE THAT THE PIRATES COMPLETED THE SURVEY EVEN THOUGH THEY HAD MOVED SOUTH TO AVOID DETECTION SHOULD HAVE TOLD ME THAT THE SURVEY WAS NOT GEOGRAPHIC. AT FIRST I THOUGHT IT MIGHT HAVE BEEN REFERRING TO A TELECOMS SURVEY SINCE YOU MENTIONED THE LONG AERIAL, BUT ACTUALLY THE ATTACHED MESSAGE IS VERY REVEALING. STILL NOT SURE WHAT THE SURVEY WAS FOR THOUGH, AND HOW THAT IS CONNECTED TO THE MISSING SUPERSTRUCTURE. CAN YOU GET ME ANY PICTURES? \n",
+      "\n",
+      "HARRY \n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(affine_decipher(c2a, key_a[0], key_a[1]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('flag', <KeywordWrapAlphabet.from_largest: 3>), -367.81492429457404)"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score = keyword_break_mp(c2b)\n",
+    "key_b, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "calm weather allowed us to complete the hull survey and establish its integrity no major remedial\n",
+      "works were required and the pumps and extra bulkheads were installed out in deep waters over the\n",
+      "next five days we are now testing the system for reliability and safety before moving on to phase\n",
+      "three of the operation operation trojan remains on target\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(sanitise(keyword_decipher(c2b, key_b[0], key_b[1]))))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<matplotlib.axes._subplots.AxesSubplot at 0x7fd7a6ada710>"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7fd7a6adad68>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "freqs_2b = pd.Series(collections.Counter([l.lower() for l in c2b if l in string.ascii_letters]))\n",
+    "freqs_2b.plot(kind='bar')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/2014/2014-challenge3.ipynb b/2014/2014-challenge3.ipynb
new file mode 100644 (file)
index 0000000..b9ca847
--- /dev/null
@@ -0,0 +1,212 @@
+{
+ "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "import pandas as pd\n",
+    "import collections\n",
+    "import string\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.affine import *\n",
+    "from cipher.keyword_cipher import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "from support.language_models import *\n",
+    "from support.plot_frequency_histogram import *\n",
+    "\n",
+    "c3a = open('3a.ciphertext').read()\n",
+    "c3b = open('3b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<matplotlib.axes._subplots.AxesSubplot at 0x7f6c8409bac8>"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f6c8409b240>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "freqs = pd.Series(english_counts)\n",
+    "freqs.plot(kind='bar')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "((11, 1, True), -839.4977013876568)"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score = affine_break(c3a)\n",
+    "key_a, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "harry you asked me about the flag day associates they area transnational hacking group dedicated to\n",
+      "the overthrow of western capitalism they have been implicated in several major protests including an\n",
+      "attempt to takeover the uk national grid attacks on reservoir systems and interference in bank\n",
+      "trading networks it looks like the fda carried out fairly extensive modifications to the ship they\n",
+      "did a good job too we hadnt noticed the added bulkheads until we compared the layout with the plans\n",
+      "from lloyds register they seem to be there to add rigidity though there is one additional panel at\n",
+      "the stern that doesnt fit the pattern and we will be removing that tonight to see what it is there\n",
+      "for we would have done it this afternoon but decided we should conduct our own hull survey in case\n",
+      "there is a booby trap\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(affine_decipher(sanitise(c3a), key_a[0], key_a[1])))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('seahorse', <KeywordWrapAlphabet.from_last: 2>), -681.3308426043137)"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score = keyword_break_mp(c3b)\n",
+    "key_b, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "phase three the nautilus system was fully tested last night with complete success we sailed within\n",
+      "four hundred metres of the target and monitored all radio traffic for two hours with no sign that we\n",
+      "were being watched or were even noticed we then conducted a full radar sweep of the area and found\n",
+      "three dead spots where we could work on the ship without detection as planned we converted the two\n",
+      "adjacent empty containers in the middle of the stack into a large workshop area and carried out a\n",
+      "full inspection drill now even if we are boarded our work should remain undetected we retrieved\n",
+      "seahorse from the third container and carried out stage one of the assembly\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(sanitise(keyword_decipher(c3b, key_b[0], key_b[1]))))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<matplotlib.axes._subplots.AxesSubplot at 0x7f6c42fd9a20>"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAAD7CAYAAAB68m/qAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvNQv5yAAAE7xJREFUeJzt3X+w3XV95/HnC1BRlpYA12yWGEMLA3W6gnBFHNFdQVxaaclukcWtNHXRzK61i7W/stuurB27Qqu19se0mwFtpmoRKGzY2rVlIh21UkoSKCg/BoxgkwnkqgSpa4XY9/5xvhmv4d57vvfce3NvPnk+Zu6c8/2e7+d83jn5ntf5nM853+9JVSFJOvgdttgFSJLmh4EuSY0w0CWpEQa6JDXCQJekRhjoktQIA12SGmGgS1IjDHRJasQRB7Kz448/vlavXn0gu5Skg97WrVu/WlVjw7Y7oIG+evVqtmzZciC7lKSDXpJH+2znlIskNcJAl6RGGOiS1AgDXZIaYaBLUiMMdElqhIEuSY0w0CWpEb0OLEryc8BbgQLuBd4CrACuA44DtgKXVdXTC1SntGSsXv/JaW975Ko3HMBKpO81dISe5ATgvwDjVfXDwOHApcDVwAer6iTgCeDyhSxUkjSzvlMuRwDPT3IE8AJgF3AucGN3+0ZgzfyXJ0nqa2igV9VO4P3AVxgE+ZMMplj2VNXebrMdwAlTtU+yLsmWJFsmJibmp2pJ0rP0mXJZBlwEnAj8C+Ao4IK+HVTVhqoar6rxsbGhJwuTJI2oz5TL64AvV9VEVT0D3AS8Cjimm4IBWAnsXKAaJUk99An0rwBnJ3lBkgDnAfcBtwEXd9usBTYtTImSpD76zKHfweDDz20MvrJ4GLAB+GXgXUkeZvDVxWsXsE5J0hC9vodeVVcCV+63ejtw1rxXJEkaiUeKSlIjDHRJaoSBLkmNMNAlqREGuiQ1wkCXpEYY6JLUCANdkhphoEtSIwx0SWqEgS5JjTDQJakRBrokNcJAl6RGGOiS1AgDXZIa0edHok9Jcvekv28keWeSY5PcmuSh7nLZgShYkjS1Pj9B92BVnV5VpwNnAv8PuBlYD2yuqpOBzd2yJGmRzHbK5TzgS1X1KHARsLFbvxFYM5+FSZJmZ7aBfinwJ9315VW1q7v+GLB8qgZJ1iXZkmTLxMTEiGVKkobpHehJngv8OHDD/rdVVQE1Vbuq2lBV41U1PjY2NnKhkqSZzWaE/iPAtqp6vFt+PMkKgO5y93wXJ0nqbzaB/ia+O90CcAuwtru+Ftg0X0VJkmavV6AnOQo4H7hp0uqrgPOTPAS8rluWJC2SI/psVFXfBI7bb93XGHzrRZK0BHikqCQ1wkCXpEYY6JLUCANdkhphoEtSIwx0SWqEgS5JjTDQJakRBrokNcJAl6RGGOiS1AgDXZIaYaBLUiMMdElqhIEuSY0w0CWpEQa6JDWi70/QHZPkxiQPJLk/ySuTHJvk1iQPdZfLFrpYSdL0+o7QPwR8qqpOBU4D7gfWA5ur6mRgc7csSVokQwM9yfcDrwGuBaiqp6tqD3ARsLHbbCOwZqGKlCQN12eEfiIwAXwkyV1JrklyFLC8qnZ12zwGLJ+qcZJ1SbYk2TIxMTE/VUuSnqVPoB8BnAH8QVW9DPgm+02vVFUBNVXjqtpQVeNVNT42NjbXeiVJ0+gT6DuAHVV1R7d8I4OAfzzJCoDucvfClChJ6mNooFfVY8DfJzmlW3UecB9wC7C2W7cW2LQgFUqSejmi53Y/C3wsyXOB7cBbGLwYXJ/kcuBR4JKFKVGS1EevQK+qu4HxKW46b37LkSSNyiNFJakRBrokNcJAl6RGGOiS1AgDXZIaYaBLUiMMdElqhIEuSY0w0CWpEX0P/ZeGWr3+k9Pe9shVbziAlUiHJkfoktQIA12SGmGgS1IjDHRJaoSBLkmNMNAlqRG9vraY5BHgKeA7wN6qGk9yLPAJYDXwCHBJVT2xMGVKkoaZzQj9tVV1elXt++Wi9cDmqjoZ2NwtS5IWyVymXC4CNnbXNwJr5l6OJGlUfQO9gL9MsjXJum7d8qra1V1/DFg+VcMk65JsSbJlYmJijuVKkqbT99D/c6pqZ5IXArcmeWDyjVVVSWqqhlW1AdgAMD4+PuU2kqS56zVCr6qd3eVu4GbgLODxJCsAusvdC1WkJGm4oYGe5KgkR++7Drwe+AJwC7C222wtsGmhipQkDddnymU5cHOSfdt/vKo+leRO4PoklwOPApcsXJmSpGGGBnpVbQdOm2L914DzFqIoSdLseaSoJDXCQJekRhjoktQIA12SGmGgS1IjDHRJaoSBLkmNMNAlqREGuiQ1wkCXpEYY6JLUCANdkhphoEtSIwx0SWqEgS5JjTDQJakRBrokNaLPT9ABkORwYAuws6ouTHIicB1wHLAVuKyqnl6YMufP6vWfnPa2R656wwGsRDow3OcPHbMZoV8B3D9p+Wrgg1V1EvAEcPl8FiZJmp1egZ5kJfAG4JpuOcC5wI3dJhuBNQtRoCSpn75TLr8N/BJwdLd8HLCnqvZ2yzuAE6ZqmGQdsA5g1apVo1d6CJrprTL4dlnS9xo6Qk9yIbC7qraO0kFVbaiq8aoaHxsbG+UuJEk99Bmhvwr48SQ/ChwJfB/wIeCYJEd0o/SVwM6FK1OSNMzQEXpV/deqWllVq4FLgU9X1U8CtwEXd5utBTYtWJWSpKHm8j30XwbeleRhBnPq185PSZKkUfT+HjpAVf0V8Ffd9e3AWfNfkiRpFB4pKkmNMNAlqREGuiQ1wkCXpEbM6kPRpcKTDUnSszlCl6RGGOiS1IiDcspFwzktJR16HKFLUiMMdElqhIEuSY0w0CWpEQa6JDXCQJekRhjoktQIA12SGtHnR6KPTPK3Sf4uyReTvKdbf2KSO5I8nOQTSZ678OVKkqbTZ4T+beDcqjoNOB24IMnZwNXAB6vqJOAJ4PKFK1OSNEyfH4muqvqHbvE53V8B5wI3dus3AmsWpEJJUi+9zuWS5HBgK3AS8PvAl4A9VbW322QHcMI0bdcB6wBWrVo113olNWymcxCB5yEapteHolX1nao6HVjJ4IehT+3bQVVtqKrxqhofGxsbsUxJ0jCz+pZLVe0BbgNeCRyTZN8IfyWwc55rkyTNwtAplyRjwDNVtSfJ84HzGXwgehtwMXAdsBbYtJCF6sDwLa908Oozh74C2NjNox8GXF9Vf5bkPuC6JO8F7gKuXcA6JUlDDA30qroHeNkU67czmE+XJC0B/mKRpHnnL2YtDg/9l6RGGOiS1AgDXZIaYaBLUiMMdElqhIEuSY0w0CWpEQa6JDXCQJekRhjoktQIA12SGuG5XHTI8nwjao0jdElqhIEuSY0w0CWpEQa6JDViaKAneVGS25Lcl+SLSa7o1h+b5NYkD3WXyxa+XEnSdPqM0PcCP19VLwHOBn4myUuA9cDmqjoZ2NwtS5IWydBAr6pdVbWtu/4UcD9wAnARsLHbbCOwZqGKlCQNN6vvoSdZzeAHo+8AllfVru6mx4Dl07RZB6wDWLVq1ah1StKSs9SOZej9oWiSfwb8KfDOqvrG5NuqqoCaql1Vbaiq8aoaHxsbm1OxkqTp9Qr0JM9hEOYfq6qbutWPJ1nR3b4C2L0wJUqS+hg65ZIkwLXA/VX1W5NuugVYC1zVXW6aTcczvVUBD72WpNnqM4f+KuAy4N4kd3fr/huDIL8+yeXAo8AlC1OiJKmPoYFeVZ8DMs3N581vOToU+W5Nmh8eKSpJjTDQJakRBrokNcJAl6RGGOiS1AgDXZIaYaBLUiMMdElqhIEuSY2Y1elzJS0Oj6ZVH47QJakRBrokNcJAl6RGGOiS1AgDXZIaYaBLUiMMdElqxNBAT/LhJLuTfGHSumOT3Jrkoe5y2cKWKUkaps8I/Y+AC/Zbtx7YXFUnA5u7ZUnSIhoa6FX1GeDr+62+CNjYXd8IrJnnuiRJszTqHPryqtrVXX8MWD7dhknWJdmSZMvExMSI3UmShpnzh6JVVUDNcPuGqhqvqvGxsbG5didJmsaoJ+d6PMmKqtqVZAWwez6LWopmOjmSJ0aSNFsLkSmjjtBvAdZ219cCm0a8H0nSPOnztcU/AW4HTkmyI8nlwFXA+UkeAl7XLUuSFtHQKZeqetM0N503z7VIkubAI0UlqREGuiQ1wkCXpEYY6JLUCH8kWtKU/GHqg48jdElqhIEuSY0w0CWpEQa6JDXCD0V1UDvYTpp2sNV7qGjl/8URuiQ1wkCXpEY45XIAtPJ2TtLS5ghdkhphoEtSIwx0SWrEnAI9yQVJHkzycJL181WUJGn2Rv5QNMnhwO8D5wM7gDuT3FJV981XcZLUl18+mNsI/Szg4araXlVPA9cBF81PWZKk2UpVjdYwuRi4oKre2i1fBryiqt6x33brgHXd4inAg9Pc5fHAV0cqZvS29rk029pnW33Opa19Dry4qsaG3ktVjfQHXAxcM2n5MuD35nB/Ww50W/tcmm3ts60+D7Z6D7Y+J//NZcplJ/CiScsru3WSpEUwl0C/Ezg5yYlJngtcCtwyP2VJkmZr5G+5VNXeJO8A/gI4HPhwVX1xDrVsWIS29rk029pnW33Opa19zsLIH4pKkpYWjxSVpEYY6JLUCANdOghk4EXDt9ShbNEDPcmyJGclec2+v57tjkzyriQ3JfnTJD+X5MiFrncU3ZPxzUne3S2vSnLWYtc1H5J8rrt8Ksk39vt7MsmXk7y9x/2cOcW6Cxei5vmQ5LQk7+j+TptFu5H22xp82PXnI9b6xiRHd9d/tev7jB7tru6zbj51j80JI7b9aJK3JTl1hLYvmWLdv+7R7meTLJttf13bzUl+dL91c/pwdFE/FE3yVuAKBt9hvxs4G7i9qs7t0fZ64Cngo92q/wAcU1VvHNJuI3BFVe3plpcBH6iq/zjN9u+a6f6q6rd61PoHwD8B51bVD3V9/mVVvXxIu6n6fhLYWlV3D2n7POAngNVM+jZTVf3asHrnU5LjgM9X1SlDttsG/FRVfaFbfhPwzqp6xQLWNg78CvBiBo9RGGTnS4e0uwJ4G3BTt+rfAhuq6nd79DnSftu13cjg4L07h227X7t7quqlSc4B3gv8JvDuYY9tkm1VdcZ+6+4Z9vh02717qvXD9r8kVwKXAF8HPgHcUFWPD+uva/ta4NXd3w8CdwGfqaoP9Wj7BeCPgd8Ajuwux6vqlUPavZfBV7a3AR8G/qJ6hmqS7cDfA5+uqvd06571mM/GYgf6vcDLgb+pqtO7V9b/WVX/rkfb+6rqJcPWTdHurqp62bB1k267srt6Slfrvu/a/xjwt1X15h61bquqMyb3k+TvqmrGkV2SjwPjwP/pVl0I3MMgpG+oqt+Yoe2n6MIf+M6+9VX1gRnafK6qzknyFDB5x9gXdN83U70z3O+Kqto1ZJsfAG5kEHCvBn4KuLCqnpyhzf51zqreJA8Cvwjcy+AFFwYNHx3S7h7glVX1zW75KAYDkT5BN9J+2233AHAS8CjwTfq/AN1VVS9L8j7g3qr6+JB9/j8Dbwd+APjSpJuOBv665z7/85MWj2Sw794/3cBpivYvBf49g0HJjqp6Xc92hzN4nr4W+E/At6pq6Ii9+z+8GjiTwb/zY8DVVfVPMzYctA3weuAtDJ6v1wPXVtWXhrTbxuCcWL/D4CDNNwO3zSXQF/sn6P6xqv4xCUmeV1UPJJlxJDfJtiRnV9XfACR5BbClR7vDkiyrqie6dscyw+Mw6ZXzM8AZVfVUt/w/gOlP7/a9nul2tOrajjEpQGawsuvzH7p2V3Z9voZBUE8b6MDKqrqgZ30AVNU53eXRs2nX435nDPNum+1JLgX+N/AV4PVV9a0hbeZa50RVjXIwXJj0ItldT8+2o+63AP+mf4nfY2eS/8XgzKhXd+/eZppu/Tjwf4H3AZNPi/1UVX29T4f7DxySvJ/BMSt97QYeA74GvLBPgySbgaOA24HPAi+vqt09+3sG+BbwfAYvQF/uE+YweEVN8lhX715gGXBjklur6pdmKrmq9gJvT/LTwOe6tiNb7EDfkeQYBk/iW5M8wWD0Ma1uVF/Ac4DPJ/lKt/xi4IEefX4AuD3JDd3yG4Ff79FuOfD0pOWnu3V9/A5wM/DCJL/O4Dw4v9qj3QuBb09afgZYXlXfSvLtadrs8/kk/7Kq7u1Z46KY9P+5z7EMDlS7Iwl9Rr1zcGWSa4DNTHqcq+qm6ZsA8JGuvpu75TXAtT37PJPv7rcAq4AH9z0OM/17h71zmMElwAXA+6tqT5IVDN6ZTNfPkwze3b1pxP6m8gIGA5QZZfB5yyXAGHAD8Lbqf0ruexg8vj/MoP49SW4fNjDo3AlsYjC6Px74wyQ/0WMK9woG7ya/ClwD/GJVPZPkMOAhYKZA/8N9V6rqj7p94Gd61Dp9PUvlwKIk/wr4fuBTNTgd73TbvXim++mz03cfgOybp/90nx0mya8w2NEmP4k/UVXvG9a2a38qcB6Dkdzmqrq/R5v/zmB+dlO36scYTPl8gMGc7U9O0WZfQB4BnAxsZxBWvd6eH2jz8f85h74/CpwKfJHvvmOqPtMC3YeK53SLn62qu3r2uWj/3gNpvxfqwxkE9K9V1e8Nafc+Bs+rGT8jGnIfRwM/DfwC8M+r6nk92oxX1Zb91l1WVX88pN17GBwl/6z/tyQ/1Od5Pp+WTKAfDLon8au7xc/0fRLPsc9x4FXd4l/vv9NNsf0hERjzIcmDwz6s1Wj22w/3Ao930wsL2ec7GDw/zwQeYTDt8tmq+vRC9ruUGOg6ZCX5CPCbs3hLryUsyS8wCPGtC/3isVQZ6DpkJbmfwdfbvswSnpaS+jLQdciabnrKaSkdrAx0SWrEoh/6L0maHwa6JDXCQJekRhjoktSI/w91dSCiPmyo1wAAAABJRU5ErkJggg==\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f6c430c56a0>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "freqs_3b = pd.Series(collections.Counter([l.lower() for l in c3b if l in string.ascii_letters]))\n",
+    "freqs_3b.plot(kind='bar')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/2014/2014-challenge4.ipynb b/2014/2014-challenge4.ipynb
new file mode 100644 (file)
index 0000000..5fb6b24
--- /dev/null
@@ -0,0 +1,331 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "import pandas as pd\n",
+    "import collections\n",
+    "import string\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.keyword_cipher import *\n",
+    "from cipher.column_transposition import *\n",
+    "from cipher.railfence import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "from support.language_models import *\n",
+    "from support.plot_frequency_histogram import *\n",
+    "\n",
+    "c4a = open('4a.ciphertext').read()\n",
+    "c4b = open('4b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<matplotlib.axes._subplots.AxesSubplot at 0x7f70e84948d0>"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f70e8494080>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "freqs = pd.Series(english_counts)\n",
+    "freqs.plot(kind='bar')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'prsaoegerauiadmwehdnisnrasawuaaessrefgdosogvorbeeeaartesctdfmenuibrttlmeytumtmeuaikwhutkwerwahmnpwraeesononesebatoihacineetbrotadaktgfeesyioflttlstiiaeosvieonsrrtaupmnnoaencocnuvrsclvdrgctaiihriciaihrsduomrlemcrngleomarfhiuewhalcsasracufrawwsmehulstoaohceletmtoilsepdmumtptrslyrhhntpanwpmoadppdwbeseoassltmlpesletuncorerlclitaosvsiniifwseafortaaduyenenonnsopfhontwkoertcslyvoeiohlufoeioetsthtsbreneveaouepgieesobduorsfeercdyadutaepeadrdigseebfuoggopogalyfewsoeemdntohrebhaaesneworgnfiaulnlwadueodcotrargvuenewhiertlauilmsoniotmuinewaiuewloerstttisdrsasnussiesmerdhetryrhpnlrtereadmredebnntrnenwmoutrdosaneowomcgidciasaontiioiascesissupcrmoybrineyweelaylewtyrtilhsto'"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c4bs = sanitise(c4b)\n",
+    "c4bs"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('stern', <KeywordWrapAlphabet.from_largest: 3>), -830.5838133421847)"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score = keyword_break_mp(c4a)\n",
+    "key_a, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "harry we completed the survey and you are not going to believe what we found behind the false\n",
+      "bulkhead in the stern there was a large pumping station connected to a number of sea facing outlets\n",
+      "it looks like a scuttling valve system similar to the ones used on u boats in world war two icant\n",
+      "understand why they would goto so much effort when they could have scuttled her at anytime with a\n",
+      "small quantity of plastic explosive the team back at nsa have run some analytics on the remaining\n",
+      "text files we extracted from the servers onboard these ciphers are going to be pretty hard to crack\n",
+      "the attached report has frequency analysis matching usual english text so we can assume that the\n",
+      "sender was a native speaker did you have any thoughts on what the nautilus system might have been or\n",
+      "what it was for\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(keyword_decipher(sanitise(c4a), key_a[0], key_a[1])))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(((6, 0, 1, 7, 9, 4, 2, 3, 5, 8, 10), False, True), -1777.161911681522)"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score = column_transposition_break_mp(c4bs)\n",
+    "key_b, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "et et mlpdshgnbralwrrauiur tep as gsl di ocpedacnscbtsesuotut ira la lee a so at dy de og is as\n",
+      "tavrtdeiioalkoducrhe hom tein oarscnegigctuimetyfo so rice lite her a aire iue leer dad tom sub rg\n",
+      "mihm it yfflvwhetamioucuer to seo e oleh sri cu fig in ddy lea log ten urs site oawioheikttpohsmpps\n",
+      "wlsosinrndshstgverll muut has ra erupt it lit smt mck is yn lace trw a bfi awrr pm eere i uunet or\n",
+      "oe wfi a gary ws nsw lal dsb aveo smee mlr hive essor yim eee a osmer n no amf nrad hep no do ie re\n",
+      "hywsunroffbnwrretttg hn tear po amd in peet gh au out ale air di serna sue eu now\n",
+      "nwyopebyegheplnmshew van me on o an aol w own nbae irc mateo de nubs odys a usoe eau pre e on n west\n",
+      "ptbnrenlerrdiacswsoa a dwl to foo ea cob hoc erp rr uses in egf st fast hurn hterneoavcfotsaeocrd\n",
+      "int cwo a is y at it wwsncauwsdsoseldlkdf mm levu norm ect\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(sanitise(column_transposition_decipher(sanitise(c4bs), key_b[0], \n",
+    "                                                              fillcolumnwise=key_b[1],\n",
+    "                                                              emptycolumnwise=key_b[2]))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(((4, 8, 0, 6, 9, 3, 1, 2, 5, 7, 10), False, True), -2823.7851213306785)"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score = column_transposition_break_mp(c4bs, fitness=Ptrigrams)\n",
+    "key_b, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "te tmpl dsehgbralrwranuirtep sag sul doc pea dc nisc tses out ub tial a lee as road yd egoist as avr\n",
+      "ted ii to ako durch el hote in a or smc n gig cut i meet fo soir cey lie her a air te ie leed radu\n",
+      "to sub rmg ihmmiyfflwvhettaiouc eur tmo so eol hes re ic fig id nd yule log tn eur ass teoa\n",
+      "iwohieittposhmpkpsl so snirnwdsstgvrellhmut has are ru up it list mttmcisynalcektrabfi war rwp mere\n",
+      "iuu nee too ew fai garry sns wall dwsbveosememalrivees so rhy ieee a some mr no am frn adn he no do\n",
+      "eire phys un rf of bwnwrettgthnrterpo admin a petg hao uu tea laird sie renau eeuonwnswypebygeheo\n",
+      "plm she vw ann me no a no al woo wnba eric mn a to den bus oed yau so eea us pre on new step tn rene\n",
+      "lrrbdicswsaoadawl of ooaecotbhcerprrusoes neg ft sfa is turn he trn he ovc fost aea ord inc two cas\n",
+      "ya ttiw wisc au wds sons ldlkfdmmelvunomrecet\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(sanitise(column_transposition_decipher(sanitise(c4bs), key_b[0], \n",
+    "                                                              fillcolumnwise=key_b[1], \n",
+    "                                                              emptycolumnwise=key_b[2]))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<matplotlib.axes._subplots.AxesSubplot at 0x7f70a1377dd8>"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f70a30f36d8>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "freqs_4b = pd.Series(collections.Counter([l.lower() for l in c4b if l in string.ascii_letters]))\n",
+    "freqs_4b.plot(kind='bar')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(5, -1581.9784460662272)"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "railfence_break(c4bs)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "phase four the decks were cleared by two am and the mounting plates were prepared and measured\n",
+      "mounting points were assembled by four am though owing to the approaching dawn deployment of seabird\n",
+      "was postponed and we embarked onstage two of seahorse assembly with camouflage plates installed we\n",
+      "set to cruising in case of air or sea surveillance following standard routes to avoid suspicion\n",
+      "monitoring of airwaves gave no cause for concern but we have raised security levels and are using a\n",
+      "column transposition cipher for this communication with keyword seabird future comms will relyon\n",
+      "even more security tonight will be used for more sea trials of the nautilus system while the\n",
+      "assembly crew rest and the survey team carryout further mapping we will resume the seahorse build at\n",
+      "dusk tomorrow\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(railfence_decipher(c4bs, 5)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/2014/2014-challenge5.ipynb b/2014/2014-challenge5.ipynb
new file mode 100644 (file)
index 0000000..f9392fc
--- /dev/null
@@ -0,0 +1,319 @@
+{
+ "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "import pandas as pd\n",
+    "import collections\n",
+    "import string\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.keyword_cipher import *\n",
+    "from cipher.column_transposition import *\n",
+    "from cipher.railfence import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "from support.language_models import *\n",
+    "from support.plot_frequency_histogram import *\n",
+    "\n",
+    "c5a = open('5a.ciphertext').read()\n",
+    "c5b = open('5b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<matplotlib.axes._subplots.AxesSubplot at 0x7fc6513e1a90>"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7fc6513e14e0>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "freqs = pd.Series(english_counts)\n",
+    "freqs.plot(kind='bar')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'sssatanuelclaendeeheevrnhtailsltocsoeoanuodoeecaferbetrtenoiiucrwurfaproeercssoeuatulgtematremlieaveieogcelesaeeeyyiuuoaidaosdmdecsshthuhatcnxaererseltunaghanrdtevepisydtaeamcinmrnweoramrvibodsdfdpatimrssietdaospecgracnetblfioeushsmeeirlshmittrlnesehmclssoswfottwnbyteyngeymttgstariixeeedrnasmltwgmildcrtseogohrolsshmawndsstrabndnecfcayehotdornonenecatneavoeaatehercyrighsayrefsooatemncwtkaaawndadmsllnnnlutfoeeenoyoewtmanrrsxhvorolhisfunnthaeeofolphebaatmnornoeodnvtphnoetedeaeonphpaeuratvhndetahrahpoorsefovddsttpsvgraaatodsuryidovtrelerltmemdheoarshoarrrerxisgeifawfaiyidusiyieeesotkeaelatresntifemteiaighaceiondktkitteaeanecnndictnedddenstsheanrtamneahshidaocnuissctehslnlectheetlltidlcttnpnmcvsvnositdaelxpihsfattysfoedcmwhtebaachertaigriuirtngiaphetrowehwswaacmgcouwoogoegsmtarteeiemvayinogstitagblncstcycolretedarehopnebyegwcteetlteyeteenansafmo'"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c5bs = sanitise(c5b)\n",
+    "c5bs"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('seabird', <KeywordWrapAlphabet.from_largest: 3>), -1255.0542494109186)"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score = keyword_break_mp(c5a)\n",
+    "key_a, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "harry i cracked that last message for myself and noticed something really odd the text said it was\n",
+      "encrypted using a column transposition with keyword seabird but it was enciphered using a rail fence\n",
+      "cipher i can only assume that the text we retrieved was an archive of the original message re\n",
+      "encrypted for safety whoever the flag day associates are they have a pretty sophisticated operation\n",
+      "if they are filing messages like this more like one of the major terrorist groups than the usual\n",
+      "hacker collective the tech guys took a look at the aerial from the boat and they tell me that it is\n",
+      "a drag wire usually used to communicate with a submarine when submerged it carried an acoustic\n",
+      "transducer array as well as a shortwave transmitter and listening gear one thing that puzzles me now\n",
+      "is why we were allowed to find the ship floating at all surely they must have planned to sink her\n",
+      "using the scuttling equipment otherwise what was it for they seem too smart to leave it floating for\n",
+      "us to find any thoughts mark ps just before i sent this the cipher clerk came in with a decrypt of\n",
+      "the attached columnar transposition keyword has length six think it answers some of our questions\n",
+      "about the nautilus system\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(keyword_decipher(sanitise(c5a), key_a[0], key_a[1])))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(((3, 2, 4, 1, 5, 0), False, True), -1998.321513226948)"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score = column_transposition_break_mp(c5bs)\n",
+    "key_b, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "phase five seahorse is ready for trials and the nautilus system is fully functional we engaged the\n",
+      "mechanism and lowered the deck to three feet above sealevel approaching the shore by the radar\n",
+      "station at all times signals from their communications were monitored and no sign was given that our\n",
+      "approach had been monitored or even noticed we backed off the deck was raised by two feet and the\n",
+      "approach attempted again once more our incursion was unnoticed overnight we conducted a range of\n",
+      "tests and mapped the radar coverage on three separate occasions there seems to have been a flurry of\n",
+      "activity and our modeling suggests that the ships masts may have triggered brief alarms on all\n",
+      "occasions the automatic dive systems cut incorrectly lowering the decks to sealevel and the alarms\n",
+      "were cancelled the seahorse deployment system will be fully mounted tonight and we will conduct a\n",
+      "battery of tests on the deployment and emergency recovery systems over the next two nights assuming\n",
+      "that sea and air traffic remains low xxxx\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(column_transposition_decipher(sanitise(c5bs), key_b[0], \n",
+    "                                                              fillcolumnwise=key_b[1], \n",
+    "                                                              emptycolumnwise=key_b[2])))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(((3, 2, 4, 1, 5, 0), False, True), -2821.4971440358026)"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score = column_transposition_break_mp(c5bs, fitness=Ptrigrams)\n",
+    "key_b, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "phase five seahorse is ready for trials and the nautilus system is fully functional we engaged the\n",
+      "mechanism and lowered the deck to three feet above sealevel approaching the shore by the radar\n",
+      "station at all times signals from their communications were monitored and no sign was given that our\n",
+      "approach had been monitored or even noticed we backed off the deck was raised by two feet and the\n",
+      "approach attempted again once more our incursion was unnoticed overnight we conducted a range of\n",
+      "tests and mapped the radar coverage on three separate occasions there seems to have been a flurry of\n",
+      "activity and our modeling suggests that the ships masts may have triggered brief alarms on all\n",
+      "occasions the automatic dive systems cut incorrectly lowering the decks to sealevel and the alarms\n",
+      "were cancelled the seahorse deployment system will be fully mounted tonight and we will conduct a\n",
+      "battery of tests on the deployment and emergency recovery systems over the next two nights assuming\n",
+      "that sea and air traffic remains low xxxx\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(column_transposition_decipher(c5bs, key_b[0], \n",
+    "                                            fillcolumnwise=key_b[1], \n",
+    "                                             emptycolumnwise=key_b[2])))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['tokens',\n",
+       " 'trials',\n",
+       " 'tricks',\n",
+       " 'tromps',\n",
+       " 'umiaks',\n",
+       " 'unfair',\n",
+       " 'urbans',\n",
+       " 'urgent',\n",
+       " 'vocals',\n",
+       " 'womans',\n",
+       " 'womens',\n",
+       " 'wreaks',\n",
+       " 'wrecks',\n",
+       " 'yokels',\n",
+       " 'ricardo',\n",
+       " 'sneaker',\n",
+       " 'speaker',\n",
+       " 'tobagos',\n",
+       " 'trebles',\n",
+       " 'woolens',\n",
+       " 'sneakers',\n",
+       " 'speakers',\n",
+       " 'speedier',\n",
+       " 'tobaccos',\n",
+       " 'together',\n",
+       " 'treaties',\n",
+       " 'treatise',\n",
+       " 'trollops',\n",
+       " 'unedited',\n",
+       " 'woollens',\n",
+       " 'wreckers',\n",
+       " 'treatises',\n",
+       " 'triteness',\n",
+       " 'usherette',\n",
+       " 'woodcocks',\n",
+       " 'tritenesss',\n",
+       " 'usherettes']"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "transpositions[key_b[0]]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/2014/2014-challenge6.ipynb b/2014/2014-challenge6.ipynb
new file mode 100644 (file)
index 0000000..18a1296
--- /dev/null
@@ -0,0 +1,291 @@
+{
+ "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "import pandas as pd\n",
+    "import collections\n",
+    "import string\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.railfence import *\n",
+    "from cipher.hill import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "from support.language_models import *\n",
+    "from support.plot_frequency_histogram import *\n",
+    "\n",
+    "\n",
+    "c6a = open('6a.ciphertext').read()\n",
+    "c6b = open('6b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<matplotlib.axes._subplots.AxesSubplot at 0x7f4c5027da58>"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f4c5027d160>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "freqs = pd.Series(english_counts)\n",
+    "freqs.plot(kind='bar')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<matplotlib.axes._subplots.AxesSubplot at 0x7f4c502dacc0>"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXoAAAD7CAYAAABkO19ZAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvNQv5yAAAEpRJREFUeJzt3XmwZGV5x/HvIyOMCzos15EwyGCcgEighCuQQg2LlYxCBCNOQIOo6JQLBiUuGI2UlkRwx5Bgphh0FIpVDCS4USOKyCJ3AFkGiRMWHYrlGhYptcTRJ3+cM9hebi+3T/ednne+n6qu7nP6vP0+99xzf+ec93T3jcxEklSuJ23oAiRJw2XQS1LhDHpJKpxBL0mFM+glqXAGvSQVzqCXpMIZ9JJUOINekgo3Z0MXALDtttvmwoULN3QZkrRRWbVq1c8zc6zbciMR9AsXLmRiYmJDlyFJG5WIuLuX5Ry6kaTCGfSSVDiDXpIKZ9BLUuEMekkqnEEvSYUz6CWpcAa9JBVuJD4wtSlYeMKlbZ+76+SDZ7ESSZsaj+glqXAGvSQVzqCXpMIZ9JJUOINekgpn0EtS4Qx6SSqcQS9JhTPoJalwBr0kFc6gl6TCGfSSVDiDXpIKZ9BLUuEMekkqXNegj4gzI+KBiLilZd4nI+LHEXFTRHwtIua1PPeBiFgTEbdHxF8Pq3BJUm96OaL/ErB4yrzLgN0yc3fgf4APAETErsARwAvqNv8eEZsNrFpJ0ox1DfrMvAJ4cMq8b2fmunryGmBB/fhQ4NzM/E1m3gmsAfYeYL2SpBkaxBj9m4Bv1I+3B37W8tzaet4TRMTSiJiIiInJyckBlCFJmk6joI+IDwLrgLNn2jYzl2XmeGaOj42NNSlDktRB3/8cPCLeABwCHJSZWc++B9ihZbEF9TxJ0gbS1xF9RCwG3ge8MjN/1fLUJcAREbFFROwELAJ+2LxMSVK/uh7RR8Q5wP7AthGxFjiR6l02WwCXRQTANZn51sy8NSLOB1ZTDem8IzN/N6ziJUnddQ36zDxymtnLOyx/EnBSk6IkSYPjJ2MlqXAGvSQVzqCXpMIZ9JJUOINekgpn0EtS4Qx6SSqcQS9JhTPoJalwBr0kFc6gl6TCGfSSVDiDXpIKZ9BLUuEMekkqnEEvSYUz6CWpcAa9JBXOoJekwhn0klQ4g16SCmfQS1LhugZ9RJwZEQ9ExC0t87aOiMsi4if1/Vb1/IiIz0fEmoi4KSL2HGbxkqTuejmi/xKweMq8E4CVmbkIWFlPA7wcWFTflgKnD6ZMSVK/ugZ9Zl4BPDhl9qHAivrxCuCwlvlfzso1wLyI2G5QxUqSZq7fMfr5mXlv/fg+YH79eHvgZy3Lra3nPUFELI2IiYiYmJyc7LMMSVI3jS/GZmYC2Ue7ZZk5npnjY2NjTcuQJLXRb9Dfv35Ipr5/oJ5/D7BDy3IL6nmSpA1kTp/tLgGOBk6u7y9umX9sRJwL7AM80jLEI0ltLTzh0rbP3XXywbNYSXm6Bn1EnAPsD2wbEWuBE6kC/vyIOAa4G1hSL/514BXAGuBXwBuHULMkaQa6Bn1mHtnmqYOmWTaBdzQtSpI0OH4yVpIKZ9BLUuEMekkqnEEvSYUz6CWpcAa9JBXOoJekwhn0klQ4g16SCmfQS1LhDHpJKpxBL0mFM+glqXAGvSQVzqCXpMIZ9JJUOINekgpn0EtS4Qx6SSqcQS9JhTPoJalwBr0kFc6gl6TCNQr6iHh3RNwaEbdExDkRMTcidoqIayNiTUScFxGbD6pYSdLM9R30EbE98A/AeGbuBmwGHAGcAnw2M58HPAQcM4hCJUn9aTp0Mwd4SkTMAZ4K3AscCFxYP78COKxhH5KkBvoO+sy8B/gU8FOqgH8EWAU8nJnr6sXWAttP1z4ilkbERERMTE5O9luGJKmLJkM3WwGHAjsBfwI8DVjca/vMXJaZ45k5PjY21m8ZkqQumgzdvAy4MzMnM/O3wEXAfsC8eigHYAFwT8MaJUkNNAn6nwL7RsRTIyKAg4DVwOXA4fUyRwMXNytRktREkzH6a6kuul4P3Fy/1jLg/cDxEbEG2AZYPoA6JUl9mtN9kfYy80TgxCmz7wD2bvK6kqTB8ZOxklQ4g16SCmfQS1LhDHpJKpxBL0mFM+glqXAGvSQVzqCXpMI1+sDUsCw84dJp59918sGzXIm68XcljT6P6CWpcAa9JBVuJIduJG3cHNIbLR7RS1LhDHpJKpxBL0mFM+glqXAGvSQVzqCXpMIZ9JJUON9HL6mtdu+HB98TvzHxiF6SCmfQS1LhGg3dRMQ84AxgNyCBNwG3A+cBC4G7gCWZ+VCjKqWNgB/716hqekR/KvDNzNwF2AO4DTgBWJmZi4CV9bQkaQPpO+gj4pnAS4HlAJn5WGY+DBwKrKgXWwEc1rRISVL/mhzR7wRMAl+MiBsi4oyIeBowPzPvrZe5D5g/XeOIWBoRExExMTk52aAMSVInTYJ+DrAncHpmvhD4JVOGaTIzqcbunyAzl2XmeGaOj42NNShDktRJk6BfC6zNzGvr6Qupgv/+iNgOoL5/oFmJkqQm+g76zLwP+FlE7FzPOghYDVwCHF3POxq4uFGFkqRGmn4y9p3A2RGxOXAH8Eaqncf5EXEMcDewpGEfkqQGGgV9Zt4IjE/z1EFNXleSNDh+MlaSCmfQS1Lh/PZKAX5L4Ybietds8Ihekgpn0EtS4Qx6SSqcQS9JhTPoJalwBr0kFc6gl6TCGfSSVDiDXpIKZ9BLUuEMekkqnEEvSYUz6CWpcAa9JBXOoJekwhn0klQ4g16SCmfQS1LhDHpJKlzj/xkbEZsBE8A9mXlIROwEnAtsA6wCjsrMx5r2I/XD/8kqDeaI/jjgtpbpU4DPZubzgIeAYwbQhySpT42CPiIWAAcDZ9TTARwIXFgvsgI4rEkfkqRmmh7Rfw54H/D7enob4OHMXFdPrwW2n65hRCyNiImImJicnGxYhiSpnb6DPiIOAR7IzFX9tM/MZZk5npnjY2Nj/ZYhSeqiycXY/YBXRsQrgLnAM4BTgXkRMac+ql8A3NO8TElSv/o+os/MD2TmgsxcCBwBfCczXwdcDhxeL3Y0cHHjKiVJfRvG++jfDxwfEWuoxuyXD6EPSVKPGr+PHiAzvwt8t358B7D3IF5XkjrxcxK98ZOxklQ4g16SCjeQoZuNlad9kjYFHtFLUuEMekkqnEEvSYUz6CWpcAa9JBXOoJekwhn0klQ4g16SCmfQS1LhDHpJKpxBL0mFM+glqXAGvSQVzqCXpMIZ9JJUuE36++hL5ffsS2rlEb0kFc6gl6TCGfSSVDiDXpIK1/fF2IjYAfgyMB9IYFlmnhoRWwPnAQuBu4AlmflQ81JHR7uLnV7oLIMXs1WaJkf064B/zMxdgX2Bd0TErsAJwMrMXASsrKclSRtI30Gfmfdm5vX140eB24DtgUOBFfViK4DDmhYpSerfQMboI2Ih8ELgWmB+Zt5bP3Uf1dDOdG2WRsRERExMTk4OogxJ0jQaf2AqIp4OfBV4V2b+IiIefy4zMyJyunaZuQxYBjA+Pj7tMjPhuKqkUgw6zxod0UfEk6lC/uzMvKiefX9EbFc/vx3wQJM+JEnNNHnXTQDLgdsy8zMtT10CHA2cXN9f3KhCSRoBG/OoQZOhm/2Ao4CbI+LGet4/UQX8+RFxDHA3sKRZiZKkJvoO+sy8Eog2Tx/U7+tKkgbLT8ZKUuEMekkqnN9HL21kNuaLgtowPKKXpMIZ9JJUOIduJG1yNrVvoDXotVFwXFrqn0M3klQ4g16SCmfQS1LhDHpJKpwXY0fcpvbuAEmD5xG9JBXOoJekwhn0klQ4g16SCmfQS1LhDHpJKpxBL0mF8330kjREo/BZGI/oJalwBr0kFW5oQzcRsRg4FdgMOCMzTx5WX9q4+N3yG4brfdM1lCP6iNgM+Dfg5cCuwJERsesw+pIkdTasoZu9gTWZeUdmPgacCxw6pL4kSR1EZg7+RSMOBxZn5pvr6aOAfTLz2JZllgJL68mdgdvbvNy2wM9nWEI/bWazr1Gvbzb7GvX6ZrOvUa9vNvsa9fpms69ObXbMzLGur5CZA78Bh1ONy6+fPgo4rc/XmpiNNrPZ16jX57pwXWzovka9vo1hXbTehjV0cw+wQ8v0gnqeJGmWDSvorwMWRcROEbE5cARwyZD6kiR1MJS3V2bmuog4FvgW1dsrz8zMW/t8uWWz1GY2+xr1+mazr1Gvbzb7GvX6ZrOvUa9vNvvqt77HDeVirCRpdPjJWEkqnEEvSYUz6CVNKyo7dF9So25kgz4itoqIvSPipetvXZafGxHHR8RFEfHViHh3RMydrXq7qf9o/j4iPlxPPyci9m6z7Ffq++Nms8Zhiogr6/tHI+IXU26PRMSdEfH2Lq+x1zTzDhlWzbMlIvaIiGPr2x49thn69p7VBbyv99M2Il4TEVvWjz9U17lnlzan9DKvqXq9bd9Hu7Mi4i0RscsM2jzhq18iYv8e2r0zIraaYYntX28UL8ZGxJuB46jef38jsC9wdWYe2KHN+cCjwFn1rNcC8zLzNR3arACOy8yH6+mtgE9n5pvaLH98p7oz8zMd+jod+D1wYGY+v+7r25n5ommWXQ28DPgGsD8QU/p5sFMdbep8BFiVmTd2aLcF8GpgIS3vyMrMj3bqbxAiYhvgqszcucMy1wOvz8xb6ukjgXdl5j4DrmUc+CCwI9V6CKrc271Luxmvv3pn/hbgonrWq4BlmfmvXfrqZ3uf8fZb/42clpnXdWo7TbubMnP3iHgx8DHgk8CHO/2uIuL6zNxzyrybeljvH55ufrv1HhEnAkuAB4HzgAsy8/6OP1DV7gDgJfXtT4EbgCsy89QObW4BvgJ8Aphb349n5l906etjVG9Lvx44E/hWNgjrUf3HI8cBLwKuycwD6j3ov3Rps1tmtu49L68Ds5Pd14c8QGY+FBEv7LD8lvX9znV96z8b8DfAD7v0tU9m7hkRN7T0tXmbZb8ArASeC6zij4M+6/mdjNe3/6qnDwFuAt4aERdk5ifatLuYeocA/KZTBxFxZWa+OCIerWt6/CmqUHxGlxr/SGb+Xw9HOocDF0bEa6n+2F4P/FWb+qbWNZP6zgbeC9xMtXPuVc/rr8UxVNvGL+HxI9irgY5BT3/b+zjTb7c/6dBmH+B1EXE38Et63OkBv6vvD6bacV1ah9cTRMTbgLcDz42Im1qe2hL4QZd+qOtaby7V9n5bu4Uz8yPARyJid+DvgO9FxNrMfFmnTjLz8oi4gmodHgC8FXgB1bf0trMPcApwFdXPczawX7cfKDM/FBH/TLV9vxE4rd65L8/M/+3WfroXHLkbcF19fyOwRf341i5tzgL2bZneB/hylzY/ArZqmd4auLmH+q4AtmyZ3pJqz96pzbVUnym4vp4eA27o0ub0PtffFcDTW6afDnwPeAqwukO7Wzb0776Hn+3PgNXAN4GnDKmPK/tsN+P1R7UzmdsyPbfHbbCf7b2f7XbH6W491PffwH8AdwDzgC2AH7VZ9plUZ0HnTOln6z5/D1sA3+1huWcD76TamdzUw/IrgWuAzwJ/CzyrhzabU53N3AisAY6Y4c+yB/A54MfA6VRnEZ+Y6ToZ1SP6tRExD/hP4LKIeAi4e7oFI+JmqiO3JwNXRcRP6+kdqVZOJ58Gro6IC+rp1wAn9VDffOCxlunH6nmdfB74GvCsiDiJ6uj0Q50aZObbeqhlOs/ij48ofwvMz8xfR0SnI82rIuLPM/PmPvsdipbf8XpbU+00r40IsvvR5UydGBFnUP1hP76+MvOi9k2A/tbfF6l+jq/V04cBy3totxd/2N4BngPcvn5dtVknM95uM3Pav7seLAEWA5/KzIcjYjuqs6Tp+niE6kzoyD77muqpVMO+06qvBS2hOti6AHhLZnY7G4LqrHgvYDeqeh+OiKsz89cd2lxHdab3IqovJ/tCRLw6Owyx1TUeR3XG+nPgDOC9mfnbiHgS1RnY+3qo9w+vV+81RlZE/CXVHv+bWX3l8dTnd+zUvtuGWl8sWT/2/51efuER8UGqDaX1j/O8zPx4l3a7AAdRnf6uzMy2p5dN1Kd8r6LawKA6Rb+Ease2LDNfN2X59UE6B1hEdRT2G3o/TR+qpr/jPvo7C9gFuJU/DN1ktrl209JuNfA84E5msP7qi5Qvrie/n5k39FDjjNdJv9vtqJtyILAZVYB/NDNPa7P8x6l+7rbXq7r0tyXwBuA9wLMzc4sOy45n5sSUeUdl5le69PERqm8UmO73+PyZZsfIB/2oqv84X1JPXtHLH+dsqi8orh8L/MHUjW3KsrMapKMuIm7PDheFO7Sbdj2O0vob9e22H1PW+zrg/sxcN4R+jqVad3sBdwHfp9oxf2fQfQ2aQS9NERFfBD7Z4+m8NhER8R6qcF81jB3JMBn00hQRcRvV2+dmNAQjjSqDXppiYxiCkWbCoJekwo3sVyBIkgbDoJekwhn0klQ4g16SCvf/uHjGhOba0aMAAAAASUVORK5CYII=\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f4c0ed65ef0>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "freqs_6a = pd.Series(collections.Counter([l.lower() for l in c6a if l in string.ascii_letters]))\n",
+    "freqs_6a.plot(kind='bar')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<matplotlib.axes._subplots.AxesSubplot at 0x7f4c502da780>"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f4c0fd5a208>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "freqs_6b = pd.Series(collections.Counter([l.lower() for l in c6b if l in string.ascii_letters]))\n",
+    "freqs_6b.plot(kind='bar')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'mtaeglatcleptenopeautelebiiootatwnantateituiiagaeostgvetabdresiacqobwavgrhrsihssaekajbwwttdrsmeetnyafsegilegtkrreocuantteomsgstnsiaeluutrbaiaeteeserhxgtooarrbhpcklialhnaesvearhbepiydcesewtaxuyaerywoeinhteegeisieireaassrbitnhtuorooleewsttereoahyakhlsmsaeodslthsutigqimnidsgetpmwtrnnotfhvselkaumrndvcnrluceryhyeetlnigouncnanrhpnosbhshpslreclvrinfoehniaeennhcrbenrgunruesmlrehiutgteordroeaeoisoeusiknteeslohthdcrmisuteoteaeoshfaiaesemritrseisaigwyrmhrbtetncoenuhorcadeodlcrncomnctosihudtcinagesntisutigytmshthyalatlsnhilguimtlbfldyhrfrnetsaosteetaefhlgokhretcakuteihrlrtlsetshlcpeadhthyutaeennhryraeennihrnbhnsnehyutsdtoywmtiatalwhvbepetlxihuscrtadtikhnxmsaesnwluevgnrcpegvnhteruigeuealsdntikeaeomctwrybusiilephkyodhrsyhecaatrmrltrarretstuoetnuesiduaidoesisaeetbllerpntroisiatsiasesomihsieiaunsaitneelacrfnrnngvetteenslhvpepteonedtnaooutgsotancetimiiwoetiuihclsewtcniieotslfbeecohenpoelsdoctceeemiiirttmhbiuovecegaitjuaborcleentatruyinetsidlaeehitwencceohwvohoatwkteroarhcseer'"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c6as = sanitise(c6a)\n",
+    "c6as"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'hwssswxfewhhrfewpdrvttdhxbccleayphalnadhiehaoudrotwnrrvysabjlttbaytmelrkaidopthatlelrtwaamaneksvvzrvllatkcrjquicizgtoqcpnrrkttowandqehtqrvtbaydqealannohulanuzlwextlvjrvivhnohdqmgykaclmswrupdetfioftfelhzpxhaswftwprrsweiseohefpdrvttnvagdvswgoerbetnharvaeevtlltbmgaiatgelinmdawevhatterdhrznbnvoutnefoteveaehlaymhacglzeptvvdimworfisgtuzlwibeqohubtghamqornjnnrumqvjtxeltfovgawdaeevllgrtxibgtibevmpsaateoasevaeyqohameonncfuidoefafattemuimnflznbekofobrliaehhauihnnnwzaeevtlltpaalnanvtzlzuucptaelinanpaahewfthaosetaribnbnvhaevdhyytlmuxb'"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c6bs = sanitise(c6b)\n",
+    "c6bs"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(3, -2314.997881051078)"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score = railfence_break(c6as)\n",
+    "key_a, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "mark the last message told usa lot the scuttling equipment is designed to pump water in and out of\n",
+      "the vessel like a submarine dive control but clearly they werent planning to turn a container ship\n",
+      "into a sub this ship is a largescale version of something i have seen in the caribbean drug runners\n",
+      "use a similar technique to get below radar coverage for inshore runs sinking the vessel so that the\n",
+      "deck remains just below the wave tops the fda pirates seem more interested in staying away from\n",
+      "shore but getting close enough to track and record electronic communications without detection i am\n",
+      "guessing this scuttling system is what they call nautilus in their log but i am still baffled by the\n",
+      "references to seahorse the next page of the log looks harder to crack but the cipher clerk tells me\n",
+      "it is a hill cipher and that they must have been in a hurry or have been enciphering by hand since\n",
+      "they just used a two by two matrix actually we have been pretty lax with our security and i think\n",
+      "the next message is end will use avi genere cipher given that we are using secure cables i dont\n",
+      "think we have too much to worry about so i will keep the keyword short say three characters more\n",
+      "later harry\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(railfence_decipher(c6as, key_a)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(matrix([[0, 1],\n",
+       "         [1, 1]]), -666.1299098341699)"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score = hill_break(c6bs)\n",
+    "key_b, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "phase six seahorse operated exactly as planned with good forward visibility at the trial depths the\n",
+      "crew managed several tasks requiring concentration and dexterity and we plan to run a full test\n",
+      "overnight on dummy cables dropped from the ship the software seems to be operating as designed but\n",
+      "there are still bugs in the firmware that need ironing out before we deploy the collective is\n",
+      "working full time to hunt them down and remove them though we are all getting tired mistakes are\n",
+      "easy to make and could be fatal time is no longer on our side though and we are still planning to\n",
+      "launch the final phase of the operation in three days timex\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(hill_decipher(key_b, c6bs)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/2014/2014-challenge7.ipynb b/2014/2014-challenge7.ipynb
new file mode 100644 (file)
index 0000000..474b1ad
--- /dev/null
@@ -0,0 +1,434 @@
+{
+ "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "import pandas as pd\n",
+    "import collections\n",
+    "import string\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.vigenere import *\n",
+    "from cipher.amsco import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "from support.language_models import *\n",
+    "from support.plot_frequency_histogram import *\n",
+    "\n",
+    "c7a = open('7a.ciphertext').read()\n",
+    "c7b = open('7b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<matplotlib.axes._subplots.AxesSubplot at 0x7f068ca71908>"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f068ca71208>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "freqs = pd.Series(english_counts)\n",
+    "freqs.plot(kind='bar')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<matplotlib.axes._subplots.AxesSubplot at 0x7f064cd8c710>"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f064c084b70>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "freqs_7a = pd.Series(collections.Counter([l.lower() for l in c7a if l in string.ascii_letters]))\n",
+    "freqs_7a.plot(kind='bar')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<matplotlib.axes._subplots.AxesSubplot at 0x7f064e351b70>"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f064bf7d550>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "freqs_7b = pd.Series(collections.Counter([l.lower() for l in c7b if l in string.ascii_letters]))\n",
+    "freqs_7b.plot(kind='bar')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'veyjmyjkrzilysyjeydorulcsrcjnmoiddeugurlogfsnwcrlhckhghmwkejxlyktlagflalvtmgkyyomvlmgkyjosfdrzepwaqgnrzeqzinoaqforkcsltjwdussrzarlhcnajneqzabbakeebatjgoiklgcerzebjidlwmgdussnmljwdgftmlhceeazalasksnbtlmukcvtfwilderhrckuksbjqtfwcpwwfsdydrcsdwsbyfdmfeblhcneqkejohguhussjmciqfmjuqoirzosltfwsfapuwwmmlbzatwhyvnmadcstfstrzedvafsdzwelgpcjaraneanrzeqwwylepkscshmjscaslglmfgcjakqsrwrwlhcuurswyqollhcktyjbmsrbkibwcjwapwdyfapwamxapgulvfgnekwtcjsqiuyjeuatfsdgktgfcravcharlepfodtojlsdssrwncvtmjegffmjccvdcukndarwsgkaukokwtfanediiwtfasmfaqmbpwsamekasqaolscmmpjwodqeyjsyyouzellhcqfgltcvajgcydsfapuatfsjsjypagewdgfsnwcraolkyqleklhcveacpjstckcyfcyjrwscpsncveqaglwdrgdchlmqaljotsrceorwonwrylebnefacjwdckiefebxopmnbwrqwamhepstggnqawykajjeyvyagnawrlwdytosltfwrcxepwnawtmlhcuazdeqanrzejssrhaplodlhcxdydoeturlhcfevlscutggnfsskwrcsljqwmjrgwdgliqwnajynleboirzakgrckeamrceobafgwdyesagtpsnqhoqatggnaapfwryfdrwljkuqohyltfwyuwrcjeydlwmprgwfstgvollulvepktyfdgkhmotfwwfglcssqwmzdygkpmoepwdrzeqgrrgfagmnmtgfgrzeweuqlbcvogfggkrcsljqillelkitwalvwmmlbtupftfjosyhytarlepqilvawkillhyltgeerzegjillepuenlmgyhrforuaruhyfyrzilyuqwfsdbsltfwyasnfsrbdyfsvczihsciwdydoaslqgciwtgftfwmgvdjwodlhcgccsnasnwguewtkwaazaplsfgwgfgrzebwenkeyuazdeqanrzepwgggngvolliksggferzeskwgdlzwanjozdekturatksylwebkokwdghlmeaaqtmyerlhcxujdcmnepsgceankfpgmrzemealagmnepfmcftgxiyergyhratgkillhcarzwsranrwrcktqlondawslmfguwajdhyneydorlojgsczepw'"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c7as = sanitise(c7a)\n",
+    "c7as"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'anwaecnndrtwtanireoahsrdntieerdctewayerevaaarpioerobsedescrehlaoitithsdtrinosepeplthtnidtwsduledlhotpeaterhaaredeoaiodtahregerothwhtsureteeinwigiresetpowicooonitseudseechacteofiileonewiotacteodteuneahsedaptryemronmomlexontkemeoyvitsteenhantrertieineotndlhpoplyitewitrsedeevdycfrmnsnaypinmteeneeinahinepritedehveleaorelllvmocnahncepherohjuuvehautathttetoasipowwneedselopgdeslfedterfcaatehjasdtrprleseeretetecneorrsgckamiiwaefutiashaongcthsrenrehtrsthhaceinwtprloghetodaeraloeedeatsomldwedtwefsbelevpdteonoignsavftegsebomcehatietnrsptonthusorecredendcetlwaehesedrncveracuhoihaleinaemeunherdesttstasipedeyleeemtiisiigothntssfolnitretrwhemtkhhswtorcssnererohteencsapeblircnthuleofenrsromrnshmaddaodeatihioroutwevthapeceetovterdleaditewdottttcatkmbhtheicwantnisedwatxankeabovoanmswlprgaispodfogndpedeswrdacttrefhdesyaberretlavod'"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c7bs = sanitise(c7b)\n",
+    "c7bs"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('say', -1726.4679903722085)"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score = vigenere_frequency_break(c7as)\n",
+    "key_a, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "dear mark things area lot clearer now i flew out to inspect the ship myself last night and took a\n",
+      "good look around the reason the ship was not scuttled was that the valves had jammed it looks like\n",
+      "the driftwood was pulled into the mechanism and blocked the inlet presumably the crew had already\n",
+      "abandoned the vessel which was lucky for us without the ship we would have had no idea that the fda\n",
+      "had been operating in these waters seahorse is no longer a mystery the cutaway on the starboard side\n",
+      "cleared an area of around five meters square with a distinctive pattern of bolts fastened to\n",
+      "reinforced deck plates i saw something like this on a sub rescue mission a couple of years ago when\n",
+      "they fitted a local ship with a jury rigged inspection system the deck plates can carry a crane\n",
+      "designed to deploy an rova remote operated vehicle designed for undersea operations i was already\n",
+      "concerned about the reference to the cables in the last part of the fda log but the next section has\n",
+      "me really worried it is encrypted with a more secure modified amsco transposition cipher and tells\n",
+      "us what they were really up to what i dont understand is how the whole assembly is powered the sort\n",
+      "of computing they must be doing is really intensive and would burn through a battery in days in that\n",
+      "time their intercept might not catch anything useful but they can hardly have hijacked a local\n",
+      "socket in the middle of the ocean can you get me a chart showing the deepsea cables in the region i\n",
+      "dont imagine the us will be a problem but it may need some diplomacy to get the full coverage maps\n",
+      "from the omani government if i am right it is in their best interests to playalong we all have alot\n",
+      "to lose here\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(vigenere_decipher(c7as, key_a)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(((1, 2, 0, 4, 3), (2, 1), <AmscoFillStyle.continuous: 1>),\n",
+       " -1902.8377732825452)"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score = amsco_break(c7bs)\n",
+    "key_b, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "phase seven we approached the cable junction undercover of night with nautilus at an elevation of\n",
+      "three feet towing seahorse to starboard comms interception showed that we remained undetected and\n",
+      "seahorse was deployed at operating depth the various layers of armoured protection were removed from\n",
+      "the cable and as expected once the steel jacket was removed the other layers provided little\n",
+      "resistance the divers entered the water and cut into the core to insert the optical repeaters\n",
+      "linking them back to the man in the middle unit which was powered up and fully tested initial tests\n",
+      "showed that it was operating as expected and three keys have already been recovered from the omani\n",
+      "transmissions with daylight approaching the remaining tests were postponed for the following night\n",
+      "and the ship returned to deeper waters where it remained at low deck height the divers were left at\n",
+      "seahorse to decompress slowly and will be recovered tomorrow once the final tests have been\n",
+      "concluded\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(amsco_transposition_decipher(c7bs, key_b[0], fillpattern=key_b[1], fillstyle=key_b[2])))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['cable',\n",
+       " 'facto',\n",
+       " 'facts',\n",
+       " 'gabon',\n",
+       " 'hafts',\n",
+       " 'hefts',\n",
+       " 'ibexs',\n",
+       " 'kabul',\n",
+       " 'lacys',\n",
+       " 'ladys',\n",
+       " 'laius',\n",
+       " 'lefts',\n",
+       " 'macon',\n",
+       " 'macro',\n",
+       " 'macys',\n",
+       " 'malts',\n",
+       " 'melon',\n",
+       " 'melts',\n",
+       " 'negro',\n",
+       " 'oahus',\n",
+       " 'obeys',\n",
+       " 'obits',\n",
+       " 'odets',\n",
+       " 'pacts',\n",
+       " 'pants',\n",
+       " 'pelts',\n",
+       " 'pints',\n",
+       " 'piotr',\n",
+       " 'pious',\n",
+       " 'plots',\n",
+       " 'plows',\n",
+       " 'ploys',\n",
+       " 'rafts',\n",
+       " 'rants',\n",
+       " 'remus',\n",
+       " 'rents',\n",
+       " 'riots',\n",
+       " 'scout',\n",
+       " 'shout',\n",
+       " 'snout',\n",
+       " 'cabbed',\n",
+       " 'cabbie',\n",
+       " 'cabbys',\n",
+       " 'cabral',\n",
+       " 'dabble',\n",
+       " 'faeroe',\n",
+       " 'gabbro',\n",
+       " 'ibexes',\n",
+       " 'jaguar',\n",
+       " 'kaboom',\n",
+       " 'kaftan',\n",
+       " 'lacuna',\n",
+       " 'lagoon',\n",
+       " 'lefter',\n",
+       " 'legume',\n",
+       " 'macaws',\n",
+       " 'magyar',\n",
+       " 'malays',\n",
+       " 'maltas',\n",
+       " 'mellon',\n",
+       " 'negevs',\n",
+       " 'nellys',\n",
+       " 'nelson',\n",
+       " 'odious',\n",
+       " 'paddys',\n",
+       " 'panzas',\n",
+       " 'peggys',\n",
+       " 'pelves',\n",
+       " 'pennys',\n",
+       " 'photos',\n",
+       " 'pinups',\n",
+       " 'qantas',\n",
+       " 'rabats',\n",
+       " 'rallys',\n",
+       " 'refuse',\n",
+       " 'refute',\n",
+       " 'remuss',\n",
+       " 'renews',\n",
+       " 'repute',\n",
+       " 'scouts',\n",
+       " 'shouts',\n",
+       " 'snouts',\n",
+       " 'cabbage',\n",
+       " 'cabrera',\n",
+       " 'dabbled',\n",
+       " 'gadwall',\n",
+       " 'ladonna',\n",
+       " 'leftest',\n",
+       " 'madonna',\n",
+       " 'malayan',\n",
+       " 'million',\n",
+       " 'papacys',\n",
+       " 'pellets',\n",
+       " 'penneys',\n",
+       " 'qantass',\n",
+       " 'ragtags',\n",
+       " 'refuses',\n",
+       " 'refuter',\n",
+       " 'regrets',\n",
+       " 'rennets',\n",
+       " 'renters',\n",
+       " 'reroute',\n",
+       " 'sallust',\n",
+       " 'macassar',\n",
+       " 'mahatmas',\n",
+       " 'mahayana',\n",
+       " 'nanettes',\n",
+       " 'palatals',\n",
+       " 'phosphor',\n",
+       " 'reenters',\n",
+       " 'phosphors',\n",
+       " 'sinusitis',\n",
+       " 'malayalams',\n",
+       " 'sinusitiss']"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "transpositions[key_b[0]]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/2014/2014-challenge8.ipynb b/2014/2014-challenge8.ipynb
new file mode 100644 (file)
index 0000000..d39900b
--- /dev/null
@@ -0,0 +1,5108 @@
+{
+ "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "import pandas as pd\n",
+    "import collections\n",
+    "import string\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.vigenere import *\n",
+    "from cipher.cadenus import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "from support.language_models import *\n",
+    "from support.plot_frequency_histogram import *\n",
+    "\n",
+    "c8a = open('8a.ciphertext').read()\n",
+    "c8b = open('8b.ciphertext').read().strip()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<matplotlib.axes._subplots.AxesSubplot at 0x7f383433e908>"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f383433e048>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "freqs = pd.Series(english_counts)\n",
+    "freqs.plot(kind='bar')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<matplotlib.axes._subplots.AxesSubplot at 0x7f37f28e9f98>"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f37f463ecc0>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "freqs_8a = pd.Series(collections.Counter([l.lower() for l in c8a if l in string.ascii_letters]))\n",
+    "freqs_8a.plot(kind='bar')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'nyvlggsyglchxfeuytqcesqxpziufiggrbjhpayncruyfpsxufiupskyrectmmcncruyregxigrlglbtiblmecebzsvrlpuxpbibjajrljreobajrlufigjehbezywtmgjyxfqxictsgrdgtbjafyoocwtmjblctwwucqmgofrlfmrfrlfwlbtijlwuypmchjqxicrfchumtsmzjbimyvhcuvyrugxjcwpdtpuisrlfdhbaencyqumufeogrhcrjmytqsmsxjmrcsxjrmttiswzvjrfpecjitnidgemdssaitasvjhuyofgxpsxgmvvqfvrxiyxxmymbxfjpufigbeufeuuiiyzfavbaofbxicmsamqfisqwpgrtribbmtskhcwuuimcxufinbitrvpwxsmnbljppytuixgpmlifbgpmtfpeugsodvpkxicsnyrjeswcvokioreoyvnchggkirishiuyrerlfdpjeluasorvpjwzqxfkwgpsnyhsmrfkiblaigpfuiociersflwvpiuusufmoewpliufeuuiemrprwflhdpmuggbjmodsskeugsoygsmwtrlfzecypnyreyftrvbgxblhuusufeuuivqiblsoavjrmdyplcchcrfpeugsonvprsdmpplxiyxdfeolimemwcrufimczfjsgasnkmukiorxicjeylbtitfsxlmobiwcppnmoexigwqjeogenqyscxiyxufizummjvfgrtreucxictpuisqyqnpzumufmoyjfuqplxiqfvrajrlmsglrlfwajjpomxhsitqxiyxxcoomabzsvrmuyreuixgpmnyugxpsxpdfvqmocwtdssjsoeiomyhfxpasncyqumufeqjeomjpsvpurumiynppgxjrmorlfkiblxjkixcrpuoomaufeurlfgvigkicwuqidsvjrcdmqnsrjaeugsoqescioavznxfbytgrhygbbioswdgticvtmafaeoqxbpxisrugrhrlsmyhfxichbrecywfdssmxicvjlxfpgfnxtuidyrdpedixigwnycccxicfscelrlsmyhfaffewcffcrmmslgrhdssgrufiggkirehymoqxufigbemcxtlsuqgscajryqypmrlfzitrlbpvz'"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c8as = sanitise(c8a)\n",
+    "c8as"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('bye', -1461.9840974270046)"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score = vigenere_frequency_break(c8as)\n",
+    "key_a, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "mark i cracked what appears to be the final document about the trojan deployment and i think i have\n",
+      "an idea about how to deal with it and with the flag day associates the principal weakness of any\n",
+      "system like the one they have installed is the need to provide large quantities of power the fda\n",
+      "came up with an ingenious solution but it is very vulnerable special forces could take it out for us\n",
+      "but that would tell the fda that we have cracked their ciphers so instead i suggest we let them\n",
+      "destroy trojan for us we will need cooperation from the omani government an armed fighter jet and\n",
+      "the flight control systems from a drone meanwhile we need to ensure two things one that we do not\n",
+      "send critical information across the ba balm and abstrait and two that we use an on critical key\n",
+      "generation protocol on that channel given the level of commitment the fda have shown in developing\n",
+      "this plan i am sure that they will reinstate the powersupply within a few months but with luck they\n",
+      "will not guess that we know about it and we will put it out of business for long enough to come up\n",
+      "with a plan of our own to exploit it in the meantime we now know that their highest security\n",
+      "communications are encrypted using a caden us cipher so we can start hunting through the database\n",
+      "for other intercepts we can crack this maybe the breakthrough we have been looking for in the fight\n",
+      "against the fda lets not screw it up all the best harry\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(vigenere_decipher(c8as, key_a)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "875.0"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(c8b) / 8"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['00000',\n",
+       " '00101',\n",
+       " '00010',\n",
+       " '00000',\n",
+       " '00100',\n",
+       " '10100',\n",
+       " '01110',\n",
+       " '10011',\n",
+       " '10011',\n",
+       " '00000',\n",
+       " '00010',\n",
+       " '10011',\n",
+       " '00111',\n",
+       " '10001',\n",
+       " '01000',\n",
+       " '01110',\n",
+       " '01011',\n",
+       " '00100',\n",
+       " '10011',\n",
+       " '00010',\n",
+       " '10010',\n",
+       " '00100',\n",
+       " '10001',\n",
+       " '10011',\n",
+       " '00111',\n",
+       " '10010',\n",
+       " '00111',\n",
+       " '10011',\n",
+       " '10001',\n",
+       " '00000',\n",
+       " '00111',\n",
+       " '01010',\n",
+       " '11000',\n",
+       " '01110',\n",
+       " '10001',\n",
+       " '01111',\n",
+       " '00101',\n",
+       " '10001',\n",
+       " '00110',\n",
+       " '00100',\n",
+       " '01110',\n",
+       " '00000',\n",
+       " '00011',\n",
+       " '01111',\n",
+       " '01111',\n",
+       " '01001',\n",
+       " '01101',\n",
+       " '00110',\n",
+       " '01011',\n",
+       " '10011',\n",
+       " '00100',\n",
+       " '10001',\n",
+       " '01101',\n",
+       " '00100',\n",
+       " '00101',\n",
+       " '00100',\n",
+       " '01110',\n",
+       " '00101',\n",
+       " '01000',\n",
+       " '01110',\n",
+       " '10001',\n",
+       " '10011',\n",
+       " '10010',\n",
+       " '00011',\n",
+       " '00011',\n",
+       " '01110',\n",
+       " '00100',\n",
+       " '00100',\n",
+       " '10100',\n",
+       " '01100',\n",
+       " '10010',\n",
+       " '00010',\n",
+       " '10001',\n",
+       " '10100',\n",
+       " '00100',\n",
+       " '10001',\n",
+       " '01101',\n",
+       " '00101',\n",
+       " '00100',\n",
+       " '10011',\n",
+       " '01011',\n",
+       " '00000',\n",
+       " '00000',\n",
+       " '00101',\n",
+       " '10010',\n",
+       " '10011',\n",
+       " '10110',\n",
+       " '01000',\n",
+       " '00100',\n",
+       " '01101',\n",
+       " '10011',\n",
+       " '10001',\n",
+       " '10101',\n",
+       " '01110',\n",
+       " '01110',\n",
+       " '01101',\n",
+       " '00100',\n",
+       " '10001',\n",
+       " '00111',\n",
+       " '10100',\n",
+       " '00000',\n",
+       " '00111',\n",
+       " '10001',\n",
+       " '00000',\n",
+       " '10101',\n",
+       " '00100',\n",
+       " '10001',\n",
+       " '00100',\n",
+       " '00100',\n",
+       " '10011',\n",
+       " '10010',\n",
+       " '10101',\n",
+       " '10010',\n",
+       " '01000',\n",
+       " '00100',\n",
+       " '01011',\n",
+       " '00111',\n",
+       " '01011',\n",
+       " '01110',\n",
+       " '10010',\n",
+       " '10011',\n",
+       " '00011',\n",
+       " '01110',\n",
+       " '00000',\n",
+       " '01011',\n",
+       " '01110',\n",
+       " '11000',\n",
+       " '00000',\n",
+       " '00100',\n",
+       " '10010',\n",
+       " '01100',\n",
+       " '01101',\n",
+       " '01101',\n",
+       " '00011',\n",
+       " '01000',\n",
+       " '00110',\n",
+       " '01101',\n",
+       " '01101',\n",
+       " '10001',\n",
+       " '00111',\n",
+       " '01110',\n",
+       " '00111',\n",
+       " '00111',\n",
+       " '10011',\n",
+       " '10010',\n",
+       " '01101',\n",
+       " '00000',\n",
+       " '01110',\n",
+       " '01000',\n",
+       " '01011',\n",
+       " '01101',\n",
+       " '00010',\n",
+       " '01101',\n",
+       " '10010',\n",
+       " '10010',\n",
+       " '01000',\n",
+       " '00010',\n",
+       " '10001',\n",
+       " '00100',\n",
+       " '00000',\n",
+       " '01101',\n",
+       " '01101',\n",
+       " '00100',\n",
+       " '00100',\n",
+       " '01000',\n",
+       " '01000',\n",
+       " '01000',\n",
+       " '00100',\n",
+       " '10001',\n",
+       " '10110',\n",
+       " '10011',\n",
+       " '00000',\n",
+       " '01101',\n",
+       " '00100',\n",
+       " '10010',\n",
+       " '10001',\n",
+       " '10101',\n",
+       " '01110',\n",
+       " '00110',\n",
+       " '01000',\n",
+       " '00100',\n",
+       " '01000',\n",
+       " '11000',\n",
+       " '10110',\n",
+       " '10010',\n",
+       " '10010',\n",
+       " '00011',\n",
+       " '00110',\n",
+       " '01111',\n",
+       " '10101',\n",
+       " '01110',\n",
+       " '01000',\n",
+       " '00000',\n",
+       " '01000',\n",
+       " '10010',\n",
+       " '00000',\n",
+       " '01110',\n",
+       " '00000',\n",
+       " '00100',\n",
+       " '01110',\n",
+       " '00000',\n",
+       " '00100',\n",
+       " '00011',\n",
+       " '10001',\n",
+       " '01101',\n",
+       " '01000',\n",
+       " '10011',\n",
+       " '10001',\n",
+       " '01101',\n",
+       " '10111',\n",
+       " '00100',\n",
+       " '01000',\n",
+       " '00110',\n",
+       " '10001',\n",
+       " '01111',\n",
+       " '10010',\n",
+       " '10010',\n",
+       " '00111',\n",
+       " '00000',\n",
+       " '00011',\n",
+       " '00111',\n",
+       " '00011',\n",
+       " '10011',\n",
+       " '01110',\n",
+       " '01000',\n",
+       " '01111',\n",
+       " '00000',\n",
+       " '00000',\n",
+       " '10011',\n",
+       " '00100',\n",
+       " '10111',\n",
+       " '00100',\n",
+       " '01101',\n",
+       " '01101',\n",
+       " '00100',\n",
+       " '10010',\n",
+       " '00000',\n",
+       " '00110',\n",
+       " '10001',\n",
+       " '01110',\n",
+       " '00001',\n",
+       " '10011',\n",
+       " '01011',\n",
+       " '00100',\n",
+       " '10010',\n",
+       " '10001',\n",
+       " '01101',\n",
+       " '10001',\n",
+       " '01110',\n",
+       " '01000',\n",
+       " '10001',\n",
+       " '11000',\n",
+       " '01111',\n",
+       " '00001',\n",
+       " '00110',\n",
+       " '00100',\n",
+       " '00011',\n",
+       " '00010',\n",
+       " '01011',\n",
+       " '01011',\n",
+       " '01000',\n",
+       " '10110',\n",
+       " '00000',\n",
+       " '01011',\n",
+       " '00000',\n",
+       " '01011',\n",
+       " '00100',\n",
+       " '00100',\n",
+       " '01101',\n",
+       " '01000',\n",
+       " '00110',\n",
+       " '10001',\n",
+       " '10001',\n",
+       " '01101',\n",
+       " '10110',\n",
+       " '11000',\n",
+       " '10001',\n",
+       " '01011',\n",
+       " '01000',\n",
+       " '01100',\n",
+       " '01011',\n",
+       " '01111',\n",
+       " '10010',\n",
+       " '10011',\n",
+       " '01110',\n",
+       " '01011',\n",
+       " '00100',\n",
+       " '00101',\n",
+       " '10011',\n",
+       " '10001',\n",
+       " '00011',\n",
+       " '01100',\n",
+       " '10100',\n",
+       " '00000',\n",
+       " '10001',\n",
+       " '01000',\n",
+       " '00100',\n",
+       " '00100',\n",
+       " '00100',\n",
+       " '01000',\n",
+       " '01000',\n",
+       " '00000',\n",
+       " '01110',\n",
+       " '01011',\n",
+       " '01101',\n",
+       " '00100',\n",
+       " '10110',\n",
+       " '10010',\n",
+       " '00000',\n",
+       " '01110',\n",
+       " '00111',\n",
+       " '10001',\n",
+       " '10011',\n",
+       " '01011',\n",
+       " '10010',\n",
+       " '10011',\n",
+       " '01110',\n",
+       " '00001',\n",
+       " '00100',\n",
+       " '10011',\n",
+       " '01101',\n",
+       " '10010',\n",
+       " '01011',\n",
+       " '10101',\n",
+       " '00101',\n",
+       " '01000',\n",
+       " '10101',\n",
+       " '00011',\n",
+       " '01110',\n",
+       " '10101',\n",
+       " '10011',\n",
+       " '01111',\n",
+       " '01110',\n",
+       " '00000',\n",
+       " '00100',\n",
+       " '00100',\n",
+       " '01000',\n",
+       " '10010',\n",
+       " '00010',\n",
+       " '01000',\n",
+       " '01110',\n",
+       " '00111',\n",
+       " '01000',\n",
+       " '01111',\n",
+       " '10010',\n",
+       " '00100',\n",
+       " '10101',\n",
+       " '00100',\n",
+       " '00100',\n",
+       " '00011',\n",
+       " '10011',\n",
+       " '00100',\n",
+       " '10110',\n",
+       " '00101',\n",
+       " '00000',\n",
+       " '10001',\n",
+       " '01101',\n",
+       " '00111',\n",
+       " '00100',\n",
+       " '00001',\n",
+       " '01011',\n",
+       " '00100',\n",
+       " '00000',\n",
+       " '01110',\n",
+       " '10011',\n",
+       " '01110',\n",
+       " '00111',\n",
+       " '10011',\n",
+       " '10011',\n",
+       " '10011',\n",
+       " '00100',\n",
+       " '01111',\n",
+       " '01101',\n",
+       " '00010',\n",
+       " '01010',\n",
+       " '00000',\n",
+       " '01110',\n",
+       " '01101',\n",
+       " '00111',\n",
+       " '10110',\n",
+       " '00100',\n",
+       " '10011',\n",
+       " '01100',\n",
+       " '10101',\n",
+       " '11000',\n",
+       " '01111',\n",
+       " '10001',\n",
+       " '10001',\n",
+       " '00100',\n",
+       " '01110',\n",
+       " '01101',\n",
+       " '01101',\n",
+       " '00000',\n",
+       " '10010',\n",
+       " '00110',\n",
+       " '00011',\n",
+       " '00100',\n",
+       " '00011',\n",
+       " '01110',\n",
+       " '00100',\n",
+       " '00100',\n",
+       " '00100',\n",
+       " '01110',\n",
+       " '00000',\n",
+       " '00000',\n",
+       " '01100',\n",
+       " '10011',\n",
+       " '00010',\n",
+       " '01000',\n",
+       " '00010',\n",
+       " '10011',\n",
+       " '10011',\n",
+       " '01000',\n",
+       " '00101',\n",
+       " '01101',\n",
+       " '00000',\n",
+       " '00011',\n",
+       " '10001',\n",
+       " '00100',\n",
+       " '10010',\n",
+       " '10001',\n",
+       " '10011',\n",
+       " '10010',\n",
+       " '00100',\n",
+       " '10001',\n",
+       " '01110',\n",
+       " '10010',\n",
+       " '00100',\n",
+       " '10011',\n",
+       " '10001',\n",
+       " '00111',\n",
+       " '00010',\n",
+       " '01000',\n",
+       " '00010',\n",
+       " '10011',\n",
+       " '01111',\n",
+       " '10010',\n",
+       " '00000',\n",
+       " '00000',\n",
+       " '00100',\n",
+       " '00111',\n",
+       " '01011',\n",
+       " '00011',\n",
+       " '00111',\n",
+       " '10010',\n",
+       " '00101',\n",
+       " '10111',\n",
+       " '10010',\n",
+       " '01110',\n",
+       " '00000',\n",
+       " '01110',\n",
+       " '10011',\n",
+       " '00010',\n",
+       " '10011',\n",
+       " '00001',\n",
+       " '00001',\n",
+       " '10010',\n",
+       " '01110',\n",
+       " '00100',\n",
+       " '01000',\n",
+       " '10001',\n",
+       " '01101',\n",
+       " '10010',\n",
+       " '00000',\n",
+       " '00011',\n",
+       " '01011',\n",
+       " '11000',\n",
+       " '10011',\n",
+       " '10001',\n",
+       " '10001',\n",
+       " '10100',\n",
+       " '01101',\n",
+       " '10001',\n",
+       " '00010',\n",
+       " '00100',\n",
+       " '01111',\n",
+       " '10011',\n",
+       " '10011',\n",
+       " '00111',\n",
+       " '10001',\n",
+       " '00100',\n",
+       " '10100',\n",
+       " '00111',\n",
+       " '01101',\n",
+       " '01010',\n",
+       " '10011',\n",
+       " '00000',\n",
+       " '00010',\n",
+       " '00100',\n",
+       " '00010',\n",
+       " '00100',\n",
+       " '00100',\n",
+       " '01011',\n",
+       " '10001',\n",
+       " '10110',\n",
+       " '01101',\n",
+       " '01000',\n",
+       " '10001',\n",
+       " '00100',\n",
+       " '00100',\n",
+       " '00100',\n",
+       " '00000',\n",
+       " '00100',\n",
+       " '10010',\n",
+       " '00100',\n",
+       " '00100',\n",
+       " '00100',\n",
+       " '01000',\n",
+       " '00011',\n",
+       " '01000',\n",
+       " '10010',\n",
+       " '01110',\n",
+       " '00110',\n",
+       " '00010',\n",
+       " '00100',\n",
+       " '01110',\n",
+       " '01100',\n",
+       " '01101',\n",
+       " '10001',\n",
+       " '10011',\n",
+       " '00100',\n",
+       " '01001',\n",
+       " '00111',\n",
+       " '00000',\n",
+       " '00110',\n",
+       " '00000',\n",
+       " '00001',\n",
+       " '10010',\n",
+       " '00100',\n",
+       " '01101',\n",
+       " '01000',\n",
+       " '10011',\n",
+       " '01011',\n",
+       " '10110',\n",
+       " '10011',\n",
+       " '10001',\n",
+       " '01101',\n",
+       " '00001',\n",
+       " '01100',\n",
+       " '01000',\n",
+       " '00100',\n",
+       " '01011',\n",
+       " '10010',\n",
+       " '00000',\n",
+       " '10001',\n",
+       " '00100',\n",
+       " '10011',\n",
+       " '00100',\n",
+       " '10010',\n",
+       " '10001',\n",
+       " '01101',\n",
+       " '00110',\n",
+       " '10010',\n",
+       " '01101',\n",
+       " '00111',\n",
+       " '00100',\n",
+       " '00001',\n",
+       " '01000',\n",
+       " '01110',\n",
+       " '10010',\n",
+       " '00011',\n",
+       " '01000',\n",
+       " '00100',\n",
+       " '01101',\n",
+       " '00000',\n",
+       " '00101',\n",
+       " '01011',\n",
+       " '00100',\n",
+       " '01000',\n",
+       " '10010',\n",
+       " '00000',\n",
+       " '00111',\n",
+       " '01110',\n",
+       " '00010',\n",
+       " '01000',\n",
+       " '00101',\n",
+       " '00100',\n",
+       " '10101',\n",
+       " '01100',\n",
+       " '00101',\n",
+       " '00000',\n",
+       " '10011',\n",
+       " '00000',\n",
+       " '01101',\n",
+       " '00000',\n",
+       " '10011',\n",
+       " '10001',\n",
+       " '01101',\n",
+       " '01000',\n",
+       " '00000',\n",
+       " '00110',\n",
+       " '01101',\n",
+       " '00111',\n",
+       " '00000',\n",
+       " '10011',\n",
+       " '01101',\n",
+       " '01100',\n",
+       " '01000',\n",
+       " '00001',\n",
+       " '01101',\n",
+       " '01000',\n",
+       " '10100',\n",
+       " '00101',\n",
+       " '00100',\n",
+       " '01101',\n",
+       " '10001',\n",
+       " '10011',\n",
+       " '01110',\n",
+       " '10011',\n",
+       " '10011',\n",
+       " '10001',\n",
+       " '01101',\n",
+       " '11000',\n",
+       " '01111',\n",
+       " '00000',\n",
+       " '01000',\n",
+       " '00011',\n",
+       " '11000',\n",
+       " '01000',\n",
+       " '00100',\n",
+       " '00110',\n",
+       " '00011',\n",
+       " '01101',\n",
+       " '01100',\n",
+       " '00100',\n",
+       " '10001',\n",
+       " '00111',\n",
+       " '00111',\n",
+       " '01000',\n",
+       " '01110',\n",
+       " '10011',\n",
+       " '10001',\n",
+       " '00100',\n",
+       " '10011',\n",
+       " '00010',\n",
+       " '00100',\n",
+       " '10010',\n",
+       " '10010',\n",
+       " '00100',\n",
+       " '01000',\n",
+       " '01011',\n",
+       " '00011',\n",
+       " '10001',\n",
+       " '00001',\n",
+       " '00010',\n",
+       " '00100',\n",
+       " '01111',\n",
+       " '10001',\n",
+       " '01000',\n",
+       " '00110',\n",
+       " '00000',\n",
+       " '00100',\n",
+       " '10010',\n",
+       " '01110',\n",
+       " '00000',\n",
+       " '00011',\n",
+       " '01011',\n",
+       " '10011',\n",
+       " '00000',\n",
+       " '00111',\n",
+       " '01000',\n",
+       " '00100',\n",
+       " '10101',\n",
+       " '00100',\n",
+       " '00001',\n",
+       " '10001',\n",
+       " '00010',\n",
+       " '00100',\n",
+       " '01101',\n",
+       " '01011',\n",
+       " '00100',\n",
+       " '10101',\n",
+       " '00000',\n",
+       " '10010',\n",
+       " '00000',\n",
+       " '00011',\n",
+       " '01101',\n",
+       " '01101',\n",
+       " '10011',\n",
+       " '00111',\n",
+       " '01101',\n",
+       " '00100',\n",
+       " '01000',\n",
+       " '10011',\n",
+       " '00100',\n",
+       " '01000',\n",
+       " '01000',\n",
+       " '10010',\n",
+       " '00000',\n",
+       " '00111',\n",
+       " '10100',\n",
+       " '00111',\n",
+       " '00111',\n",
+       " '10100',\n",
+       " '00000',\n",
+       " '01100',\n",
+       " '01110',\n",
+       " '01101',\n",
+       " '00100',\n",
+       " '00101',\n",
+       " '11000',\n",
+       " '00111',\n",
+       " '01011',\n",
+       " '01110',\n",
+       " '01101',\n",
+       " '10110',\n",
+       " '00111',\n",
+       " '00000',\n",
+       " '00100',\n",
+       " '00100',\n",
+       " '00100',\n",
+       " '00100',\n",
+       " '01110',\n",
+       " '10010',\n",
+       " '01101',\n",
+       " '00100',\n",
+       " '00100',\n",
+       " '11000',\n",
+       " '00000',\n",
+       " '01101',\n",
+       " '00100',\n",
+       " '01000',\n",
+       " '10010',\n",
+       " '00100',\n",
+       " '10011',\n",
+       " '01110',\n",
+       " '00110',\n",
+       " '11000',\n",
+       " '01000',\n",
+       " '10011',\n",
+       " '00100',\n",
+       " '10001',\n",
+       " '01011',\n",
+       " '01000',\n",
+       " '00111',\n",
+       " '10011',\n",
+       " '00010',\n",
+       " '01100',\n",
+       " '01000',\n",
+       " '01110',\n",
+       " '01000',\n",
+       " '10001',\n",
+       " '00000',\n",
+       " '10001',\n",
+       " '00101',\n",
+       " '00011',\n",
+       " '01110',\n",
+       " '00100',\n",
+       " '10011',\n",
+       " '01101',\n",
+       " '01000',\n",
+       " '00111',\n",
+       " '10011',\n",
+       " '01101',\n",
+       " '00100',\n",
+       " '00111',\n",
+       " '01000',\n",
+       " '01000',\n",
+       " '01010',\n",
+       " '00000',\n",
+       " '01100',\n",
+       " '10001',\n",
+       " '00011',\n",
+       " '01100',\n",
+       " '01101',\n",
+       " '00000',\n",
+       " '00011',\n",
+       " '00000',\n",
+       " '01101',\n",
+       " '00000',\n",
+       " '01110',\n",
+       " '00011',\n",
+       " '10010',\n",
+       " '00100',\n",
+       " '10010',\n",
+       " '00100',\n",
+       " '01000',\n",
+       " '11000',\n",
+       " '00010',\n",
+       " '01011',\n",
+       " '10010',\n",
+       " '01000',\n",
+       " '00000',\n",
+       " '01101',\n",
+       " '10011',\n",
+       " '00000',\n",
+       " '01110',\n",
+       " '01011',\n",
+       " '10011',\n",
+       " '00010',\n",
+       " '01000',\n",
+       " '11000',\n",
+       " '01100',\n",
+       " '01000',\n",
+       " '00011',\n",
+       " '00100',\n",
+       " '01101',\n",
+       " '10011',\n",
+       " '10011',\n",
+       " '00111',\n",
+       " '01011',\n",
+       " '10011',\n",
+       " '01101',\n",
+       " '00011',\n",
+       " '10111',\n",
+       " '10011',\n",
+       " '10011',\n",
+       " '10011',\n",
+       " '01100',\n",
+       " '00000',\n",
+       " '10010',\n",
+       " '00001',\n",
+       " '01011',\n",
+       " '00100',\n",
+       " '00000',\n",
+       " '00100',\n",
+       " '00100',\n",
+       " '10011',\n",
+       " '01011',\n",
+       " '01000',\n",
+       " '10010',\n",
+       " '01000',\n",
+       " '10001',\n",
+       " '10011',\n",
+       " '10110',\n",
+       " '10011',\n",
+       " '10100',\n",
+       " '10001',\n",
+       " '01111',\n",
+       " '00101',\n",
+       " '00000',\n",
+       " '01000',\n",
+       " '01011',\n",
+       " '10011',\n",
+       " '00100',\n",
+       " '00000',\n",
+       " '01110',\n",
+       " '00100',\n",
+       " '00101',\n",
+       " '00100',\n",
+       " '01000',\n",
+       " '10010',\n",
+       " '01000',\n",
+       " '01000',\n",
+       " '01000',\n",
+       " '11000',\n",
+       " '01000',\n",
+       " '10010',\n",
+       " '01000',\n",
+       " '01010',\n",
+       " '10101',\n",
+       " '10011',\n",
+       " '10110',\n",
+       " '01000',\n",
+       " '10010',\n",
+       " '01111',\n",
+       " '10001',\n",
+       " '00001',\n",
+       " '10010',\n",
+       " '01000',\n",
+       " '01101',\n",
+       " '00100',\n",
+       " '01011',\n",
+       " '01111',\n",
+       " '00111',\n",
+       " '10001',\n",
+       " '01100',\n",
+       " '01110',\n",
+       " '00111',\n",
+       " '01000',\n",
+       " '00000',\n",
+       " '00110',\n",
+       " '01101',\n",
+       " '01011',\n",
+       " '10010',\n",
+       " '01011',\n",
+       " '10101',\n",
+       " '01000',\n",
+       " '10011',\n",
+       " '01110',\n",
+       " '00011',\n",
+       " '00000',\n",
+       " '01000',\n",
+       " '10010',\n",
+       " '00011',\n",
+       " '01111',\n",
+       " '01101',\n",
+       " '11000',\n",
+       " '00011',\n",
+       " '00011',\n",
+       " '00010',\n",
+       " '00000',\n",
+       " '00000',\n",
+       " '01110',\n",
+       " '10011',\n",
+       " '00000',\n",
+       " '00111',\n",
+       " '00010',\n",
+       " '00100',\n",
+       " '00111',\n",
+       " '10011',\n",
+       " '10100',\n",
+       " '00100',\n",
+       " '01000',\n",
+       " '10001',\n",
+       " '10001',\n",
+       " '00100',\n",
+       " '00011',\n",
+       " '00000',\n",
+       " '00100',\n",
+       " '00010',\n",
+       " '10011',\n",
+       " '01110',\n",
+       " '10010',\n",
+       " '01101',\n",
+       " '10001',\n",
+       " '00111',\n",
+       " '10101',\n",
+       " '01101',\n",
+       " '00000',\n",
+       " '01110',\n",
+       " '00011',\n",
+       " '01110',\n",
+       " '01000',\n",
+       " '01010',\n",
+       " '01110',\n",
+       " '00100',\n",
+       " '10011',\n",
+       " '00010',\n",
+       " '01000',\n",
+       " '01101',\n",
+       " '00100',\n",
+       " '01101',\n",
+       " '00100',\n",
+       " '10100',\n",
+       " '10001',\n",
+       " '10001',\n",
+       " '01000',\n",
+       " '10010',\n",
+       " '00011',\n",
+       " '00010',\n",
+       " '01110',\n",
+       " '10100',\n",
+       " '10001',\n",
+       " '00000',\n",
+       " '00110',\n",
+       " '01011',\n",
+       " '10101',\n",
+       " '01000',\n",
+       " '01100',\n",
+       " '01100',\n",
+       " '10100',\n",
+       " '01111',\n",
+       " '01111',\n",
+       " '00011',\n",
+       " '01000',\n",
+       " '10011',\n",
+       " '00100',\n",
+       " '00000',\n",
+       " '01101',\n",
+       " '00011',\n",
+       " '01000',\n",
+       " '10011',\n",
+       " '01100',\n",
+       " '00000',\n",
+       " '00000',\n",
+       " '01000',\n",
+       " '00000',\n",
+       " '01000',\n",
+       " '00100',\n",
+       " '01011',\n",
+       " '00100',\n",
+       " '01110',\n",
+       " '01101',\n",
+       " '01101',\n",
+       " '10001',\n",
+       " '00100',\n",
+       " '00100',\n",
+       " '00011',\n",
+       " '00000',\n",
+       " '01110',\n",
+       " '00011',\n",
+       " '00001',\n",
+       " '01110',\n",
+       " '01000',\n",
+       " '10100',\n",
+       " '01100',\n",
+       " '00100',\n",
+       " '01011',\n",
+       " '10001',\n",
+       " '01110',\n",
+       " '10011',\n",
+       " '01101',\n",
+       " '10011',\n",
+       " '10011',\n",
+       " '10011',\n",
+       " '00110',\n",
+       " '01000',\n",
+       " '10011',\n",
+       " '01101',\n",
+       " ...]"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[c for c in chunks(c8b, 5)]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[0,\n",
+       " 5,\n",
+       " 2,\n",
+       " 0,\n",
+       " 4,\n",
+       " 20,\n",
+       " 14,\n",
+       " 19,\n",
+       " 19,\n",
+       " 0,\n",
+       " 2,\n",
+       " 19,\n",
+       " 7,\n",
+       " 17,\n",
+       " 8,\n",
+       " 14,\n",
+       " 11,\n",
+       " 4,\n",
+       " 19,\n",
+       " 2,\n",
+       " 18,\n",
+       " 4,\n",
+       " 17,\n",
+       " 19,\n",
+       " 7,\n",
+       " 18,\n",
+       " 7,\n",
+       " 19,\n",
+       " 17,\n",
+       " 0,\n",
+       " 7,\n",
+       " 10,\n",
+       " 24,\n",
+       " 14,\n",
+       " 17,\n",
+       " 15,\n",
+       " 5,\n",
+       " 17,\n",
+       " 6,\n",
+       " 4,\n",
+       " 14,\n",
+       " 0,\n",
+       " 3,\n",
+       " 15,\n",
+       " 15,\n",
+       " 9,\n",
+       " 13,\n",
+       " 6,\n",
+       " 11,\n",
+       " 19,\n",
+       " 4,\n",
+       " 17,\n",
+       " 13,\n",
+       " 4,\n",
+       " 5,\n",
+       " 4,\n",
+       " 14,\n",
+       " 5,\n",
+       " 8,\n",
+       " 14,\n",
+       " 17,\n",
+       " 19,\n",
+       " 18,\n",
+       " 3,\n",
+       " 3,\n",
+       " 14,\n",
+       " 4,\n",
+       " 4,\n",
+       " 20,\n",
+       " 12,\n",
+       " 18,\n",
+       " 2,\n",
+       " 17,\n",
+       " 20,\n",
+       " 4,\n",
+       " 17,\n",
+       " 13,\n",
+       " 5,\n",
+       " 4,\n",
+       " 19,\n",
+       " 11,\n",
+       " 0,\n",
+       " 0,\n",
+       " 5,\n",
+       " 18,\n",
+       " 19,\n",
+       " 22,\n",
+       " 8,\n",
+       " 4,\n",
+       " 13,\n",
+       " 19,\n",
+       " 17,\n",
+       " 21,\n",
+       " 14,\n",
+       " 14,\n",
+       " 13,\n",
+       " 4,\n",
+       " 17,\n",
+       " 7,\n",
+       " 20,\n",
+       " 0,\n",
+       " 7,\n",
+       " 17,\n",
+       " 0,\n",
+       " 21,\n",
+       " 4,\n",
+       " 17,\n",
+       " 4,\n",
+       " 4,\n",
+       " 19,\n",
+       " 18,\n",
+       " 21,\n",
+       " 18,\n",
+       " 8,\n",
+       " 4,\n",
+       " 11,\n",
+       " 7,\n",
+       " 11,\n",
+       " 14,\n",
+       " 18,\n",
+       " 19,\n",
+       " 3,\n",
+       " 14,\n",
+       " 0,\n",
+       " 11,\n",
+       " 14,\n",
+       " 24,\n",
+       " 0,\n",
+       " 4,\n",
+       " 18,\n",
+       " 12,\n",
+       " 13,\n",
+       " 13,\n",
+       " 3,\n",
+       " 8,\n",
+       " 6,\n",
+       " 13,\n",
+       " 13,\n",
+       " 17,\n",
+       " 7,\n",
+       " 14,\n",
+       " 7,\n",
+       " 7,\n",
+       " 19,\n",
+       " 18,\n",
+       " 13,\n",
+       " 0,\n",
+       " 14,\n",
+       " 8,\n",
+       " 11,\n",
+       " 13,\n",
+       " 2,\n",
+       " 13,\n",
+       " 18,\n",
+       " 18,\n",
+       " 8,\n",
+       " 2,\n",
+       " 17,\n",
+       " 4,\n",
+       " 0,\n",
+       " 13,\n",
+       " 13,\n",
+       " 4,\n",
+       " 4,\n",
+       " 8,\n",
+       " 8,\n",
+       " 8,\n",
+       " 4,\n",
+       " 17,\n",
+       " 22,\n",
+       " 19,\n",
+       " 0,\n",
+       " 13,\n",
+       " 4,\n",
+       " 18,\n",
+       " 17,\n",
+       " 21,\n",
+       " 14,\n",
+       " 6,\n",
+       " 8,\n",
+       " 4,\n",
+       " 8,\n",
+       " 24,\n",
+       " 22,\n",
+       " 18,\n",
+       " 18,\n",
+       " 3,\n",
+       " 6,\n",
+       " 15,\n",
+       " 21,\n",
+       " 14,\n",
+       " 8,\n",
+       " 0,\n",
+       " 8,\n",
+       " 18,\n",
+       " 0,\n",
+       " 14,\n",
+       " 0,\n",
+       " 4,\n",
+       " 14,\n",
+       " 0,\n",
+       " 4,\n",
+       " 3,\n",
+       " 17,\n",
+       " 13,\n",
+       " 8,\n",
+       " 19,\n",
+       " 17,\n",
+       " 13,\n",
+       " 23,\n",
+       " 4,\n",
+       " 8,\n",
+       " 6,\n",
+       " 17,\n",
+       " 15,\n",
+       " 18,\n",
+       " 18,\n",
+       " 7,\n",
+       " 0,\n",
+       " 3,\n",
+       " 7,\n",
+       " 3,\n",
+       " 19,\n",
+       " 14,\n",
+       " 8,\n",
+       " 15,\n",
+       " 0,\n",
+       " 0,\n",
+       " 19,\n",
+       " 4,\n",
+       " 23,\n",
+       " 4,\n",
+       " 13,\n",
+       " 13,\n",
+       " 4,\n",
+       " 18,\n",
+       " 0,\n",
+       " 6,\n",
+       " 17,\n",
+       " 14,\n",
+       " 1,\n",
+       " 19,\n",
+       " 11,\n",
+       " 4,\n",
+       " 18,\n",
+       " 17,\n",
+       " 13,\n",
+       " 17,\n",
+       " 14,\n",
+       " 8,\n",
+       " 17,\n",
+       " 24,\n",
+       " 15,\n",
+       " 1,\n",
+       " 6,\n",
+       " 4,\n",
+       " 3,\n",
+       " 2,\n",
+       " 11,\n",
+       " 11,\n",
+       " 8,\n",
+       " 22,\n",
+       " 0,\n",
+       " 11,\n",
+       " 0,\n",
+       " 11,\n",
+       " 4,\n",
+       " 4,\n",
+       " 13,\n",
+       " 8,\n",
+       " 6,\n",
+       " 17,\n",
+       " 17,\n",
+       " 13,\n",
+       " 22,\n",
+       " 24,\n",
+       " 17,\n",
+       " 11,\n",
+       " 8,\n",
+       " 12,\n",
+       " 11,\n",
+       " 15,\n",
+       " 18,\n",
+       " 19,\n",
+       " 14,\n",
+       " 11,\n",
+       " 4,\n",
+       " 5,\n",
+       " 19,\n",
+       " 17,\n",
+       " 3,\n",
+       " 12,\n",
+       " 20,\n",
+       " 0,\n",
+       " 17,\n",
+       " 8,\n",
+       " 4,\n",
+       " 4,\n",
+       " 4,\n",
+       " 8,\n",
+       " 8,\n",
+       " 0,\n",
+       " 14,\n",
+       " 11,\n",
+       " 13,\n",
+       " 4,\n",
+       " 22,\n",
+       " 18,\n",
+       " 0,\n",
+       " 14,\n",
+       " 7,\n",
+       " 17,\n",
+       " 19,\n",
+       " 11,\n",
+       " 18,\n",
+       " 19,\n",
+       " 14,\n",
+       " 1,\n",
+       " 4,\n",
+       " 19,\n",
+       " 13,\n",
+       " 18,\n",
+       " 11,\n",
+       " 21,\n",
+       " 5,\n",
+       " 8,\n",
+       " 21,\n",
+       " 3,\n",
+       " 14,\n",
+       " 21,\n",
+       " 19,\n",
+       " 15,\n",
+       " 14,\n",
+       " 0,\n",
+       " 4,\n",
+       " 4,\n",
+       " 8,\n",
+       " 18,\n",
+       " 2,\n",
+       " 8,\n",
+       " 14,\n",
+       " 7,\n",
+       " 8,\n",
+       " 15,\n",
+       " 18,\n",
+       " 4,\n",
+       " 21,\n",
+       " 4,\n",
+       " 4,\n",
+       " 3,\n",
+       " 19,\n",
+       " 4,\n",
+       " 22,\n",
+       " 5,\n",
+       " 0,\n",
+       " 17,\n",
+       " 13,\n",
+       " 7,\n",
+       " 4,\n",
+       " 1,\n",
+       " 11,\n",
+       " 4,\n",
+       " 0,\n",
+       " 14,\n",
+       " 19,\n",
+       " 14,\n",
+       " 7,\n",
+       " 19,\n",
+       " 19,\n",
+       " 19,\n",
+       " 4,\n",
+       " 15,\n",
+       " 13,\n",
+       " 2,\n",
+       " 10,\n",
+       " 0,\n",
+       " 14,\n",
+       " 13,\n",
+       " 7,\n",
+       " 22,\n",
+       " 4,\n",
+       " 19,\n",
+       " 12,\n",
+       " 21,\n",
+       " 24,\n",
+       " 15,\n",
+       " 17,\n",
+       " 17,\n",
+       " 4,\n",
+       " 14,\n",
+       " 13,\n",
+       " 13,\n",
+       " 0,\n",
+       " 18,\n",
+       " 6,\n",
+       " 3,\n",
+       " 4,\n",
+       " 3,\n",
+       " 14,\n",
+       " 4,\n",
+       " 4,\n",
+       " 4,\n",
+       " 14,\n",
+       " 0,\n",
+       " 0,\n",
+       " 12,\n",
+       " 19,\n",
+       " 2,\n",
+       " 8,\n",
+       " 2,\n",
+       " 19,\n",
+       " 19,\n",
+       " 8,\n",
+       " 5,\n",
+       " 13,\n",
+       " 0,\n",
+       " 3,\n",
+       " 17,\n",
+       " 4,\n",
+       " 18,\n",
+       " 17,\n",
+       " 19,\n",
+       " 18,\n",
+       " 4,\n",
+       " 17,\n",
+       " 14,\n",
+       " 18,\n",
+       " 4,\n",
+       " 19,\n",
+       " 17,\n",
+       " 7,\n",
+       " 2,\n",
+       " 8,\n",
+       " 2,\n",
+       " 19,\n",
+       " 15,\n",
+       " 18,\n",
+       " 0,\n",
+       " 0,\n",
+       " 4,\n",
+       " 7,\n",
+       " 11,\n",
+       " 3,\n",
+       " 7,\n",
+       " 18,\n",
+       " 5,\n",
+       " 23,\n",
+       " 18,\n",
+       " 14,\n",
+       " 0,\n",
+       " 14,\n",
+       " 19,\n",
+       " 2,\n",
+       " 19,\n",
+       " 1,\n",
+       " 1,\n",
+       " 18,\n",
+       " 14,\n",
+       " 4,\n",
+       " 8,\n",
+       " 17,\n",
+       " 13,\n",
+       " 18,\n",
+       " 0,\n",
+       " 3,\n",
+       " 11,\n",
+       " 24,\n",
+       " 19,\n",
+       " 17,\n",
+       " 17,\n",
+       " 20,\n",
+       " 13,\n",
+       " 17,\n",
+       " 2,\n",
+       " 4,\n",
+       " 15,\n",
+       " 19,\n",
+       " 19,\n",
+       " 7,\n",
+       " 17,\n",
+       " 4,\n",
+       " 20,\n",
+       " 7,\n",
+       " 13,\n",
+       " 10,\n",
+       " 19,\n",
+       " 0,\n",
+       " 2,\n",
+       " 4,\n",
+       " 2,\n",
+       " 4,\n",
+       " 4,\n",
+       " 11,\n",
+       " 17,\n",
+       " 22,\n",
+       " 13,\n",
+       " 8,\n",
+       " 17,\n",
+       " 4,\n",
+       " 4,\n",
+       " 4,\n",
+       " 0,\n",
+       " 4,\n",
+       " 18,\n",
+       " 4,\n",
+       " 4,\n",
+       " 4,\n",
+       " 8,\n",
+       " 3,\n",
+       " 8,\n",
+       " 18,\n",
+       " 14,\n",
+       " 6,\n",
+       " 2,\n",
+       " 4,\n",
+       " 14,\n",
+       " 12,\n",
+       " 13,\n",
+       " 17,\n",
+       " 19,\n",
+       " 4,\n",
+       " 9,\n",
+       " 7,\n",
+       " 0,\n",
+       " 6,\n",
+       " 0,\n",
+       " 1,\n",
+       " 18,\n",
+       " 4,\n",
+       " 13,\n",
+       " 8,\n",
+       " 19,\n",
+       " 11,\n",
+       " 22,\n",
+       " 19,\n",
+       " 17,\n",
+       " 13,\n",
+       " 1,\n",
+       " 12,\n",
+       " 8,\n",
+       " 4,\n",
+       " 11,\n",
+       " 18,\n",
+       " 0,\n",
+       " 17,\n",
+       " 4,\n",
+       " 19,\n",
+       " 4,\n",
+       " 18,\n",
+       " 17,\n",
+       " 13,\n",
+       " 6,\n",
+       " 18,\n",
+       " 13,\n",
+       " 7,\n",
+       " 4,\n",
+       " 1,\n",
+       " 8,\n",
+       " 14,\n",
+       " 18,\n",
+       " 3,\n",
+       " 8,\n",
+       " 4,\n",
+       " 13,\n",
+       " 0,\n",
+       " 5,\n",
+       " 11,\n",
+       " 4,\n",
+       " 8,\n",
+       " 18,\n",
+       " 0,\n",
+       " 7,\n",
+       " 14,\n",
+       " 2,\n",
+       " 8,\n",
+       " 5,\n",
+       " 4,\n",
+       " 21,\n",
+       " 12,\n",
+       " 5,\n",
+       " 0,\n",
+       " 19,\n",
+       " 0,\n",
+       " 13,\n",
+       " 0,\n",
+       " 19,\n",
+       " 17,\n",
+       " 13,\n",
+       " 8,\n",
+       " 0,\n",
+       " 6,\n",
+       " 13,\n",
+       " 7,\n",
+       " 0,\n",
+       " 19,\n",
+       " 13,\n",
+       " 12,\n",
+       " 8,\n",
+       " 1,\n",
+       " 13,\n",
+       " 8,\n",
+       " 20,\n",
+       " 5,\n",
+       " 4,\n",
+       " 13,\n",
+       " 17,\n",
+       " 19,\n",
+       " 14,\n",
+       " 19,\n",
+       " 19,\n",
+       " 17,\n",
+       " 13,\n",
+       " 24,\n",
+       " 15,\n",
+       " 0,\n",
+       " 8,\n",
+       " 3,\n",
+       " 24,\n",
+       " 8,\n",
+       " 4,\n",
+       " 6,\n",
+       " 3,\n",
+       " 13,\n",
+       " 12,\n",
+       " 4,\n",
+       " 17,\n",
+       " 7,\n",
+       " 7,\n",
+       " 8,\n",
+       " 14,\n",
+       " 19,\n",
+       " 17,\n",
+       " 4,\n",
+       " 19,\n",
+       " 2,\n",
+       " 4,\n",
+       " 18,\n",
+       " 18,\n",
+       " 4,\n",
+       " 8,\n",
+       " 11,\n",
+       " 3,\n",
+       " 17,\n",
+       " 1,\n",
+       " 2,\n",
+       " 4,\n",
+       " 15,\n",
+       " 17,\n",
+       " 8,\n",
+       " 6,\n",
+       " 0,\n",
+       " 4,\n",
+       " 18,\n",
+       " 14,\n",
+       " 0,\n",
+       " 3,\n",
+       " 11,\n",
+       " 19,\n",
+       " 0,\n",
+       " 7,\n",
+       " 8,\n",
+       " 4,\n",
+       " 21,\n",
+       " 4,\n",
+       " 1,\n",
+       " 17,\n",
+       " 2,\n",
+       " 4,\n",
+       " 13,\n",
+       " 11,\n",
+       " 4,\n",
+       " 21,\n",
+       " 0,\n",
+       " 18,\n",
+       " 0,\n",
+       " 3,\n",
+       " 13,\n",
+       " 13,\n",
+       " 19,\n",
+       " 7,\n",
+       " 13,\n",
+       " 4,\n",
+       " 8,\n",
+       " 19,\n",
+       " 4,\n",
+       " 8,\n",
+       " 8,\n",
+       " 18,\n",
+       " 0,\n",
+       " 7,\n",
+       " 20,\n",
+       " 7,\n",
+       " 7,\n",
+       " 20,\n",
+       " 0,\n",
+       " 12,\n",
+       " 14,\n",
+       " 13,\n",
+       " 4,\n",
+       " 5,\n",
+       " 24,\n",
+       " 7,\n",
+       " 11,\n",
+       " 14,\n",
+       " 13,\n",
+       " 22,\n",
+       " 7,\n",
+       " 0,\n",
+       " 4,\n",
+       " 4,\n",
+       " 4,\n",
+       " 4,\n",
+       " 14,\n",
+       " 18,\n",
+       " 13,\n",
+       " 4,\n",
+       " 4,\n",
+       " 24,\n",
+       " 0,\n",
+       " 13,\n",
+       " 4,\n",
+       " 8,\n",
+       " 18,\n",
+       " 4,\n",
+       " 19,\n",
+       " 14,\n",
+       " 6,\n",
+       " 24,\n",
+       " 8,\n",
+       " 19,\n",
+       " 4,\n",
+       " 17,\n",
+       " 11,\n",
+       " 8,\n",
+       " 7,\n",
+       " 19,\n",
+       " 2,\n",
+       " 12,\n",
+       " 8,\n",
+       " 14,\n",
+       " 8,\n",
+       " 17,\n",
+       " 0,\n",
+       " 17,\n",
+       " 5,\n",
+       " 3,\n",
+       " 14,\n",
+       " 4,\n",
+       " 19,\n",
+       " 13,\n",
+       " 8,\n",
+       " 7,\n",
+       " 19,\n",
+       " 13,\n",
+       " 4,\n",
+       " 7,\n",
+       " 8,\n",
+       " 8,\n",
+       " 10,\n",
+       " 0,\n",
+       " 12,\n",
+       " 17,\n",
+       " 3,\n",
+       " 12,\n",
+       " 13,\n",
+       " 0,\n",
+       " 3,\n",
+       " 0,\n",
+       " 13,\n",
+       " 0,\n",
+       " 14,\n",
+       " 3,\n",
+       " 18,\n",
+       " 4,\n",
+       " 18,\n",
+       " 4,\n",
+       " 8,\n",
+       " 24,\n",
+       " 2,\n",
+       " 11,\n",
+       " 18,\n",
+       " 8,\n",
+       " 0,\n",
+       " 13,\n",
+       " 19,\n",
+       " 0,\n",
+       " 14,\n",
+       " 11,\n",
+       " 19,\n",
+       " 2,\n",
+       " 8,\n",
+       " 24,\n",
+       " 12,\n",
+       " 8,\n",
+       " 3,\n",
+       " 4,\n",
+       " 13,\n",
+       " 19,\n",
+       " 19,\n",
+       " 7,\n",
+       " 11,\n",
+       " 19,\n",
+       " 13,\n",
+       " 3,\n",
+       " 23,\n",
+       " 19,\n",
+       " 19,\n",
+       " 19,\n",
+       " 12,\n",
+       " 0,\n",
+       " 18,\n",
+       " 1,\n",
+       " 11,\n",
+       " 4,\n",
+       " 0,\n",
+       " 4,\n",
+       " 4,\n",
+       " 19,\n",
+       " 11,\n",
+       " 8,\n",
+       " 18,\n",
+       " 8,\n",
+       " 17,\n",
+       " 19,\n",
+       " 22,\n",
+       " 19,\n",
+       " 20,\n",
+       " 17,\n",
+       " 15,\n",
+       " 5,\n",
+       " 0,\n",
+       " 8,\n",
+       " 11,\n",
+       " 19,\n",
+       " 4,\n",
+       " 0,\n",
+       " 14,\n",
+       " 4,\n",
+       " 5,\n",
+       " 4,\n",
+       " 8,\n",
+       " 18,\n",
+       " 8,\n",
+       " 8,\n",
+       " 8,\n",
+       " 24,\n",
+       " 8,\n",
+       " 18,\n",
+       " 8,\n",
+       " 10,\n",
+       " 21,\n",
+       " 19,\n",
+       " 22,\n",
+       " 8,\n",
+       " 18,\n",
+       " 15,\n",
+       " 17,\n",
+       " 1,\n",
+       " 18,\n",
+       " 8,\n",
+       " 13,\n",
+       " 4,\n",
+       " 11,\n",
+       " 15,\n",
+       " 7,\n",
+       " 17,\n",
+       " 12,\n",
+       " 14,\n",
+       " 7,\n",
+       " 8,\n",
+       " 0,\n",
+       " 6,\n",
+       " 13,\n",
+       " 11,\n",
+       " 18,\n",
+       " 11,\n",
+       " 21,\n",
+       " 8,\n",
+       " 19,\n",
+       " 14,\n",
+       " 3,\n",
+       " 0,\n",
+       " 8,\n",
+       " 18,\n",
+       " 3,\n",
+       " 15,\n",
+       " 13,\n",
+       " 24,\n",
+       " 3,\n",
+       " 3,\n",
+       " 2,\n",
+       " 0,\n",
+       " 0,\n",
+       " 14,\n",
+       " 19,\n",
+       " 0,\n",
+       " 7,\n",
+       " 2,\n",
+       " 4,\n",
+       " 7,\n",
+       " 19,\n",
+       " 20,\n",
+       " 4,\n",
+       " 8,\n",
+       " 17,\n",
+       " 17,\n",
+       " 4,\n",
+       " 3,\n",
+       " 0,\n",
+       " 4,\n",
+       " 2,\n",
+       " 19,\n",
+       " 14,\n",
+       " 18,\n",
+       " 13,\n",
+       " 17,\n",
+       " 7,\n",
+       " 21,\n",
+       " 13,\n",
+       " 0,\n",
+       " 14,\n",
+       " 3,\n",
+       " 14,\n",
+       " 8,\n",
+       " 10,\n",
+       " 14,\n",
+       " 4,\n",
+       " 19,\n",
+       " 2,\n",
+       " 8,\n",
+       " 13,\n",
+       " 4,\n",
+       " 13,\n",
+       " 4,\n",
+       " 20,\n",
+       " 17,\n",
+       " 17,\n",
+       " 8,\n",
+       " 18,\n",
+       " 3,\n",
+       " 2,\n",
+       " 14,\n",
+       " 20,\n",
+       " 17,\n",
+       " 0,\n",
+       " 6,\n",
+       " 11,\n",
+       " 21,\n",
+       " 8,\n",
+       " 12,\n",
+       " 12,\n",
+       " 20,\n",
+       " 15,\n",
+       " 15,\n",
+       " 3,\n",
+       " 8,\n",
+       " 19,\n",
+       " 4,\n",
+       " 0,\n",
+       " 13,\n",
+       " 3,\n",
+       " 8,\n",
+       " 19,\n",
+       " 12,\n",
+       " 0,\n",
+       " 0,\n",
+       " 8,\n",
+       " 0,\n",
+       " 8,\n",
+       " 4,\n",
+       " 11,\n",
+       " 4,\n",
+       " 14,\n",
+       " 13,\n",
+       " 13,\n",
+       " 17,\n",
+       " 4,\n",
+       " 4,\n",
+       " 3,\n",
+       " 0,\n",
+       " 14,\n",
+       " 3,\n",
+       " 1,\n",
+       " 14,\n",
+       " 8,\n",
+       " 20,\n",
+       " 12,\n",
+       " 4,\n",
+       " 11,\n",
+       " 17,\n",
+       " 14,\n",
+       " 19,\n",
+       " 13,\n",
+       " 19,\n",
+       " 19,\n",
+       " 19,\n",
+       " 6,\n",
+       " 8,\n",
+       " 19,\n",
+       " 13,\n",
+       " ...]"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[(int(c, 2)) for c in chunks(c8b, 5)]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "24"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "max([(int(c, 2)) for c in chunks(c8b, 5)])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'y'"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "max([chr(int(c, 2) + ord('a')) for c in chunks(c8b, 5)])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'y'"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "max([unpos(int(c, 2)) for c in chunks(c8b, 5)])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def cadenus_letter(n, doubled='v'):\n",
+    "    letter = chr(n + ord('a'))\n",
+    "    if letter > doubled:\n",
+    "        letter = chr(n + ord('a') + 1)\n",
+    "    return letter"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def cadenus_letter(n, doubled='v'):\n",
+    "    letter = unpos(n)\n",
+    "    if letter > doubled:\n",
+    "        letter = unpos(n + 1)\n",
+    "    return letter"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('afcaeuottacthrioletcserthshtrahkzorpfrgeoadppjnglternefeofiortsddoeeumscruernfetlaafstxientrvoonerhuahravereetsvsielhlostdoalozaesmnndignnrhohhtsnaoilncnssicreanneeiiierxtanesrvogieizxssdgpvoiaisaoaeoaedrnitrnyeigrpsshadhdtoipaateyennesagrobtlesrnroirzpbgedcllixalaleenigrrnxzrlimlpstoleftrdmuarieeeiiaolnexsaohrtlstobetnslvfivdovtpoaeeisciohipseveedtexfarnhebleaotohtttepnckaonhxetmvzprreonnasgdedoeeeoaamtcicttifnadresrtserosetrhcictpsaaehldhsfysoaotctbbsoeirnsadlztrrunrceptthreuhnktaceceelrxnireeeaeseeeidisogceomnrtejhagabsenitlxtrnbmielsaretesrngsnhebiosdienafleisahocifevmfatanatrniagnhatnmibniufenrtottrnzpaidziegdnmerhhiotretcesseildrbceprigaesoadltahievebrcenlevasadnnthneiteiisahuhhuamonefzhlonxhaeeeeosneezaneisetogziterlihtcmioirarfdoetnihtnehiikamrdmnadanaodseseizclsiantaoltcizmidentthltndytttmasbleaeetlisirtxturpfailteaoefeisiiizisikvtxisprbsinelphrmohiagnlslvitodaisdpnzddcaaotahcehtueirredaectosnrhvnaodoikoetcineneurrisdcouraglvimmuppditeanditmaaiaieleonnreedaodboiumelrotntttgitnrlrienniklzsogstcifzpipvidvssmnceiasiitsnneatitomrhbnhnidprlrepoznalsnvsdosanesitfaenltgodatteeaisicrootmsmfhauenirsghznxeintegodiileedtarnosrcaaendtcuttfdrbehtmfitoordruiaozaanoeeldoinhusgiteaoriecevemntratmtfpeucutahamtnexonicdeemrpaolitoafesoosspfnlneeootachllirssysofpdftfrnpraeeazlonahautntcntcbaxloneftoatecvoxdlxvnneedtiioigtegmtaheeatefaaeprrcrosheerrpalediengidrreouhvesuroztnsosinuiuiofprda',\n",
+       " -1814.2525644323327)"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c8bl = ''.join([cadenus_letter(int(c, 2)) for c in chunks(c8b, 5)])\n",
+    "c8bl, Pletters(c8bl)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('afcaeuottacthrioletcserthshtrahkyorpfrgeoadppjnglternefeofiortsddoeeumscruernfetlaafstwientrvoonerhuahravereetsvsielhlostdoaloyaesmnndignnrhohhtsnaoilncnssicreanneeiiierwtanesrvogieiywssdgpvoiaisaoaeoaedrnitrnxeigrpsshadhdtoipaatexennesagrobtlesrnroirypbgedclliwalaleenigrrnwyrlimlpstoleftrdmuarieeeiiaolnewsaohrtlstobetnslvfivdovtpoaeeisciohipseveedtewfarnhebleaotohtttepnckaonhwetmvyprreonnasgdedoeeeoaamtcicttifnadresrtserosetrhcictpsaaehldhsfxsoaotctbbsoeirnsadlytrrunrceptthreuhnktaceceelrwnireeeaeseeeidisogceomnrtejhagabsenitlwtrnbmielsaretesrngsnhebiosdienafleisahocifevmfatanatrniagnhatnmibniufenrtottrnypaidyiegdnmerhhiotretcesseildrbceprigaesoadltahievebrcenlevasadnnthneiteiisahuhhuamonefyhlonwhaeeeeosneeyaneisetogyiterlihtcmioirarfdoetnihtnehiikamrdmnadanaodseseiyclsiantaoltciymidentthltndxtttmasbleaeetlisirtwturpfailteaoefeisiiiyisikvtwisprbsinelphrmohiagnlslvitodaisdpnyddcaaotahcehtueirredaectosnrhvnaodoikoetcineneurrisdcouraglvimmuppditeanditmaaiaieleonnreedaodboiumelrotntttgitnrlrienniklysogstcifypipvidvssmnceiasiitsnneatitomrhbnhnidprlrepoynalsnvsdosanesitfaenltgodatteeaisicrootmsmfhauenirsghynweintegodiileedtarnosrcaaendtcuttfdrbehtmfitoordruiaoyaanoeeldoinhusgiteaoriecevemntratmtfpeucutahamtnewonicdeemrpaolitoafesoosspfnlneeootachllirssxsofpdftfrnpraeeaylonahautntcntcbawloneftoatecvowdlwvnneedtiioigtegmtaheeatefaaeprrcrosheerrpalediengidrreouhvesuroytnsosinuiuiofprda',\n",
+       " -1760.1126100904926)"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c8bl = ''.join([cadenus_letter(int(c, 2), doubled='z') for c in chunks(c8b, 5)])\n",
+    "c8bl, Pletters(c8bl)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'y'"
+      ]
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "max((cl for cl in string.ascii_lowercase),\n",
+    "   key=lambda l: Pletters(cadenus_letter(int(c, 2), doubled=l) for c in chunks(c8b, 5)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('afcaeuottacthrioletcserthshtrahkzorpfrgeoadppjnglternefeofiortsddoeeumscruernfetlaafstxientrvoonerhuahravereetsvsielhlostdoalozaesmnndignnrhohhtsnaoilncnssicreanneeiiierxtanesrvogieizxssdgpvoiaisaoaeoaedrnitrnyeigrpsshadhdtoipaateyennesagrobtlesrnroirzpbgedcllixalaleenigrrnxzrlimlpstoleftrdmuarieeeiiaolnexsaohrtlstobetnslvfivdovtpoaeeisciohipseveedtexfarnhebleaotohtttepnckaonhxetmvzprreonnasgdedoeeeoaamtcicttifnadresrtserosetrhcictpsaaehldhsfysoaotctbbsoeirnsadlztrrunrceptthreuhnktaceceelrxnireeeaeseeeidisogceomnrtejhagabsenitlxtrnbmielsaretesrngsnhebiosdienafleisahocifevmfatanatrniagnhatnmibniufenrtottrnzpaidziegdnmerhhiotretcesseildrbceprigaesoadltahievebrcenlevasadnnthneiteiisahuhhuamonefzhlonxhaeeeeosneezaneisetogziterlihtcmioirarfdoetnihtnehiikamrdmnadanaodseseizclsiantaoltcizmidentthltndytttmasbleaeetlisirtxturpfailteaoefeisiiizisikvtxisprbsinelphrmohiagnlslvitodaisdpnzddcaaotahcehtueirredaectosnrhvnaodoikoetcineneurrisdcouraglvimmuppditeanditmaaiaieleonnreedaodboiumelrotntttgitnrlrienniklzsogstcifzpipvidvssmnceiasiitsnneatitomrhbnhnidprlrepoznalsnvsdosanesitfaenltgodatteeaisicrootmsmfhauenirsghznxeintegodiileedtarnosrcaaendtcuttfdrbehtmfitoordruiaozaanoeeldoinhusgiteaoriecevemntratmtfpeucutahamtnexonicdeemrpaolitoafesoosspfnlneeootachllirssysofpdftfrnpraeeazlonahautntcntcbaxloneftoatecvoxdlxvnneedtiioigtegmtaheeatefaaeprrcrosheerrpalediengidrreouhvesuroztnsosinuiuiofprda',\n",
+       " -1814.2525644323327)"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c8bl = ''.join([cadenus_letter(int(c, 2), doubled='v') for c in chunks(c8b, 5)])\n",
+    "c8bl, Pletters(c8bl)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('a', 'z')"
+      ]
+     },
+     "execution_count": 19,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "min(c8bl), max(c8bl)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(1400, 56.0)"
+      ]
+     },
+     "execution_count": 20,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(c8bl), len(c8bl) / 25"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<matplotlib.axes._subplots.AxesSubplot at 0x7f37f275c390>"
+      ]
+     },
+     "execution_count": 21,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f37f2757470>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "freqs_8b = pd.Series(collections.Counter([l.lower() for l in c8bl if l in string.ascii_letters]))\n",
+    "freqs_8b.plot(kind='bar')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<matplotlib.axes._subplots.AxesSubplot at 0x7f37f26b4c50>"
+      ]
+     },
+     "execution_count": 22,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f37f27526a0>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "freqs = pd.Series(english_counts)\n",
+    "freqs.plot(kind='bar')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['afcaeuottacthrioletcserthshtrahkzorpfrgeoadppjnglternefe',\n",
+       " 'ofiortsddoeeumscruernfetlaafstxientrvoonerhuahravereetsv',\n",
+       " 'sielhlostdoalozaesmnndignnrhohhtsnaoilncnssicreanneeiiie',\n",
+       " 'rxtanesrvogieizxssdgpvoiaisaoaeoaedrnitrnyeigrpsshadhdto',\n",
+       " 'ipaateyennesagrobtlesrnroirzpbgedcllixalaleenigrrnxzrlim',\n",
+       " 'lpstoleftrdmuarieeeiiaolnexsaohrtlstobetnslvfivdovtpoaee',\n",
+       " 'isciohipseveedtexfarnhebleaotohtttepnckaonhxetmvzprreonn',\n",
+       " 'asgdedoeeeoaamtcicttifnadresrtserosetrhcictpsaaehldhsfys',\n",
+       " 'oaotctbbsoeirnsadlztrrunrceptthreuhnktaceceelrxnireeeaes',\n",
+       " 'eeeidisogceomnrtejhagabsenitlxtrnbmielsaretesrngsnhebios',\n",
+       " 'dienafleisahocifevmfatanatrniagnhatnmibniufenrtottrnzpai',\n",
+       " 'dziegdnmerhhiotretcesseildrbceprigaesoadltahievebrcenlev',\n",
+       " 'asadnnthneiteiisahuhhuamonefzhlonxhaeeeeosneezaneisetogz',\n",
+       " 'iterlihtcmioirarfdoetnihtnehiikamrdmnadanaodseseizclsian',\n",
+       " 'taoltcizmidentthltndytttmasbleaeetlisirtxturpfailteaoefe',\n",
+       " 'isiiizisikvtxisprbsinelphrmohiagnlslvitodaisdpnzddcaaota',\n",
+       " 'hcehtueirredaectosnrhvnaodoikoetcineneurrisdcouraglvimmu',\n",
+       " 'ppditeanditmaaiaieleonnreedaodboiumelrotntttgitnrlrienni',\n",
+       " 'klzsogstcifzpipvidvssmnceiasiitsnneatitomrhbnhnidprlrepo',\n",
+       " 'znalsnvsdosanesitfaenltgodatteeaisicrootmsmfhauenirsghzn',\n",
+       " 'xeintegodiileedtarnosrcaaendtcuttfdrbehtmfitoordruiaozaa',\n",
+       " 'noeeldoinhusgiteaoriecevemntratmtfpeucutahamtnexonicdeem',\n",
+       " 'rpaolitoafesoosspfnlneeootachllirssysofpdftfrnpraeeazlon',\n",
+       " 'ahautntcntcbaxloneftoatecvoxdlxvnneedtiioigtegmtaheeatef',\n",
+       " 'aaeprrcrosheerrpalediengidrreouhvesuroztnsosinuiuiofprda']"
+      ]
+     },
+     "execution_count": 23,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "rows = chunks(c8bl, len(c8bl) // 25)\n",
+    "rows"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['a..ae....a..h....e..se..hsh..ah....p...e.a.pp.....e..e.e',\n",
+       " '......s...ee..s...e...e..aa.s...e.......e.h.ah.a.e.ee.s.',\n",
+       " 's.e.h..s...a...aes.........h.hh.s.a......ss...ea..ee...e',\n",
+       " '...a.es.....e...ss..p...a.sa.ae.ae........e...pssha.h...',\n",
+       " '.paa.e.e..esa......es.......p..e......a.a.ee............',\n",
+       " '.ps...e......a..eee..a...e.sa.h...s...e..s.........p.aee',\n",
+       " '.s...h.pse.ee..e..a..he..ea...h...ep...a..h.e....p..e...',\n",
+       " 'as..e..eee.aa..........a..es..se..se..h....psaaeh..hs..s',\n",
+       " '.a......s.e...sa..........ep..h.e.h...a.e.ee......eeeaes',\n",
+       " 'eee...s...e.....e.ha.a.se...........e.sa.e.es...s.he...s',\n",
+       " '..e.a..e.sah....e...a.a.a....a..ha.........e.........pa.',\n",
+       " '...e....e.hh....e..esse......ep...aes.a...ah.e.e...e..e.',\n",
+       " 'asa....h.e..e..sah.hh.a...e..h....haeeee.s.ee.a.e.se....',\n",
+       " '..e...h.......a....e...h..eh...a.....a.a.a..sese....s.a.',\n",
+       " '.a.........e...h.........as..eaee...s.......p.a...ea.e.e',\n",
+       " '.s.....s......sp..s..e.ph...h.a...s......a.s.p.....aa..a',\n",
+       " 'h.eh..e...e.ae...s..h..a......e....e.e....s.....a.......',\n",
+       " 'pp...ea.....aa.a.e.e....ee.a.......e................e...',\n",
+       " '...s..s.....p.p....ss...e.as...s..ea......h..h...p...ep.',\n",
+       " '..a.s..s..sa.es...ae......a..eea.s.......s..ha.e...s.h..',\n",
+       " '.e...e......ee..a...s..aae...........eh............a..aa',\n",
+       " '..ee.....h.s...ea...e.e.e....a....pe....aha...e......ee.',\n",
+       " '.pa.....a.es..ssp....ee...a.h....ss.s..p......p.aeea....',\n",
+       " 'aha.........a....e...a.e..........ee........e...aheea.e.',\n",
+       " 'aaep.....shee..pa.e..e......e..h.es......s.s........p..a']"
+      ]
+     },
+     "execution_count": 24,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "chunks(''.join([l if l in 'phase' else '.' for l in c8bl]), 56)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['aosriliaoeddaitihpkzxnraa',\n",
+       " 'ffixppssaeizstascplneopha',\n",
+       " 'cietascgoeeiaeoiedzaieaae',\n",
+       " 'aolaatidtinedrlihislneoup',\n",
+       " 'erhntooecdagnltittostlltr',\n",
+       " 'utleelhdtifdniczuegnedinr',\n",
+       " 'ososyeiobslnthiieasvgottc',\n",
+       " 'tdsrefpeboemhtzsintsoiocr',\n",
+       " 'tdtvntsesgiencmirdcddnano',\n",
+       " 'aodonreeocsremikriioihfts',\n",
+       " 'ceogedvoeeahiidvetfsiuech',\n",
+       " 'teaismeaiohhtoetdmzalssbe',\n",
+       " 'huleauearmoieinxaapnegoae',\n",
+       " 'rmoigadmnncoirtieaieeioxr',\n",
+       " 'iszzrrttsritiatscipsdtslr',\n",
+       " 'ocaxoiecatfrsrhptavitesop',\n",
+       " 'lresbexideeeaflroiitaapna',\n",
+       " 'eusstefcljvthdtbsedfrofel',\n",
+       " 'temdleatzhmcuonsnlvanrnfe',\n",
+       " 'crngeirttafehedireseoiltd',\n",
+       " 'snnpsinirgashtynhosnsenoi',\n",
+       " 'efdvrahfratsuntevnmlrceae',\n",
+       " 'reionoenubaeaitlnnntceetn',\n",
+       " 'ttgirlbansnimhtparcgavoeg',\n",
+       " 'hlnaonldrealotmhoeeoaeoci',\n",
+       " 'saniieercntdnnardeidemtvd',\n",
+       " 'harsrxaeeirreesmodaannaor',\n",
+       " 'tfhazsosptnbfhboiastdtcxr',\n",
+       " 'rsoopatrtliczilhkoittrhde',\n",
+       " 'athaboottxaehieiodiecallo',\n",
+       " 'hxheghhshtgplkaaebteutlxu',\n",
+       " 'kitoerterrnroaegtosatmivh',\n",
+       " 'zesadttrenhinmencinittrnv',\n",
+       " 'onnecltoubagxrtliunsffsne',\n",
+       " 'rtadlseshmtahdlsnmeidpses',\n",
+       " 'prorltpenineamileeacreyeu',\n",
+       " 'fviniontkemsensvnltrbusdr',\n",
+       " 'rolixbcrtlioeaiierioecoto',\n",
+       " 'gontaekhasbaedrtuotohufiz',\n",
+       " 'encrltaccandeatortotttpit',\n",
+       " 'oennanoierilonxdrnmmmadon',\n",
+       " 'arsylsncceutsataitrsfhfis',\n",
+       " 'dhseelhtetfanouisthmiatgo',\n",
+       " 'puiievxpeeehedrsdtbftmfts',\n",
+       " 'pacgnfeslsniespdcgnhotrei',\n",
+       " 'jhrriitarrrezefpoihaonngn',\n",
+       " 'nrepgvmaxntvasanutnurepmu',\n",
+       " 'gaasrdvengoeneizrniedxrti',\n",
+       " 'lvnsrozhistbeildardnroaau',\n",
+       " 'tenhnvplrntriztdglpiunehi',\n",
+       " 'ereaxtrdehrcsceclrrriieeo',\n",
+       " 'reedzprheeneelaavilsacaef',\n",
+       " 'neihroesebzntsoaiergodzap',\n",
+       " 'etidlaofaiploieomnehzeltr',\n",
+       " 'fsitienyeoaegaftmnpzaeoed',\n",
+       " 'eveomensssivzneauionamnfa']"
+      ]
+     },
+     "execution_count": 25,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "columns = [''.join(c) for c in zip(*rows)]\n",
+    "columns"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'a': [(0, 0),\n",
+       "  (0, 3),\n",
+       "  (0, 9),\n",
+       "  (0, 29),\n",
+       "  (0, 41),\n",
+       "  (1, 25),\n",
+       "  (1, 26),\n",
+       "  (1, 44),\n",
+       "  (1, 47),\n",
+       "  (2, 11),\n",
+       "  (2, 15),\n",
+       "  (2, 34),\n",
+       "  (2, 47),\n",
+       "  (3, 3),\n",
+       "  (3, 24),\n",
+       "  (3, 27),\n",
+       "  (3, 29),\n",
+       "  (3, 32),\n",
+       "  (3, 50),\n",
+       "  (4, 2),\n",
+       "  (4, 3),\n",
+       "  (4, 12),\n",
+       "  (4, 38),\n",
+       "  (4, 40),\n",
+       "  (5, 13),\n",
+       "  (5, 21),\n",
+       "  (5, 28),\n",
+       "  (5, 53),\n",
+       "  (6, 18),\n",
+       "  (6, 26),\n",
+       "  (6, 39),\n",
+       "  (7, 0),\n",
+       "  (7, 11),\n",
+       "  (7, 12),\n",
+       "  (7, 23),\n",
+       "  (7, 45),\n",
+       "  (7, 46),\n",
+       "  (8, 1),\n",
+       "  (8, 15),\n",
+       "  (8, 38),\n",
+       "  (8, 53),\n",
+       "  (9, 19),\n",
+       "  (9, 21),\n",
+       "  (9, 39),\n",
+       "  (10, 4),\n",
+       "  (10, 10),\n",
+       "  (10, 20),\n",
+       "  (10, 22),\n",
+       "  (10, 24),\n",
+       "  (10, 29),\n",
+       "  (10, 33),\n",
+       "  (10, 54),\n",
+       "  (11, 34),\n",
+       "  (11, 38),\n",
+       "  (11, 42),\n",
+       "  (12, 0),\n",
+       "  (12, 2),\n",
+       "  (12, 16),\n",
+       "  (12, 22),\n",
+       "  (12, 35),\n",
+       "  (12, 46),\n",
+       "  (13, 14),\n",
+       "  (13, 31),\n",
+       "  (13, 37),\n",
+       "  (13, 39),\n",
+       "  (13, 41),\n",
+       "  (13, 54),\n",
+       "  (14, 1),\n",
+       "  (14, 25),\n",
+       "  (14, 30),\n",
+       "  (14, 46),\n",
+       "  (14, 51),\n",
+       "  (15, 30),\n",
+       "  (15, 41),\n",
+       "  (15, 51),\n",
+       "  (15, 52),\n",
+       "  (15, 55),\n",
+       "  (16, 12),\n",
+       "  (16, 23),\n",
+       "  (16, 48),\n",
+       "  (17, 6),\n",
+       "  (17, 12),\n",
+       "  (17, 13),\n",
+       "  (17, 15),\n",
+       "  (17, 27),\n",
+       "  (18, 26),\n",
+       "  (18, 35),\n",
+       "  (19, 2),\n",
+       "  (19, 11),\n",
+       "  (19, 18),\n",
+       "  (19, 26),\n",
+       "  (19, 31),\n",
+       "  (19, 45),\n",
+       "  (20, 16),\n",
+       "  (20, 23),\n",
+       "  (20, 24),\n",
+       "  (20, 51),\n",
+       "  (20, 54),\n",
+       "  (20, 55),\n",
+       "  (21, 16),\n",
+       "  (21, 29),\n",
+       "  (21, 40),\n",
+       "  (21, 42),\n",
+       "  (22, 2),\n",
+       "  (22, 8),\n",
+       "  (22, 26),\n",
+       "  (22, 48),\n",
+       "  (22, 51),\n",
+       "  (23, 0),\n",
+       "  (23, 2),\n",
+       "  (23, 12),\n",
+       "  (23, 21),\n",
+       "  (23, 48),\n",
+       "  (23, 52),\n",
+       "  (24, 0),\n",
+       "  (24, 1),\n",
+       "  (24, 16),\n",
+       "  (24, 55)],\n",
+       " 'e': [(0, 4),\n",
+       "  (0, 17),\n",
+       "  (0, 21),\n",
+       "  (0, 39),\n",
+       "  (0, 50),\n",
+       "  (0, 53),\n",
+       "  (0, 55),\n",
+       "  (1, 10),\n",
+       "  (1, 11),\n",
+       "  (1, 18),\n",
+       "  (1, 22),\n",
+       "  (1, 32),\n",
+       "  (1, 40),\n",
+       "  (1, 49),\n",
+       "  (1, 51),\n",
+       "  (1, 52),\n",
+       "  (2, 2),\n",
+       "  (2, 16),\n",
+       "  (2, 46),\n",
+       "  (2, 50),\n",
+       "  (2, 51),\n",
+       "  (2, 55),\n",
+       "  (3, 5),\n",
+       "  (3, 12),\n",
+       "  (3, 30),\n",
+       "  (3, 33),\n",
+       "  (3, 42),\n",
+       "  (4, 5),\n",
+       "  (4, 7),\n",
+       "  (4, 10),\n",
+       "  (4, 19),\n",
+       "  (4, 31),\n",
+       "  (4, 42),\n",
+       "  (4, 43),\n",
+       "  (5, 6),\n",
+       "  (5, 16),\n",
+       "  (5, 17),\n",
+       "  (5, 18),\n",
+       "  (5, 25),\n",
+       "  (5, 38),\n",
+       "  (5, 54),\n",
+       "  (5, 55),\n",
+       "  (6, 9),\n",
+       "  (6, 11),\n",
+       "  (6, 12),\n",
+       "  (6, 15),\n",
+       "  (6, 22),\n",
+       "  (6, 25),\n",
+       "  (6, 34),\n",
+       "  (6, 44),\n",
+       "  (6, 52),\n",
+       "  (7, 4),\n",
+       "  (7, 7),\n",
+       "  (7, 8),\n",
+       "  (7, 9),\n",
+       "  (7, 26),\n",
+       "  (7, 31),\n",
+       "  (7, 35),\n",
+       "  (7, 47),\n",
+       "  (8, 10),\n",
+       "  (8, 26),\n",
+       "  (8, 32),\n",
+       "  (8, 40),\n",
+       "  (8, 42),\n",
+       "  (8, 43),\n",
+       "  (8, 50),\n",
+       "  (8, 51),\n",
+       "  (8, 52),\n",
+       "  (8, 54),\n",
+       "  (9, 0),\n",
+       "  (9, 1),\n",
+       "  (9, 2),\n",
+       "  (9, 10),\n",
+       "  (9, 16),\n",
+       "  (9, 24),\n",
+       "  (9, 36),\n",
+       "  (9, 41),\n",
+       "  (9, 43),\n",
+       "  (9, 51),\n",
+       "  (10, 2),\n",
+       "  (10, 7),\n",
+       "  (10, 16),\n",
+       "  (10, 43),\n",
+       "  (11, 3),\n",
+       "  (11, 8),\n",
+       "  (11, 16),\n",
+       "  (11, 19),\n",
+       "  (11, 22),\n",
+       "  (11, 29),\n",
+       "  (11, 35),\n",
+       "  (11, 45),\n",
+       "  (11, 47),\n",
+       "  (11, 51),\n",
+       "  (11, 54),\n",
+       "  (12, 9),\n",
+       "  (12, 12),\n",
+       "  (12, 26),\n",
+       "  (12, 36),\n",
+       "  (12, 37),\n",
+       "  (12, 38),\n",
+       "  (12, 39),\n",
+       "  (12, 43),\n",
+       "  (12, 44),\n",
+       "  (12, 48),\n",
+       "  (12, 51),\n",
+       "  (13, 2),\n",
+       "  (13, 19),\n",
+       "  (13, 26),\n",
+       "  (13, 45),\n",
+       "  (13, 47),\n",
+       "  (14, 11),\n",
+       "  (14, 29),\n",
+       "  (14, 31),\n",
+       "  (14, 32),\n",
+       "  (14, 50),\n",
+       "  (14, 53),\n",
+       "  (14, 55),\n",
+       "  (15, 21),\n",
+       "  (16, 2),\n",
+       "  (16, 6),\n",
+       "  (16, 10),\n",
+       "  (16, 13),\n",
+       "  (16, 30),\n",
+       "  (16, 35),\n",
+       "  (16, 37),\n",
+       "  (17, 5),\n",
+       "  (17, 17),\n",
+       "  (17, 19),\n",
+       "  (17, 24),\n",
+       "  (17, 25),\n",
+       "  (17, 35),\n",
+       "  (17, 52),\n",
+       "  (18, 24),\n",
+       "  (18, 34),\n",
+       "  (18, 53),\n",
+       "  (19, 13),\n",
+       "  (19, 19),\n",
+       "  (19, 29),\n",
+       "  (19, 30),\n",
+       "  (19, 47),\n",
+       "  (20, 1),\n",
+       "  (20, 5),\n",
+       "  (20, 12),\n",
+       "  (20, 13),\n",
+       "  (20, 25),\n",
+       "  (20, 37),\n",
+       "  (21, 2),\n",
+       "  (21, 3),\n",
+       "  (21, 15),\n",
+       "  (21, 20),\n",
+       "  (21, 22),\n",
+       "  (21, 24),\n",
+       "  (21, 35),\n",
+       "  (21, 46),\n",
+       "  (21, 53),\n",
+       "  (21, 54),\n",
+       "  (22, 10),\n",
+       "  (22, 21),\n",
+       "  (22, 22),\n",
+       "  (22, 49),\n",
+       "  (22, 50),\n",
+       "  (23, 17),\n",
+       "  (23, 23),\n",
+       "  (23, 34),\n",
+       "  (23, 35),\n",
+       "  (23, 44),\n",
+       "  (23, 50),\n",
+       "  (23, 51),\n",
+       "  (23, 54),\n",
+       "  (24, 2),\n",
+       "  (24, 11),\n",
+       "  (24, 12),\n",
+       "  (24, 18),\n",
+       "  (24, 21),\n",
+       "  (24, 28),\n",
+       "  (24, 33)],\n",
+       " 'h': [(0, 12),\n",
+       "  (0, 24),\n",
+       "  (0, 26),\n",
+       "  (0, 30),\n",
+       "  (1, 42),\n",
+       "  (1, 45),\n",
+       "  (2, 4),\n",
+       "  (2, 27),\n",
+       "  (2, 29),\n",
+       "  (2, 30),\n",
+       "  (3, 49),\n",
+       "  (3, 52),\n",
+       "  (5, 30),\n",
+       "  (6, 5),\n",
+       "  (6, 21),\n",
+       "  (6, 30),\n",
+       "  (6, 42),\n",
+       "  (7, 38),\n",
+       "  (7, 48),\n",
+       "  (7, 51),\n",
+       "  (8, 30),\n",
+       "  (8, 34),\n",
+       "  (9, 18),\n",
+       "  (9, 50),\n",
+       "  (10, 11),\n",
+       "  (10, 32),\n",
+       "  (11, 10),\n",
+       "  (11, 11),\n",
+       "  (11, 43),\n",
+       "  (12, 7),\n",
+       "  (12, 17),\n",
+       "  (12, 19),\n",
+       "  (12, 20),\n",
+       "  (12, 29),\n",
+       "  (12, 34),\n",
+       "  (13, 6),\n",
+       "  (13, 23),\n",
+       "  (13, 27),\n",
+       "  (14, 15),\n",
+       "  (15, 24),\n",
+       "  (15, 28),\n",
+       "  (16, 0),\n",
+       "  (16, 3),\n",
+       "  (16, 20),\n",
+       "  (18, 42),\n",
+       "  (18, 45),\n",
+       "  (19, 44),\n",
+       "  (19, 53),\n",
+       "  (20, 38),\n",
+       "  (21, 9),\n",
+       "  (21, 41),\n",
+       "  (22, 28),\n",
+       "  (23, 1),\n",
+       "  (23, 49),\n",
+       "  (24, 10),\n",
+       "  (24, 31)],\n",
+       " 'n': [(0, 46),\n",
+       "  (0, 52),\n",
+       "  (1, 20),\n",
+       "  (1, 33),\n",
+       "  (1, 39),\n",
+       "  (2, 19),\n",
+       "  (2, 20),\n",
+       "  (2, 24),\n",
+       "  (2, 25),\n",
+       "  (2, 33),\n",
+       "  (2, 38),\n",
+       "  (2, 40),\n",
+       "  (2, 48),\n",
+       "  (2, 49),\n",
+       "  (3, 4),\n",
+       "  (3, 36),\n",
+       "  (3, 40),\n",
+       "  (4, 8),\n",
+       "  (4, 9),\n",
+       "  (4, 22),\n",
+       "  (4, 44),\n",
+       "  (4, 49),\n",
+       "  (5, 24),\n",
+       "  (5, 40),\n",
+       "  (6, 20),\n",
+       "  (6, 36),\n",
+       "  (6, 41),\n",
+       "  (6, 54),\n",
+       "  (6, 55),\n",
+       "  (7, 22),\n",
+       "  (8, 13),\n",
+       "  (8, 23),\n",
+       "  (8, 35),\n",
+       "  (8, 47),\n",
+       "  (9, 13),\n",
+       "  (9, 25),\n",
+       "  (9, 32),\n",
+       "  (9, 46),\n",
+       "  (9, 49),\n",
+       "  (10, 3),\n",
+       "  (10, 23),\n",
+       "  (10, 27),\n",
+       "  (10, 31),\n",
+       "  (10, 35),\n",
+       "  (10, 39),\n",
+       "  (10, 44),\n",
+       "  (10, 51),\n",
+       "  (11, 6),\n",
+       "  (11, 52),\n",
+       "  (12, 4),\n",
+       "  (12, 5),\n",
+       "  (12, 8),\n",
+       "  (12, 25),\n",
+       "  (12, 32),\n",
+       "  (12, 42),\n",
+       "  (12, 47),\n",
+       "  (13, 21),\n",
+       "  (13, 25),\n",
+       "  (13, 36),\n",
+       "  (13, 40),\n",
+       "  (13, 55),\n",
+       "  (14, 12),\n",
+       "  (14, 18),\n",
+       "  (15, 20),\n",
+       "  (15, 32),\n",
+       "  (15, 46),\n",
+       "  (16, 18),\n",
+       "  (16, 22),\n",
+       "  (16, 34),\n",
+       "  (16, 36),\n",
+       "  (17, 7),\n",
+       "  (17, 21),\n",
+       "  (17, 22),\n",
+       "  (17, 40),\n",
+       "  (17, 47),\n",
+       "  (17, 53),\n",
+       "  (17, 54),\n",
+       "  (18, 22),\n",
+       "  (18, 32),\n",
+       "  (18, 33),\n",
+       "  (18, 44),\n",
+       "  (18, 46),\n",
+       "  (19, 1),\n",
+       "  (19, 5),\n",
+       "  (19, 12),\n",
+       "  (19, 20),\n",
+       "  (19, 48),\n",
+       "  (19, 55),\n",
+       "  (20, 3),\n",
+       "  (20, 18),\n",
+       "  (20, 26),\n",
+       "  (21, 0),\n",
+       "  (21, 8),\n",
+       "  (21, 26),\n",
+       "  (21, 45),\n",
+       "  (21, 49),\n",
+       "  (22, 18),\n",
+       "  (22, 20),\n",
+       "  (22, 45),\n",
+       "  (22, 55),\n",
+       "  (23, 5),\n",
+       "  (23, 8),\n",
+       "  (23, 16),\n",
+       "  (23, 32),\n",
+       "  (23, 33),\n",
+       "  (24, 22),\n",
+       "  (24, 40),\n",
+       "  (24, 45)],\n",
+       " 'p': [(0, 35),\n",
+       "  (0, 43),\n",
+       "  (0, 44),\n",
+       "  (3, 20),\n",
+       "  (3, 46),\n",
+       "  (4, 1),\n",
+       "  (4, 28),\n",
+       "  (5, 1),\n",
+       "  (5, 51),\n",
+       "  (6, 7),\n",
+       "  (6, 35),\n",
+       "  (6, 49),\n",
+       "  (7, 43),\n",
+       "  (8, 27),\n",
+       "  (10, 53),\n",
+       "  (11, 30),\n",
+       "  (14, 44),\n",
+       "  (15, 15),\n",
+       "  (15, 23),\n",
+       "  (15, 45),\n",
+       "  (17, 0),\n",
+       "  (17, 1),\n",
+       "  (18, 12),\n",
+       "  (18, 14),\n",
+       "  (18, 49),\n",
+       "  (18, 54),\n",
+       "  (21, 34),\n",
+       "  (22, 1),\n",
+       "  (22, 16),\n",
+       "  (22, 39),\n",
+       "  (22, 46),\n",
+       "  (24, 3),\n",
+       "  (24, 15),\n",
+       "  (24, 52)],\n",
+       " 's': [(0, 20),\n",
+       "  (0, 25),\n",
+       "  (1, 6),\n",
+       "  (1, 14),\n",
+       "  (1, 28),\n",
+       "  (1, 54),\n",
+       "  (2, 0),\n",
+       "  (2, 7),\n",
+       "  (2, 17),\n",
+       "  (2, 32),\n",
+       "  (2, 41),\n",
+       "  (2, 42),\n",
+       "  (3, 6),\n",
+       "  (3, 16),\n",
+       "  (3, 17),\n",
+       "  (3, 26),\n",
+       "  (3, 47),\n",
+       "  (3, 48),\n",
+       "  (4, 11),\n",
+       "  (4, 20),\n",
+       "  (5, 2),\n",
+       "  (5, 27),\n",
+       "  (5, 34),\n",
+       "  (5, 41),\n",
+       "  (6, 1),\n",
+       "  (6, 8),\n",
+       "  (7, 1),\n",
+       "  (7, 27),\n",
+       "  (7, 30),\n",
+       "  (7, 34),\n",
+       "  (7, 44),\n",
+       "  (7, 52),\n",
+       "  (7, 55),\n",
+       "  (8, 8),\n",
+       "  (8, 14),\n",
+       "  (8, 55),\n",
+       "  (9, 6),\n",
+       "  (9, 23),\n",
+       "  (9, 38),\n",
+       "  (9, 44),\n",
+       "  (9, 48),\n",
+       "  (9, 55),\n",
+       "  (10, 9),\n",
+       "  (11, 20),\n",
+       "  (11, 21),\n",
+       "  (11, 36),\n",
+       "  (12, 1),\n",
+       "  (12, 15),\n",
+       "  (12, 41),\n",
+       "  (12, 50),\n",
+       "  (13, 44),\n",
+       "  (13, 46),\n",
+       "  (13, 52),\n",
+       "  (14, 26),\n",
+       "  (14, 36),\n",
+       "  (15, 1),\n",
+       "  (15, 7),\n",
+       "  (15, 14),\n",
+       "  (15, 18),\n",
+       "  (15, 34),\n",
+       "  (15, 43),\n",
+       "  (16, 17),\n",
+       "  (16, 42),\n",
+       "  (18, 3),\n",
+       "  (18, 6),\n",
+       "  (18, 19),\n",
+       "  (18, 20),\n",
+       "  (18, 27),\n",
+       "  (18, 31),\n",
+       "  (19, 4),\n",
+       "  (19, 7),\n",
+       "  (19, 10),\n",
+       "  (19, 14),\n",
+       "  (19, 33),\n",
+       "  (19, 41),\n",
+       "  (19, 51),\n",
+       "  (20, 20),\n",
+       "  (21, 11),\n",
+       "  (22, 11),\n",
+       "  (22, 14),\n",
+       "  (22, 15),\n",
+       "  (22, 33),\n",
+       "  (22, 34),\n",
+       "  (22, 36),\n",
+       "  (24, 9),\n",
+       "  (24, 34),\n",
+       "  (24, 41),\n",
+       "  (24, 43)],\n",
+       " 'v': [(1, 36),\n",
+       "  (1, 48),\n",
+       "  (1, 55),\n",
+       "  (3, 8),\n",
+       "  (3, 21),\n",
+       "  (5, 43),\n",
+       "  (5, 46),\n",
+       "  (5, 49),\n",
+       "  (6, 10),\n",
+       "  (6, 47),\n",
+       "  (10, 17),\n",
+       "  (11, 46),\n",
+       "  (11, 55),\n",
+       "  (15, 10),\n",
+       "  (15, 36),\n",
+       "  (16, 21),\n",
+       "  (16, 51),\n",
+       "  (18, 15),\n",
+       "  (18, 18),\n",
+       "  (19, 6),\n",
+       "  (21, 23),\n",
+       "  (23, 25),\n",
+       "  (23, 31),\n",
+       "  (24, 32)]}"
+      ]
+     },
+     "execution_count": 26,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "letter_positions = {letter: [(r, c) for r, row in enumerate(rows) for c, char in enumerate(row) if char == letter] \n",
+    "                    for letter in deduplicate('phaseseven')}\n",
+    "letter_positions"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{0: 'a',\n",
+       " 1: 'z',\n",
+       " 2: 'y',\n",
+       " 3: 'x',\n",
+       " 4: 'v',\n",
+       " 5: 'u',\n",
+       " 6: 't',\n",
+       " 7: 's',\n",
+       " 8: 'r',\n",
+       " 9: 'q',\n",
+       " 10: 'p',\n",
+       " 11: 'o',\n",
+       " 12: 'n',\n",
+       " 13: 'm',\n",
+       " 14: 'l',\n",
+       " 15: 'k',\n",
+       " 16: 'j',\n",
+       " 17: 'i',\n",
+       " 18: 'h',\n",
+       " 19: 'g',\n",
+       " 20: 'f',\n",
+       " 21: 'e',\n",
+       " 22: 'd',\n",
+       " 23: 'c',\n",
+       " 24: 'b'}"
+      ]
+     },
+     "execution_count": 27,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "keycolumn = make_cadenus_keycolumn(reverse=True)\n",
+    "inverse_keycolumn = {v: l for l, v in keycolumn.items()}\n",
+    "inverse_keycolumn"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def valid_partial_solution(solution, inverse_keycolumn):\n",
+    "    row_indices = [p[0] for p in sorted(solution, key=lambda x: x[1])]\n",
+    "    row_letters = [inverse_keycolumn[i] for i in row_indices]\n",
+    "    letter_pairs = ngrams(row_letters, 2)\n",
+    "    return all(p[0] <= p[1] for p in letter_pairs)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "43005"
+      ]
+     },
+     "execution_count": 29,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "solutions = [[p] for p in letter_positions['p']]\n",
+    "for letter in 'ha': #'haseseven':\n",
+    "    new_solutions = []\n",
+    "    for solution in solutions:\n",
+    "        used_columns = [p[1] for p in solution]\n",
+    "        for position in letter_positions[letter]:\n",
+    "            if position[1] not in used_columns:\n",
+    "                if valid_partial_solution(solution + [position], inverse_keycolumn):\n",
+    "                    new_solutions += [solution + [position]]\n",
+    "    solutions = new_solutions\n",
+    "len(solutions)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "True"
+      ]
+     },
+     "execution_count": 30,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "valid_partial_solution(solutions[1], inverse_keycolumn)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['pha',\n",
+       " 'ruo',\n",
+       " 'oll',\n",
+       " 'rea',\n",
+       " 'laa',\n",
+       " 'tut',\n",
+       " 'pei',\n",
+       " 'ead',\n",
+       " 'nrt',\n",
+       " 'imi',\n",
+       " 'non',\n",
+       " 'eie',\n",
+       " 'aed',\n",
+       " 'mir',\n",
+       " 'inl',\n",
+       " 'lxi',\n",
+       " 'eah',\n",
+       " 'eai',\n",
+       " 'aps',\n",
+       " 'cnl',\n",
+       " 'ren',\n",
+       " 'ege',\n",
+       " 'yoo',\n",
+       " 'eau',\n",
+       " 'uep']"
+      ]
+     },
+     "execution_count": 31,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "display = []\n",
+    "for p in solutions[1]:\n",
+    "    this_column = columns[p[1]]\n",
+    "    rotated_column = this_column[p[0]:] + this_column[:p[0]]\n",
+    "    display += [rotated_column]\n",
+    "display_rows = [''.join(r) for r in zip(*display)]\n",
+    "display_rows"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def display_solution(solution, columns):\n",
+    "    display = []\n",
+    "    for p in solution:\n",
+    "        this_column = columns[p[1]]\n",
+    "        rotated_column = this_column[p[0]:] + this_column[:p[0]]\n",
+    "        display += [rotated_column]\n",
+    "    return [''.join(r) for r in zip(*display)]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['pha',\n",
+       " 'ruo',\n",
+       " 'ols',\n",
+       " 'rer',\n",
+       " 'lai',\n",
+       " 'tul',\n",
+       " 'pei',\n",
+       " 'eaa',\n",
+       " 'nro',\n",
+       " 'ime',\n",
+       " 'nod',\n",
+       " 'eid',\n",
+       " 'aea',\n",
+       " 'mii',\n",
+       " 'int',\n",
+       " 'lxi',\n",
+       " 'eah',\n",
+       " 'eap',\n",
+       " 'apk',\n",
+       " 'cnz',\n",
+       " 'rex',\n",
+       " 'egn',\n",
+       " 'yor',\n",
+       " 'eaa',\n",
+       " 'uea']"
+      ]
+     },
+     "execution_count": 33,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "display_solution(solutions[0], columns)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "-110.74748837196742"
+      ]
+     },
+     "execution_count": 34,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "sum(Ptrigrams(r) for r in display_rows)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def score_solution(solution, columns):\n",
+    "    display = []\n",
+    "    for p in solution:\n",
+    "        this_column = columns[p[1]]\n",
+    "        rotated_column = this_column[p[0]:] + this_column[:p[0]]\n",
+    "        display += [rotated_column]\n",
+    "    display_rows = [''.join(r) for r in zip(*display)]\n",
+    "    return sum(Ptrigrams(r) for r in display_rows)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 36,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[([(0, 35), (0, 12), (0, 0)],\n",
+       "  ['pha',\n",
+       "   'ruo',\n",
+       "   'ols',\n",
+       "   'rer',\n",
+       "   'lai',\n",
+       "   'tul',\n",
+       "   'pei',\n",
+       "   'eaa',\n",
+       "   'nro',\n",
+       "   'ime',\n",
+       "   'nod',\n",
+       "   'eid',\n",
+       "   'aea',\n",
+       "   'mii',\n",
+       "   'int',\n",
+       "   'lxi',\n",
+       "   'eah',\n",
+       "   'eap',\n",
+       "   'apk',\n",
+       "   'cnz',\n",
+       "   'rex',\n",
+       "   'egn',\n",
+       "   'yor',\n",
+       "   'eaa',\n",
+       "   'uea'],\n",
+       "  -114.13063154833905),\n",
+       " ([(0, 35), (0, 12), (0, 3)],\n",
+       "  ['pha',\n",
+       "   'ruo',\n",
+       "   'oll',\n",
+       "   'rea',\n",
+       "   'laa',\n",
+       "   'tut',\n",
+       "   'pei',\n",
+       "   'ead',\n",
+       "   'nrt',\n",
+       "   'imi',\n",
+       "   'non',\n",
+       "   'eie',\n",
+       "   'aed',\n",
+       "   'mir',\n",
+       "   'inl',\n",
+       "   'lxi',\n",
+       "   'eah',\n",
+       "   'eai',\n",
+       "   'aps',\n",
+       "   'cnl',\n",
+       "   'ren',\n",
+       "   'ege',\n",
+       "   'yoo',\n",
+       "   'eau',\n",
+       "   'uep'],\n",
+       "  -110.74748837196742),\n",
+       " ([(0, 35), (0, 12), (0, 9)],\n",
+       "  ['pha',\n",
+       "   'ruo',\n",
+       "   'old',\n",
+       "   'reo',\n",
+       "   'lan',\n",
+       "   'tur',\n",
+       "   'pee',\n",
+       "   'eae',\n",
+       "   'nro',\n",
+       "   'imc',\n",
+       "   'nos',\n",
+       "   'eir',\n",
+       "   'aee',\n",
+       "   'mim',\n",
+       "   'ini',\n",
+       "   'lxk',\n",
+       "   'ear',\n",
+       "   'eai',\n",
+       "   'api',\n",
+       "   'cno',\n",
+       "   'rei',\n",
+       "   'egh',\n",
+       "   'yof',\n",
+       "   'eat',\n",
+       "   'ues'],\n",
+       "  -104.78169431178242),\n",
+       " ([(0, 35), (0, 12), (0, 29)],\n",
+       "  ['pha',\n",
+       "   'rut',\n",
+       "   'olh',\n",
+       "   'rea',\n",
+       "   'lab',\n",
+       "   'tuo',\n",
+       "   'peo',\n",
+       "   'eat',\n",
+       "   'nrt',\n",
+       "   'imx',\n",
+       "   'noa',\n",
+       "   'eie',\n",
+       "   'aeh',\n",
+       "   'mii',\n",
+       "   'ine',\n",
+       "   'lxi',\n",
+       "   'eao',\n",
+       "   'ead',\n",
+       "   'api',\n",
+       "   'cne',\n",
+       "   'rec',\n",
+       "   'ega',\n",
+       "   'yol',\n",
+       "   'eal',\n",
+       "   'ueo'],\n",
+       "  -109.4716997212109),\n",
+       " ([(0, 35), (0, 12), (0, 41)],\n",
+       "  ['pha',\n",
+       "   'rur',\n",
+       "   'ols',\n",
+       "   'rey',\n",
+       "   'lal',\n",
+       "   'tus',\n",
+       "   'pen',\n",
+       "   'eac',\n",
+       "   'nrc',\n",
+       "   'ime',\n",
+       "   'nou',\n",
+       "   'eit',\n",
+       "   'aes',\n",
+       "   'mia',\n",
+       "   'int',\n",
+       "   'lxa',\n",
+       "   'eai',\n",
+       "   'eat',\n",
+       "   'apr',\n",
+       "   'cns',\n",
+       "   'ref',\n",
+       "   'egh',\n",
+       "   'yof',\n",
+       "   'eai',\n",
+       "   'ues'],\n",
+       "  -101.93339111217242),\n",
+       " ([(0, 35), (0, 12), (1, 44)],\n",
+       "  ['pha',\n",
+       "   'ruc',\n",
+       "   'olg',\n",
+       "   'ren',\n",
+       "   'laf',\n",
+       "   'tue',\n",
+       "   'pes',\n",
+       "   'eal',\n",
+       "   'nrs',\n",
+       "   'imn',\n",
+       "   'noi',\n",
+       "   'eie',\n",
+       "   'aes',\n",
+       "   'mip',\n",
+       "   'ind',\n",
+       "   'lxc',\n",
+       "   'eag',\n",
+       "   'ean',\n",
+       "   'aph',\n",
+       "   'cno',\n",
+       "   'ret',\n",
+       "   'egr',\n",
+       "   'yoe',\n",
+       "   'eai',\n",
+       "   'uep'],\n",
+       "  -108.4937247934099),\n",
+       " ([(0, 35), (0, 12), (1, 47)],\n",
+       "  ['pha',\n",
+       "   'rua',\n",
+       "   'ols',\n",
+       "   'rer',\n",
+       "   'lad',\n",
+       "   'tuv',\n",
+       "   'pee',\n",
+       "   'ean',\n",
+       "   'nrg',\n",
+       "   'imo',\n",
+       "   'noe',\n",
+       "   'ein',\n",
+       "   'aee',\n",
+       "   'mii',\n",
+       "   'inz',\n",
+       "   'lxr',\n",
+       "   'ean',\n",
+       "   'eai',\n",
+       "   'ape',\n",
+       "   'cnd',\n",
+       "   'rex',\n",
+       "   'egr',\n",
+       "   'yot',\n",
+       "   'eai',\n",
+       "   'ueg'],\n",
+       "  -111.05157201209927),\n",
+       " ([(0, 35), (0, 12), (2, 47)],\n",
+       "  ['pha',\n",
+       "   'rus',\n",
+       "   'olr',\n",
+       "   'red',\n",
+       "   'lav',\n",
+       "   'tue',\n",
+       "   'pen',\n",
+       "   'eag',\n",
+       "   'nro',\n",
+       "   'ime',\n",
+       "   'non',\n",
+       "   'eie',\n",
+       "   'aei',\n",
+       "   'miz',\n",
+       "   'inr',\n",
+       "   'lxn',\n",
+       "   'eai',\n",
+       "   'eae',\n",
+       "   'apd',\n",
+       "   'cnx',\n",
+       "   'rer',\n",
+       "   'egt',\n",
+       "   'yoi',\n",
+       "   'eag',\n",
+       "   'uea'],\n",
+       "  -113.41085773377256),\n",
+       " ([(0, 35), (0, 12), (3, 50)],\n",
+       "  ['pha',\n",
+       "   'rux',\n",
+       "   'olt',\n",
+       "   'rer',\n",
+       "   'lad',\n",
+       "   'tue',\n",
+       "   'peh',\n",
+       "   'ear',\n",
+       "   'nrc',\n",
+       "   'ims',\n",
+       "   'noc',\n",
+       "   'eie',\n",
+       "   'aec',\n",
+       "   'mil',\n",
+       "   'inr',\n",
+       "   'lxr',\n",
+       "   'ear',\n",
+       "   'eai',\n",
+       "   'api',\n",
+       "   'cne',\n",
+       "   'ree',\n",
+       "   'ego',\n",
+       "   'yoe',\n",
+       "   'ear',\n",
+       "   'uee'],\n",
+       "  -107.5080042911796),\n",
+       " ([(0, 35), (0, 12), (4, 38)],\n",
+       "  ['pha',\n",
+       "   'rue',\n",
+       "   'olk',\n",
+       "   'reh',\n",
+       "   'laa',\n",
+       "   'tus',\n",
+       "   'peb',\n",
+       "   'eaa',\n",
+       "   'nre',\n",
+       "   'imd',\n",
+       "   'nor',\n",
+       "   'eit',\n",
+       "   'aeu',\n",
+       "   'mio',\n",
+       "   'int',\n",
+       "   'lxo',\n",
+       "   'eah',\n",
+       "   'eau',\n",
+       "   'apf',\n",
+       "   'cni',\n",
+       "   'rez',\n",
+       "   'egg',\n",
+       "   'yoo',\n",
+       "   'ean',\n",
+       "   'uet'],\n",
+       "  -111.19702574254387)]"
+      ]
+     },
+     "execution_count": 36,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[(s, display_solution(s, columns), score_solution(s, columns)) for s in solutions[:10]]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 37,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[[(0, 35), (0, 12), (0, 41)],\n",
+       " [(0, 35), (0, 12), (0, 9)],\n",
+       " [(0, 35), (0, 12), (3, 50)],\n",
+       " [(0, 35), (0, 12), (1, 44)],\n",
+       " [(0, 35), (0, 12), (0, 29)],\n",
+       " [(0, 35), (0, 12), (0, 3)],\n",
+       " [(0, 35), (0, 12), (1, 47)],\n",
+       " [(0, 35), (0, 12), (4, 38)],\n",
+       " [(0, 35), (0, 12), (2, 47)],\n",
+       " [(0, 35), (0, 12), (0, 0)]]"
+      ]
+     },
+     "execution_count": 37,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "sorted(solutions[:10], key=lambda s: score_solution(s, columns), reverse=True)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 38,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "solutions = sorted(solutions, key=lambda s: score_solution(s, columns), reverse=True)[:10000]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 39,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# for letter in 'seseven': #'haseeight':\n",
+    "#     new_solutions = []\n",
+    "#     for solution in solutions:\n",
+    "#         used_columns = [p[1] for p in solution]\n",
+    "#         for position in letter_positions[letter]:\n",
+    "#             if position[1] not in used_columns:\n",
+    "#                 if valid_partial_solution(solution + [position], inverse_keycolumn):\n",
+    "#                     new_solutions += [solution + [position]]\n",
+    "#     solutions = sorted(new_solutions, key=lambda s: score_solution(s, columns), reverse=True)[:10000]\n",
+    "# len(solutions)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 40,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['pha',\n",
+       " 'reo',\n",
+       " 'oel',\n",
+       " 'rna',\n",
+       " 'lea',\n",
+       " 'tet',\n",
+       " 'pli',\n",
+       " 'ead',\n",
+       " 'nat',\n",
+       " 'ivi',\n",
+       " 'nin',\n",
+       " 'ele',\n",
+       " 'asd',\n",
+       " 'mar',\n",
+       " 'icl',\n",
+       " 'lai',\n",
+       " 'eeh',\n",
+       " 'efi',\n",
+       " 'ars',\n",
+       " 'cel',\n",
+       " 'ren',\n",
+       " 'ede',\n",
+       " 'yzo',\n",
+       " 'epu',\n",
+       " 'urp']"
+      ]
+     },
+     "execution_count": 40,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "display_solution(solutions[0], columns)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 41,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "849"
+      ]
+     },
+     "execution_count": 41,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "hinted_keywords = [w for w in keywords if w[0] =='f' if len(transpositions_of(w)) == 7]\n",
+    "len(hinted_keywords)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 42,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['fabrics',\n",
+       " 'facings',\n",
+       " 'faction',\n",
+       " 'factors',\n",
+       " 'factory',\n",
+       " 'faculty',\n",
+       " 'fadeout',\n",
+       " 'failure',\n",
+       " 'fainest',\n",
+       " 'fainted']"
+      ]
+     },
+     "execution_count": 42,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "hinted_keywords[:10]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 43,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "175"
+      ]
+     },
+     "execution_count": 43,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "first_chunk = c8bl[:175]\n",
+    "len(first_chunk)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 44,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['gatlrlnjtonethnirreh',\n",
+       " 'raorejnptreanhriaeso',\n",
+       " 'raohoanptraesrriasul',\n",
+       " 'raohhanptraemrriasln',\n",
+       " 'raorhaeptrnemsrianln',\n",
+       " 'raonlneptrnissriaaoc',\n",
+       " 'garhrarjtartsnnifphn',\n",
+       " 'raoaalapteesnfriunnr',\n",
+       " 'raonanhpterfrariutpn',\n",
+       " 'garehhrjteaaraniessp',\n",
+       " 'raonhalpterafnriutsp',\n",
+       " 'fainrleptorniseirtno',\n",
+       " 'raoaanhptemfrariunpn',\n",
+       " 'raloannptirsrhrioalt',\n",
+       " 'falmireptinonseiosrn',\n",
+       " 'ralhaanptiafmrriospn',\n",
+       " 'faeilenptnoisreirroo',\n",
+       " 'raeoeanptneafhrirusp',\n",
+       " 'earotktntvrugheivarj',\n",
+       " 'gaeorhojtarernnisaep',\n",
+       " 'gaeorhnjtarerhnisaep',\n",
+       " 'raeooaeptareesrisaun',\n",
+       " 'garnahrjtvenranivrep',\n",
+       " 'raalaenptmifsrrinopo',\n",
+       " 'faoeoepptnneareihrus',\n",
+       " 'falhonpptnaerreirsut',\n",
+       " 'fanroanpthiesreiaoul',\n",
+       " 'fanhonpptraerreinsut',\n",
+       " 'rahnaanptaofmrrisepn',\n",
+       " 'fahrrinptaitoreisohh',\n",
+       " 'rarrjaaptnensfrineon',\n",
+       " 'gaaohrmjtsrrnnninapn',\n",
+       " 'gaaarhrjtsenraninnnp',\n",
+       " 'gasrlhrjtntnraniehrp',\n",
+       " 'fasanomptnensneieean',\n",
+       " 'raalrempftinsnrpiono',\n",
+       " 'raaorejpftneanrpihes',\n",
+       " 'ghrrlanjratnthnpfhri',\n",
+       " 'gharnarjreaetvnpnfai',\n",
+       " 'frtroenppxthsredoheo',\n",
+       " 'frahoepppeaearednsus',\n",
+       " 'raeaoalpfnsntirprlhi',\n",
+       " 'raaiahnpfmotarrpnhis',\n",
+       " 'froiianppnoosredhhrl',\n",
+       " 'rahrinnpfaeeorrpsere',\n",
+       " 'rahaaiupfaeselrpsnlr',\n",
+       " 'raaerejpfsreanrpnpes',\n",
+       " 'graeohnjetarrhneisap',\n",
+       " 'fitahanpoimesrerenln',\n",
+       " 'grtaaahjeosntrnernei',\n",
+       " 'rotaaanpeosetrrurnni',\n",
+       " 'roieaaopeeanfnrureep',\n",
+       " 'rrejahnpernfarrepops',\n",
+       " 'rrejarepernfnsrepopn',\n",
+       " 'fopalrnpertntheuiirh',\n",
+       " 'frpnhrlperoapneeiesd',\n",
+       " 'foperehpernpaaeuirds',\n",
+       " 'fopalaapersnteeuinri',\n",
+       " 'rrjalaepensnfrreonrp',\n",
+       " 'fopaarnpersmpreuinnd',\n",
+       " 'roatalhpeeifnarunepr',\n",
+       " 'gtfiehrjuterranrrrep',\n",
+       " 'rrainanpeneofhreerep',\n",
+       " 'filhranpoiapmrerosdn',\n",
+       " 'rrrajaapevtnnfrevioe',\n",
+       " 'roeaaanpeatefhrusinp',\n",
+       " 'rreinanpeaeofhresrep',\n",
+       " 'ronealnperrfnhrutppr',\n",
+       " 'fioraenpohpmsreredno',\n",
+       " 'fonprlnperrpnheutidr',\n",
+       " 'finlrenporipsrertodo',\n",
+       " 'rrlatajpenfisnrerpen',\n",
+       " 'rooaeaepenfntaruhpri',\n",
+       " 'fiairnhpomopraernhdn',\n",
+       " 'pfomrteddsnnxstcnsno',\n",
+       " 'rrninalpeheofnrearep',\n",
+       " 'fonrraeperipmseunodn',\n",
+       " 'fonrnrhperirpaeunotd',\n",
+       " 'pfnsoaiddsoseetccrne',\n",
+       " 'grnatahjeetonrnesire',\n",
+       " 'grnarhrjeetnranesinp',\n",
+       " 'ronarampeetnfnrusinp',\n",
+       " 'roaaeaepeifresrueppn',\n",
+       " 'finnnorpoesnsperscan',\n",
+       " 'rosaanmpeoftnnrurpia',\n",
+       " 'flapannpitrsrheoiilt',\n",
+       " 'raaeoaopntaefnreieup',\n",
+       " 'faaeorppntaevreeieuv',\n",
+       " 'eaattktnntrogheeivrj',\n",
+       " 'gaanthnjeteorhnniarp',\n",
+       " 'rlaealnpitnfnhroirpr',\n",
+       " 'faanorppeteevreniauv',\n",
+       " 'raaejanpetanfhrnisop',\n",
+       " 'gaarehrjntvaraneivep',\n",
+       " 'raaeuaopetalfnrnisip',\n",
+       " 'faaooeppetnearenihus',\n",
+       " 'gaanehrjnthrraneiaep',\n",
+       " 'raannalpethofnrniaep',\n",
+       " 'eaahtktnntaogheeisrj',\n",
+       " 'ftaaormpxtshnneoinen',\n",
+       " 'ftashanpxtnemreoieln',\n",
+       " 'ftashnapxtnenmeoiela',\n",
+       " 'faasoeppetnearenieus',\n",
+       " 'faaeoeppetsearenious',\n",
+       " 'farnorppepeevrendauv',\n",
+       " 'farnonrpepeehiendaua',\n",
+       " 'farnoeppepeearendsus',\n",
+       " 'gfrirhrjteearanrernp',\n",
+       " 'raoieaopneeafnreurep',\n",
+       " 'paoprhndeeeiartnufos',\n",
+       " 'paoprredeeeinstnufon',\n",
+       " 'faoeirnpeeaeihenusro',\n",
+       " 'raolhaepeenafrrnursp',\n",
+       " 'gaaahhrjestarannlisp',\n",
+       " 'rlrahalpittafnrohisp',\n",
+       " 'gaviehrjnvearaneorep',\n",
+       " 'raaoorapesneatrnlhuf',\n",
+       " 'flaoinrpisnorpeolhrt',\n",
+       " 'ptrlfondxtndhhtohrce',\n",
+       " 'pthafnhdxemdratolncn',\n",
+       " 'ftrhnaipxtartoeohsni',\n",
+       " 'rlaaniapissrefrolntr',\n",
+       " 'rlralaepitsnfrrohnrp',\n",
+       " 'rlraraepitsnfrrohnnp',\n",
+       " 'fthsranpxenpmreoledn',\n",
+       " 'fthnraepxeapmseolidn',\n",
+       " 'plasinpdisnoretolert',\n",
+       " 'rlnaniepinfresroaptr',\n",
+       " 'faauirlpeslopnennird',\n",
+       " 'raaeuaepesalfrrnnsip',\n",
+       " 'flnnrrepinrtpseoatxd',\n",
+       " 'faaeuirpesalopennsir',\n",
+       " 'ptnocemdxnhesntoaeto',\n",
+       " 'raannaepesrofrrnnnep',\n",
+       " 'flanrrapisripmeonnod',\n",
+       " 'ftamrropxsnnpseonsnd',\n",
+       " 'plarinpdisnoretonnrt',\n",
+       " 'plnninpdineoretoasrt',\n",
+       " 'pleinpndisorertoortf',\n",
+       " 'ftehnrapxseapmeoolid',\n",
+       " 'fvaaoeppvteeareoinus',\n",
+       " 'raaeoaopstnefnrlirup',\n",
+       " 'fvaeoeppvtneareoirus',\n",
+       " 'grianhrjtesrranhrnnp',\n",
+       " 'fhpaarepertmnseliinn',\n",
+       " 'raotaanpseiefhrluenp',\n",
+       " 'rronhaepterafrrhunsp',\n",
+       " 'rrlealnptirfnhrhoppr',\n",
+       " 'fvaeoeppvereareonpus',\n",
+       " 'frlprlnptirpnhehoidr',\n",
+       " 'rvarajapvnetnfroeeio',\n",
+       " 'raaoahapseetafrlnuis',\n",
+       " 'frxrohnptopharehades',\n",
+       " 'rroeanhpthrfrarheppn',\n",
+       " 'ranelanpsrrifhrltpop',\n",
+       " 'rroeaanpthrsfrrhepnp',\n",
+       " 'gaoanhrjsnteranlhirp',\n",
+       " 'rrlajanptntnfhrhriop',\n",
+       " 'grlaehrjtntsranhriop',\n",
+       " 'eaotatknsnothgelhrir',\n",
+       " 'rrltornptnieahrhreuf',\n",
+       " 'rhliatnpenefhhrlrrpa',\n",
+       " 'faoionppsneerrelhrut',\n",
+       " 'raornaepsnaotnrlhfei',\n",
+       " 'faoeonppsnrerrelhput',\n",
+       " 'faoropnpsnperrelhdui',\n",
+       " 'raoaianpsnfotrrlhphi',\n",
+       " 'rhaanaspemfrtnrlnpni',\n",
+       " 'rrljasaptnntnfrhroie',\n",
+       " 'fhaprhnpemrparelnids',\n",
+       " 'frlposrptnrenpehriue',\n",
+       " 'paouinpdsnloretlhirt',\n",
+       " 'frliatnptnotxhehrhio',\n",
+       " 'frlxaohptnothaehraie',\n",
+       " 'rrliahaptnotafrhrhis',\n",
+       " 'fhaxahnpemotarelnais',\n",
+       " 'raoeooapsnnertrlhrua',\n",
+       " 'paoiinpdsnooretlhhrt',\n",
+       " 'frliataptnosxtehrhno',\n",
+       " 'rrlnauaptnhtlfrhraii',\n",
+       " 'fhahirnpemaoprelnsrd',\n",
+       " 'fharaorpemnsapelnnne',\n",
+       " 'fhasrorpemnpanelnede',\n",
+       " 'fhatrmrpesxpnnelnods',\n",
+       " 'paalinpdssioretlnort',\n",
+       " 'rraoealptshrfnrhnepp',\n",
+       " 'fhnoeaepenarmselaepn',\n",
+       " 'paaoremdessnfntennnd',\n",
+       " 'paslinpdsnioretleort',\n",
+       " 'fhnirmrpeeopnnelsrds',\n",
+       " 'frnrailptentoiehsnir',\n",
+       " 'roajraapntnenfrhioee',\n",
+       " 'faailrepmtoinseniron',\n",
+       " 'foaeoeppntnearehirus',\n",
+       " 'glanohnjntrrrhnritap',\n",
+       " 'rlanoonpntrrehrritau',\n",
+       " 'goaeehrjntaaranhisep',\n",
+       " 'roaeuaapntalferhisip',\n",
+       " 'roaeeoapntaaefrhiseu',\n",
+       " 'flanrlepntrtiseritxo',\n",
+       " 'rlanhoopntraerrritsu',\n",
+       " 'faaapnrpmtsroneninie',\n",
+       " 'flaeonppntserreriout',\n",
+       " 'glhrranjnreathnrpefi',\n",
+       " 'flrrpnhpnperoaerdeie',\n",
+       " 'flrxrohpnpothaerdahe',\n",
+       " 'rlaninnpnfreohrrptre',\n",
+       " 'forosimpspaoenenderu',\n",
+       " 'farnrlepmpriisendnoo',\n",
+       " 'goratahjnetonrnheire',\n",
+       " 'raoraenpmeatsrrnufio',\n",
+       " 'rlrejanpnernfhrrepop',\n",
+       " 'gorhraejneratanhepfi',\n",
+       " 'glrhranjnerathnrepfi',\n",
+       " 'rloanenpnefrrhrruptp',\n",
+       " 'rlrjahapnentafrreois',\n",
+       " 'paoprhndmeeiartnufos',\n",
+       " 'rorejaepneanfrrhesop',\n",
+       " 'flonprnpnerrpherutid',\n",
+       " 'rloneaepnehafrrruaep',\n",
+       " 'foapianpnsrotrehlihi',\n",
+       " 'foapirnpnsroprehlihd',\n",
+       " 'flrliinpntioeherhorr',\n",
+       " 'flrohatpnthatxerhesi',\n",
+       " 'rlrohaepnthafrrrhesp',\n",
+       " 'rahnhaepmerafrrnlnsp',\n",
+       " 'rlrhnaepntaofrrrhsep',\n",
+       " 'rlrsoaepntnhfrrrheep',\n",
+       " 'raaoraepmsenfrrnnunp',\n",
+       " 'raonnrapsroretrnaene',\n",
+       " 'raiuaanpselfmrrnripn',\n",
+       " 'faieoeppseaearenreus',\n",
+       " 'faraoeppspeearendnus',\n",
+       " 'falaninpsitrorenoitr',\n",
+       " 'fatnrirpsxrtopenonhh',\n",
+       " 'paerhomdstneantnvnle',\n",
+       " 'gantahrjseierannaenp',\n",
+       " 'raetlalpsniifnrnreop',\n",
+       " 'raetlanpsniifrrnreop',\n",
+       " 'faoirhapsaenemenernl',\n",
+       " 'raoeaanpshrfmrrneppn',\n",
+       " 'ranalalpsrfntirntpri',\n",
+       " 'fanpaoepsrrserentilu',\n",
+       " 'fanuirlpsrlopnentird',\n",
+       " 'faatonrpsmierienneun',\n",
+       " 'pallinpdsnioretnrort',\n",
+       " 'paltropdsnxthetnrohe',\n",
+       " 'galnaohjsnrtrrnnrtia',\n",
+       " 'paaoinedsmhorftnnern',\n",
+       " 'fnonisrpnssonpeancre',\n",
+       " 'ranotaapsreiefrnnuen',\n",
+       " 'famriaopsnnothensnri',\n",
+       " 'famriropsnnopsensnrd',\n",
+       " 'pnnsiopdnsoohetacrre',\n",
+       " 'ratalrnptositnrirnoh',\n",
+       " 'ealktvanttgovseihjro',\n",
+       " 'gaoharajtrrnelniapee',\n",
+       " 'gaorahfjtrenrtniaeep',\n",
+       " 'raooathptreeuariaunr',\n",
+       " 'raorrhtptrntanrianhs',\n",
+       " 'faoatolpteeuaeeiunre',\n",
+       " 'failnraptoirtleironh',\n",
+       " 'raonhanpterafrriutsp',\n",
+       " 'rarojaaptennsfriehol',\n",
+       " 'raolnanptenrfhriurtp',\n",
+       " 'failthoptonheneirral',\n",
+       " 'faionoiptosarneirnis',\n",
+       " 'faorrasptenilceiunoe',\n",
+       " 'fatlvnnptxivnseioooa',\n",
+       " 'gaaavlajtenvcfnineoe',\n",
+       " 'ralnahnptirfasrionps',\n",
+       " 'falmireptinonseiosrn',\n",
+       " 'gaahhlajtearnfninspr',\n",
+       " 'ranoafrpteeedariaunc',\n",
+       " 'ranrnnapteehofriaeae',\n",
+       " 'ranonfcptrrtdhritsnc',\n",
+       " 'raeooasptarelcrisaue',\n",
+       " 'raeoeroptarsehrisaoe',\n",
+       " 'raoenuvptnnohurihrec',\n",
+       " 'raoeluvptnnihurihroc',\n",
+       " 'galavlajtnmvcfnirnoe',\n",
+       " 'raahnanptmaofrrinsep',\n",
+       " 'ganorctjthrehxniaaeo',\n",
+       " 'fanroanpthiesreiaoul',\n",
+       " 'ganhhnajtrarrfninspt',\n",
+       " 'ranhaozptrafherinspe',\n",
+       " 'fahattmptacxuneiseor',\n",
+       " 'gahehfhjtarrtonisepo',\n",
+       " 'gahehlajtarrnfnisepr',\n",
+       " 'fanlnifptnisoteiaocr',\n",
+       " 'faamriaptsnnoceinsnr',\n",
+       " 'raalnripftnhtorpirah',\n",
+       " 'ghanrtajrtheonnpiaer',\n",
+       " 'raahnzlpftaoenrpisen',\n",
+       " 'raarnzopftnoenrpinen',\n",
+       " 'gharaaajrtnsmfnpinnn',\n",
+       " 'raaraozpftnsserpinnn',\n",
+       " 'ghtanaojromntnnprnai',\n",
+       " 'ghrosefjraozttnpfgdt',\n",
+       " 'ghrraocjraamdhnpflns',\n",
+       " 'ozkrtcsgegaiatfnjfel',\n",
+       " 'ekhrtulngraiheejpfec',\n",
+       " 'rarstolpfpzuherpdere',\n",
+       " 'frzltolppeiuaeednore',\n",
+       " 'ghaatoojrnfsdrnpepzs',\n",
+       " 'gharooojrnerdrnpeeas',\n",
+       " 'raaoithpfeeeuarpnurr',\n",
+       " 'raafontpfesrturpnrsn',\n",
+       " 'frlanirppisroaedoltr',\n",
+       " 'friintnppooruhedhrtr',\n",
+       " 'raeirolpfaeeherpsree',\n",
+       " 'fraxkrrppmogvnednajv',\n",
+       " 'ghonavhjrnrtuonphtir',\n",
+       " 'frloiroppnnaeaedrhae',\n",
+       " 'raankrspfmaghtrpnije',\n",
+       " 'frosanappsnenmedneea',\n",
+       " 'rahrinopfaeeoorpsere',\n",
+       " 'frszoteppnesugedennr',\n",
+       " 'raeniaepfsrotarpothi',\n",
+       " 'granoahjethrsrneiaal',\n",
+       " 'fiihrhepoeaeeaerrsel',\n",
+       " 'roeseooperztonrupevg',\n",
+       " 'roeaathperfeuaruppnr',\n",
+       " 'grtaooujehsrdhnernas',\n",
+       " 'roaaeoopeferonrupnpg',\n",
+       " 'rraaesopefnrmhrepepn',\n",
+       " 'rraeesspefarmnrepspn',\n",
+       " 'roalizfpefneetruprrn',\n",
+       " 'roaaionpefmeohrupnrg',\n",
+       " 'fopalrrpersneheuinre',\n",
+       " 'frainsopeneomaeeeren',\n",
+       " 'roaaranpeefvterunpvi',\n",
+       " 'filanvspoieevzeronao',\n",
+       " 'fileoonpoindoherorsg',\n",
+       " 'roatsecpenrrteruevht',\n",
+       " 'roahalrpeeafnprunspr',\n",
+       " 'foahroopeeaidoeunsos',\n",
+       " 'roahlaipeeanthrunsri',\n",
+       " 'roeaasapeatemirusinn',\n",
+       " 'finaltnportiuhertior',\n",
+       " 'finalthportiuaertior',\n",
+       " 'roeaasxpeatemfrusinn',\n",
+       " 'etravehnuvtuhrervirk',\n",
+       " 'greavlrjeatutanesirh',\n",
+       " 'rrejaorpeanfnpresoph',\n",
+       " 'rresserpeamnfpresntd',\n",
+       " 'fonsetopermgooeutnhd',\n",
+       " 'fiotdeopohuotnererot',\n",
+       " 'fintdkfporuogtertroj',\n",
+       " 'roeaavtpeaeturrusnir',\n",
+       " 'rolaaatpenftmrrurpin',\n",
+       " 'grohtaajenrotnnehpri',\n",
+       " 'rooataepenfisnruhpel',\n",
+       " 'fiargfipompjteerndnr',\n",
+       " 'fiargvapompjvierndno',\n",
+       " 'rolahsepenfaztrurpsd',\n",
+       " 'rolasaapenfnterurpei',\n",
+       " 'rolasrhpenfnterurpeh',\n",
+       " 'filrsroponpntserrdeh',\n",
+       " 'filinrnponorpherrhtd',\n",
+       " 'rolesatpennntarurrei',\n",
+       " 'ronoaafperrtetrunain',\n",
+       " 'fonrraeperipmseunodn',\n",
+       " 'fonrnrhperirpaeunotd',\n",
+       " 'fonrharperiateeunosi',\n",
+       " 'ronnstrperhcaprunaei',\n",
+       " 'rosaorfpenfgtsruepfh',\n",
+       " 'fonarropeetneaeusine',\n",
+       " 'finarrhpoetneeersine',\n",
+       " 'ronantipeetsuirusicr',\n",
+       " 'gaattirjntotoaneirsr',\n",
+       " 'raajvaepetnostrniool',\n",
+       " 'flaplerpitrntveoiirt',\n",
+       " 'faareoopntvaeaeeiveu',\n",
+       " 'raaveftpntoutsreiolo',\n",
+       " 'rlatroopithionroiatg',\n",
+       " 'faavetopetoluaenioor',\n",
+       " 'raannalpethofnrniaep',\n",
+       " 'raannanpetrofhrninep',\n",
+       " 'faanrofpetrieteninou',\n",
+       " 'rlahoelpitartnroisat',\n",
+       " 'faahgtepetajugenisnr',\n",
+       " 'gaahehfjntarrtneisep',\n",
+       " 'rlahnanpitarfrroistp',\n",
+       " 'rlahizepitahearoisin',\n",
+       " 'rlahizlpitahenroisin',\n",
+       " 'rlarizopitnhenroinin',\n",
+       " 'faahntopetatuaenisnr',\n",
+       " 'ftahnrspxtattleoisnh',\n",
+       " 'rlarsetpitnntaroinet',\n",
+       " 'flaarimpitsnoneoinnr',\n",
+       " 'gaannhajeterrfnnisnp',\n",
+       " 'raartsopnfpsmhrepdzn',\n",
+       " 'farrntopepatuaendlnr',\n",
+       " 'farnonrpepeehiendaua',\n",
+       " 'farnroopephieoendaou',\n",
+       " 'raahinopefaeoornpsre',\n",
+       " 'raaaotfpefieitrnpeue',\n",
+       " 'flrnriepipenoneodsnr',\n",
+       " 'rlannaapifenmtropsan',\n",
+       " 'faoiesopneeamaeeuren',\n",
+       " 'flienoopionhdoeorras',\n",
+       " 'flinhoopioradoeortss',\n",
+       " 'fliseerpiolstveorlst',\n",
+       " 'fliteoopiohsoneorasg',\n",
+       " 'fliteonpiohsoheorasg',\n",
+       " 'plilhrvdionaeutorrse',\n",
+       " 'favhhtopevekuaenosgr',\n",
+       " 'plavdrvdisveeutologe',\n",
+       " 'flrvtoopitvcdoeohoas',\n",
+       " 'flrseorpitledaeohlds',\n",
+       " 'flrseorpitledaeohlds',\n",
+       " 'plavervdisoeeutolode',\n",
+       " 'rlaoanipisnfrerolhpt',\n",
+       " 'flrliefpitnorteohrrp',\n",
+       " 'pthafnhdxemdratolncn',\n",
+       " 'planervdishgeutolahe',\n",
+       " 'ftrhnaipxtartoeohsni',\n",
+       " 'rlrsalrpitnfnprohepr',\n",
+       " 'faatctopesieuaennehr',\n",
+       " 'ftnronfpxnphsteoadec',\n",
+       " 'flnierhpinoreaeoarpe',\n",
+       " 'paaeuivdesaloutnnsir',\n",
+       " 'raalofrpesnsdprnnrnc',\n",
+       " 'flaadoopismedoeonngs',\n",
+       " 'flamrrnpisnipreonsod',\n",
+       " 'ftamrropxsnnpseonsnd',\n",
+       " 'ftardkapxsnogmeonnoj',\n",
+       " 'ftnndkopxnsogneoacoj',\n",
+       " 'rletaropishtiorooait',\n",
+       " 'flemrropisnipoeoosod',\n",
+       " 'grianeajtesrgfnhrnnh',\n",
+       " 'rajtvsvpsnivcurloeoe',\n",
+       " 'frpjoonptrndohehiosg',\n",
+       " 'prpraordteissvthfoln',\n",
+       " 'prinhovdtoraeuthrnsu',\n",
+       " 'rrlranoptiatarrhofii',\n",
+       " 'palrnrvdsithtutloxah',\n",
+       " 'raianhrpsofraprlhpts',\n",
+       " 'rrorarrpthatvnrhefiv',\n",
+       " 'fveeaoopvareeaeospnu',\n",
+       " 'ranhaovpsrateurltsiu',\n",
+       " 'fhafzoipeeseneelernh',\n",
+       " 'rrhfaiuptetiehrhlrhr',\n",
+       " 'rrvdapoptvoceorhooef',\n",
+       " 'prvgovgdtvheuftholur',\n",
+       " 'frvgsaeptvhrcaeholhe',\n",
+       " 'rhahirepesaiptrllsed',\n",
+       " 'rrlajaoptntnfnrhriop',\n",
+       " 'faoaponpsntrerelhiiu',\n",
+       " 'grlthaojtnortnnhrrpi',\n",
+       " 'rrliaatptneflnrhrrpe',\n",
+       " 'rhliatnpenefhhrlrrpa',\n",
+       " 'rrlaaotptnftsrrhrpin',\n",
+       " 'gaoherfjsnrrptnlhped',\n",
+       " 'frlrlhlptnpireehrdop',\n",
+       " 'raoaahepsnfeehrlhpns',\n",
+       " 'fharxanpemposhelndal',\n",
+       " 'raoanaipsnfrtorlhpti',\n",
+       " 'rhaanhrpemfraprlnpns',\n",
+       " 'faormropespnnneendsn',\n",
+       " 'rrlahhfptnfaesrhrpsl',\n",
+       " 'rrlasaoptnfntsrhrpei',\n",
+       " 'fharshepempnraelndep',\n",
+       " 'fhaphsrpemdrmnelntpn',\n",
+       " 'fhaproipemrpneelnidh',\n",
+       " 'prlrlfadtntidlthrxoc',\n",
+       " 'frliatfptnotxtehrhio',\n",
+       " 'frlirdfptnopetehrhdg',\n",
+       " 'frlitrnptnoxphehrhod',\n",
+       " 'frlxvzaptnovdcehraoo',\n",
+       " 'rrlnauaptnhtlfrhraii',\n",
+       " 'rhansaapemrnftrlnnep',\n",
+       " 'frlhorgptnaephehrsud',\n",
+       " 'fhahscepemazaaelnsdl',\n",
+       " 'rhasathpemntaorlneii',\n",
+       " 'rhnhaarperafmprlnspn',\n",
+       " 'rraoataptsrtnnrhnair',\n",
+       " 'fratornptsxhprehnoed',\n",
+       " 'faaneoopssrreaelntpu',\n",
+       " 'fraoraiptshntoehneni',\n",
+       " 'fhaanaspesmrerelnnne',\n",
+       " 'fhaarrhpesmnprelnnnd',\n",
+       " 'frnplaopterissehsiol',\n",
+       " 'frnrhfopteiesoehsolr',\n",
+       " 'frnratrpteisnhehsolr',\n",
+       " 'raaohaapmtracnrniase',\n",
+       " 'gaaoradjmtrnsenniann',\n",
+       " 'goaeorojntareanhisae',\n",
+       " 'foaeeoopntaaeaehiseu',\n",
+       " 'foaeuaipntaleoehisin',\n",
+       " 'raasoalpmtoefnrnirup',\n",
+       " 'glasntajntoexfnrirto',\n",
+       " 'raasaeopmtoatornircv',\n",
+       " 'gohieaajnreanfnhpree',\n",
+       " 'rlaiuarpnfelearrprin',\n",
+       " 'gohraocjnramdhnhpfns',\n",
+       " 'glhraosjnramdtnrpfns',\n",
+       " 'gohassujnrfzrhnhppeh',\n",
+       " 'rlarshtpnfpzerrrpdel',\n",
+       " 'gohztuvjnreohunhpndc',\n",
+       " 'roakfrfpnfgttsrhpjuh',\n",
+       " 'flrkrolpnpgeaeerdjee',\n",
+       " 'gohzahfjnrenetnhpnes',\n",
+       " 'rlakserpnfgrtvrrpjht',\n",
+       " 'faronvlpmpotvcendgno',\n",
+       " 'roaoooipsfosrnrnpgns',\n",
+       " 'flrraropnpaaeaerdlce',\n",
+       " 'rlaninrpnfreoarrptre',\n",
+       " 'rlanrnopnfratdrrptln',\n",
+       " 'rlansorpnfroeprrptru',\n",
+       " 'farosiopmphoooenderr',\n",
+       " 'farlahepmposraendsnp',\n",
+       " 'flrnrizpnphioeerdaoh',\n",
+       " 'flrhnropnpateaerdsne',\n",
+       " 'farrshdpmpnneeendnel',\n",
+       " 'fliihrhpnoeaeeerrrse',\n",
+       " 'floposfpnerdzteruise',\n",
+       " 'pafnrofdmdrtettncnxu',\n",
+       " 'plinurvdnohleutrraie',\n",
+       " 'rlosnerpneoetprrurtv',\n",
+       " 'faisafopmooasoenrrcr',\n",
+       " 'flrohirpnthaoperhesr',\n",
+       " 'plrohivdnthaoutrhesr',\n",
+       " 'fahnhtipmeraioenlnse',\n",
+       " 'fahnhirpmeraopenlnsr',\n",
+       " 'flrhrorpntaieperhsou',\n",
+       " 'plrsoivdntnhoutrheer',\n",
+       " 'fahsnirpmenropenlenr',\n",
+       " 'fahnsirpmeaoopenlirr',\n",
+       " 'foniniapsnesolenarcr',\n",
+       " 'fanpalfpmnrtitenaiio',\n",
+       " 'paairovdmsoneutnnrnu',\n",
+       " 'paafroadmsdneetnncnu',\n",
+       " 'flaitirpnsohopernhar',\n",
+       " 'raonnrapsroretrnaene',\n",
+       " 'faesltopsrziuaenpeor',\n",
+       " 'faraltopspeiuaendnor',\n",
+       " 'fnponsopnresmseaiucn',\n",
+       " 'fneisaapnuontmealrei',\n",
+       " 'fatiatnpsxemneenornr',\n",
+       " 'gaaetctjsntiasnnevel',\n",
+       " 'faoirirpshenotenernr',\n",
+       " 'faneoogpsrreafentpue',\n",
+       " 'ranalrapsrfnpcrntprd',\n",
+       " 'faoooznpshadereneesn',\n",
+       " 'pallrhpdsnitirtnrohi',\n",
+       " 'faodoznpssederenngsn',\n",
+       " 'rnaovirpnmsviprannoe',\n",
+       " 'faorrrapssnipmennnod',\n",
+       " 'faorrrmpssnipnennnod',\n",
+       " 'ranaaajpsrfetnrnnpni',\n",
+       " 'panfgrddsrdjtetnncnh',\n",
+       " 'famriaopsnnothensnri',\n",
+       " 'fnnilrfpnsoipteacrod',\n",
+       " 'fnstokmpnocdgnearasj',\n",
+       " 'gaohsaojtrrlerniapln',\n",
+       " 'raonnafptrsnctriacae',\n",
+       " 'raonhvopterauoriutsr',\n",
+       " 'garortajtenpufniehrr',\n",
+       " 'raolnanptenrfhriurtp',\n",
+       " 'raauafrptelntvrinieo',\n",
+       " 'gaaeelsjtntttmnievth',\n",
+       " 'falaverptinveeeioeod',\n",
+       " 'ralnahnptirfasrionps',\n",
+       " 'gaanrrfjtnhepdnieaer',\n",
+       " 'raanohfptereadrinnus',\n",
+       " 'faeiltoptnoiureirror',\n",
+       " 'raeonftptartdsrissnc',\n",
+       " 'gaeororjtareaanisaee',\n",
+       " 'ranhusfptrahndritsct',\n",
+       " 'ranhusfptrahndritsct',\n",
+       " 'ranhusiptrahnhritsct',\n",
+       " 'raaaskaptmfngnrinpej',\n",
+       " 'raaieflptmostnrinhoo',\n",
+       " 'ranhaozptrafherinspe',\n",
+       " 'fahattmptacxuneiseor',\n",
+       " 'faratsnptncxmseineon',\n",
+       " 'ranaotfptsfgntricpfr',\n",
+       " 'faroparptnerseeinuin',\n",
+       " 'rahiknoptahgrorisijt',\n",
+       " 'rahionoptahorerisigt',\n",
+       " 'raalrezptsinterinonv',\n",
+       " 'raaaotfpftmgntrpinfr',\n",
+       " 'ghaheotjrtaroanpiseg',\n",
+       " 'ghrosefjraozttnpfgdt',\n",
+       " 'ghrzsorjraezrnnpfnds',\n",
+       " 'frzltolppeiuaeednore',\n",
+       " 'friintnppooruhedhrtr',\n",
+       " 'frnaplkpprsrngedtnir',\n",
+       " 'ghorreajrnaeatnphfes',\n",
+       " 'ralizrdpfnoevorprhnv',\n",
+       " 'ghlnavtjrnrturnprtir',\n",
+       " 'frloknippnngsoedrhjc',\n",
+       " 'frarilrppmnoiaednnro',\n",
+       " 'frahiltppmaoiuednsro',\n",
+       " 'frarilsppmnoimednnro',\n",
+       " 'frarilsppmnoimednnro',\n",
+       " 'frsninsppnsoamedtcri',\n",
+       " 'ranhrhrpfratehrpnshl',\n",
+       " 'frhonrrppaerieedsuno',\n",
+       " 'frhrkaippangmoedsnjn',\n",
+       " 'grtvealjeovattnerosi',\n",
+       " 'rrejahtpernfaurepops',\n",
+       " 'poprhredeeiaeatufose',\n",
+       " 'pipaaoedoesmeatrfnnu',\n",
+       " 'rraoltrpeneeapreeusi',\n",
+       " 'foaigsrpeeofzaeunrtd',\n",
+       " 'pftterrddxulevtcoroe',\n",
+       " 'foafrripeesanoeunrln',\n",
+       " 'foahroopeeaidoeunsos',\n",
+       " 'roeaasapeatemirusinn',\n",
+       " 'finaltnportiuhertior',\n",
+       " 'greavlsjeatutmnesirh',\n",
+       " 'roeotcspeadsemrusszt',\n",
+       " 'fonsetopermgooeutnhd',\n",
+       " 'rrevkdopeaugtrresrjo',\n",
+       " 'grohtsojenrozonehprd',\n",
+       " 'frlrrolpenppeeeerdru',\n",
+       " 'filrthsponphenerrdal',\n",
+       " 'roaasarpemfntnrunpei',\n",
+       " 'filinrnponorpherrhtd',\n",
+       " 'fonrharperiateeunosi',\n",
+       " 'fomrstopeninuseusoer',\n",
+       " 'pirnfoldonsdhetrncce',\n",
+       " 'ronaenopeefrrorusppt',\n",
+       " 'raajafapetnftnrniopr',\n",
+       " 'raajaafpetnfstrniopl',\n",
+       " 'raanntapetroosrniner',\n",
+       " 'rlahtrupitaothroisrh',\n",
+       " 'faahgtepetajugenisnr',\n",
+       " 'rlahnanpitarfrroistp',\n",
+       " 'gaahgovjetahounnislg',\n",
+       " 'gaahgotjetahoannislg',\n",
+       " 'rlaraezpitnsteroinnv',\n",
+       " 'flaarimpitsnoneoinnr',\n",
+       " 'ftashaopxtnemgeoieln',\n",
+       " 'raaejaspnfrnemreppon',\n",
+       " 'raaretrpefphuarnpdkr',\n",
+       " 'farnrorpeprieaendnou',\n",
+       " 'farnrltpephiiuendaoo',\n",
+       " 'flrnirrpipeoneeodsrn',\n",
+       " 'flienorpionrdaeorrns',\n",
+       " 'farrinipneveooeeevre',\n",
+       " 'flinhoopioradoeortss',\n",
+       " 'plapprrdiserevtolfie',\n",
+       " 'flahagrpisatheeolsil',\n",
+       " 'flrhifapitaosneohsrr',\n",
+       " 'flrsrlipitnpnoeohedr',\n",
+       " 'gaaorocjesrnoannnans',\n",
+       " 'flarpropispdeoeonrte',\n",
+       " 'rlarizspisnhezronnin',\n",
+       " 'rleerucpistpheroovdc',\n",
+       " 'flenrrzpisaipeeooiod',\n",
+       " 'fapjrrrpsrnehaelioee',\n",
+       " 'frlrahoptitnenehoxes',\n",
+       " 'raaloofpseidrtrlnosa',\n",
+       " 'fhtfhcopexteeoelorsi',\n",
+       " 'frlfhnhptitearehorsi',\n",
+       " 'palfacfdsiteedtlorei',\n",
+       " 'frhfodsptesoemehlrgg',\n",
+       " 'prhttaedtexuisthlorh',\n",
+       " 'rrhfaiuptetiehrhlrhr',\n",
+       " 'rrvitaaptvhicnrhoiee',\n",
+       " 'prviroadtvhienthoiou',\n",
+       " 'frvgnhaptvhoeneholes',\n",
+       " 'fhvnecrpevssanelocsl',\n",
+       " 'phvnstidevslaotlocli',\n",
+       " 'paahnuadesarrmtelsii',\n",
+       " 'gaohaatjsnrtmvnlhpin',\n",
+       " 'grlhtrojtnroprnhrprd',\n",
+       " 'grlhtutjtnrirrnhrpei',\n",
+       " 'rrlailvptnfeivrhrpro',\n",
+       " 'faorphrpsnpreeelhdil',\n",
+       " 'faoropnpsnperrelhdui',\n",
+       " 'faormropespnnneendsn',\n",
+       " 'rhaansrpemfrnprlnpne',\n",
+       " 'fharnsapemprneelndne',\n",
+       " 'rhaahanpemfatrrlnpsi',\n",
+       " 'fharhhapemparnelndsp',\n",
+       " 'frlrsaiptnpneoehrdee',\n",
+       " 'rhaashlpemfnenrlnpes',\n",
+       " 'rrlfksdptnpgmorhrejn',\n",
+       " 'frlprosptnrpsmehridn',\n",
+       " 'prlpisodtneonethrfre',\n",
+       " 'frlpvdnptnrvotehrioo',\n",
+       " 'rrliahiptnotahrhrhis',\n",
+       " 'frlxvzaptnovdcehraoo',\n",
+       " 'rhansaapemrnftrlnnep',\n",
+       " 'pharesidemnfnotlnnde',\n",
+       " 'rrlhofoptnaepdrhrsue',\n",
+       " 'fhahiptpemaoduelnsrt',\n",
+       " 'grlsattjtnntahnhreii',\n",
+       " 'grlsattjtnntahnhreii',\n",
+       " 'frneofoptrgetdehnhur',\n",
+       " 'fhnhraiperapmoelnsdn',\n",
+       " 'pratiahdtsxosithnohl',\n",
+       " 'fratornptsxhprehnoed',\n",
+       " 'rraoealptshrfnrhnepp',\n",
+       " 'rhaaniupesmrerrlnnnr',\n",
+       " 'fhaanaspesmrerelnnne',\n",
+       " 'roajanfpntnsrtrhiolt',\n",
+       " 'goanlfojntentanhirro',\n",
+       " 'glanohnjntrrrhnritap',\n",
+       " 'rlanoonpntrrehrritau',\n",
+       " 'flaorevpnthtnveriexe',\n",
+       " 'faaoranpmthtlneniexe',\n",
+       " 'rlanuvrpntrluarritir',\n",
+       " 'rlahaaopntafmhrrispn',\n",
+       " 'gohrzstjnraezunhpfnd',\n",
+       " 'glhrzssjnraezmnrpfnd',\n",
+       " 'elkatoenngfirgerjpes',\n",
+       " 'gohzfuvjnreshunhpnrc',\n",
+       " 'faronnapmpohteendgan',\n",
+       " 'forznhepsperatendnns',\n",
+       " 'flrrpnhpnperoaerdeie',\n",
+       " 'roaeinepnfaeonrhpsre',\n",
+       " 'rlannzrpnfhoehrrpaen',\n",
+       " 'fornohfpspsgltendcfc',\n",
+       " 'glroanejnerthgnreaia',\n",
+       " 'gothrsrjnurazenhrpfd',\n",
+       " 'ploprhrdneeiaetrufos',\n",
+       " 'faopohspmerdomenuiso',\n",
+       " 'failftrpmoisuaenrorr',\n",
+       " 'faieerlpmolsanenrosl',\n",
+       " 'fainuorpmorldaenrnis',\n",
+       " 'foisrropsooaeoenrrte',\n",
+       " 'plisaafdnooaedtrrrcn',\n",
+       " 'fahinzopmeordrenlrno',\n",
+       " 'fahnhirpmeraopenlnsr',\n",
+       " 'foairozpssondeennrns',\n",
+       " 'roamrsfpssnnztrnnsnd',\n",
+       " 'faerzlipsaheioenseno',\n",
+       " 'faaihnzpsmoendennrla',\n",
+       " 'faaoiropsmhonoennern',\n",
+       " 'raarnaspsmnofzrnnnep',\n",
+       " 'ranaaajpsrfetnrnnpni',\n",
+       " 'pnnftsndnsdxmttaccon',\n",
+       " 'pnnhtsndnslamttaccin',\n",
+       " 'fnstorzpnoceheearaue',\n",
+       " 'gaorasgjtrenmhniaeen',\n",
+       " 'raonhvopterauoriutsr',\n",
+       " 'garnuecjtehhtanieacv',\n",
+       " 'faeiltoptnoiureirror',\n",
+       " 'gaeororjtareaanisaee',\n",
+       " 'ranhusfptrahndritsct',\n",
+       " 'faloceeptnsaaseirnle',\n",
+       " 'raheltaptatiuiristor',\n",
+       " 'rahelfrptatidnristoc',\n",
+       " 'raaalonpftmiohrpinog',\n",
+       " 'raahnzlpftaoenrpisen',\n",
+       " 'raahnoapftaoomrpiseg',\n",
+       " 'raaoisrpfeeemnrpnurn',\n",
+       " 'friintrppooruvedhrtr',\n",
+       " 'frahiltppmaoiuednsro',\n",
+       " 'frahiltppmaoiuednsro',\n",
+       " 'frarilsppmnoimednnro',\n",
+       " 'frsninsppnsoamedtcri',\n",
+       " 'frhonrrppaerieedsuno',\n",
+       " 'fiirohrpoeneaeerrnus',\n",
+       " 'roalizrpefneevruprrn',\n",
+       " 'foadzhepeloeraeueonp',\n",
+       " 'foeaasepeatemgeusinn',\n",
+       " 'foeaastpeatemceusinn',\n",
+       " 'rreavespeatuhmresirk',\n",
+       " 'fonprlsperrpnmeutidr',\n",
+       " 'filrtovponphsverrdan',\n",
+       " 'gaantcrjetevasnniaul',\n",
+       " 'rlanvrapitruanroitrl',\n",
+       " 'raarvzlpntvueireivrn',\n",
+       " 'raanntapetroosrniner',\n",
+       " 'gaahoaujetagernnisfe',\n",
+       " 'rlahizlpitahenroisin',\n",
+       " 'ftashnapxtnenmeoiela',\n",
+       " 'rlaneznpitatehroiivn',\n",
+       " 'raaejzfpnfrnetreppon',\n",
+       " 'farnrlspepriimendnoo',\n",
+       " 'flientrpionhuheorrar',\n",
+       " 'flaahcnpistaaseolisl',\n",
+       " 'gaavttajesvaiennloie',\n",
+       " 'flareoepispndaeonres',\n",
+       " 'fapjrrrpsrnehaelioee',\n",
+       " 'rrlailvptnfeivrhrpro',\n",
+       " 'rrlaponptnfdrtrhrpts',\n",
+       " 'faorgropsnpjeaelhdne',\n",
+       " 'fharroapemppnselndrh',\n",
+       " 'rhaansrpemfrnprlnpne',\n",
+       " 'rhaahanpemfatrrlnpsi',\n",
+       " 'fhaphthpemdruaelntpr',\n",
+       " 'prlhrofdtnaisdthrson',\n",
+       " 'phahfnedemadrgtlnscn',\n",
+       " 'paorafndesnsdstennnc',\n",
+       " 'ransreopshnetdrlatev',\n",
+       " 'frneofoptrgetdehnhur',\n",
+       " 'fhnaorepenmapselaned',\n",
+       " 'rhaaniupesmrerrlnnnr',\n",
+       " 'rhnraudpeenmrorlsnni',\n",
+       " 'rlanoonpntrrehrritau',\n",
+       " 'rlanoonpntrrehrritau',\n",
+       " 'foanpospntrrelehitiu',\n",
+       " 'rlanuvrpntrluarritir',\n",
+       " 'roakfrfpnfgttsrhpjuh',\n",
+       " 'gohzfuvjnreshunhpnrc',\n",
+       " 'gohzahfjnrenetnhpnes',\n",
+       " 'gohzahfjnrenetnhpnes',\n",
+       " 'forznhepsperatendnns',\n",
+       " 'farrlnopmpacooendlee',\n",
+       " 'farlahepmposraendsnp',\n",
+       " 'glroanejnerthgnreaia',\n",
+       " 'rooaeeapnefarerhupsp',\n",
+       " 'gotnfecjnuedranhrrcp',\n",
+       " 'flinurrpnohleherraie',\n",
+       " 'fairoffpmonestenrnur',\n",
+       " 'flohdzdpneaoeeeruson',\n",
+       " 'ponfnradsndspstnaccr',\n",
+       " 'roamrsfpssnnztrnnsnd',\n",
+       " 'roamrsfpssnnztrnnsnd',\n",
+       " 'faerzltpsaheixenseno',\n",
+       " 'fartdrzpsnneedennrge',\n",
+       " 'fartdonpsnnedsennrgs',\n",
+       " 'fnstorzpnoceheearaue',\n",
+       " 'raalfhspteidcmrinoch',\n",
+       " 'gaanrfijtnheponieaee',\n",
+       " 'fanhusiptrahnoeitsct',\n",
+       " 'frahiltppmaoiuednsro',\n",
+       " 'rahrnnopfaerodrpsene',\n",
+       " 'roalizrpefneevruprrn',\n",
+       " 'foailsopeeoezoeunrsd',\n",
+       " 'roeavtspeatusmrusirz',\n",
+       " 'grohosujenrrzhnehpad',\n",
+       " 'frlrrolpenppeeeerdru',\n",
+       " 'rooasahpenflmeruhpln',\n",
+       " 'gaanhfejnterttneirpr',\n",
+       " 'raajafapetnftnrniopr',\n",
+       " 'raarvzlpntvueireivrn',\n",
+       " 'gartptfjnerdxtneevto',\n",
+       " 'flientrpionhuheorrar',\n",
+       " 'flareoepispndaeonres',\n",
+       " 'fharohepempnlaelndhc',\n",
+       " 'paneoafdshgeedtlahun',\n",
+       " 'rlanoonpntrrehrritau',\n",
+       " 'raarcvapmfpevsrnpdho',\n",
+       " 'rlarnerpnfarrprrplie',\n",
+       " 'flinurrpnohleherraie',\n",
+       " 'fahoroopmeannoenlenh',\n",
+       " 'raallrmpftnianrpirol',\n",
+       " 'rlanvrapitruanroitrl',\n",
+       " 'faonpfcpeeedtaenuatr',\n",
+       " 'raallrmpftnianrpirol']"
+      ]
+     },
+     "execution_count": 44,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[cadenus_decipher(first_chunk, w, keycolumn)[:20] for w in hinted_keywords]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 45,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[]"
+      ]
+     },
+     "execution_count": 45,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[w for w in hinted_keywords if cadenus_decipher(first_chunk, w, keycolumn).startswith('phaseseven')]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 46,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# def cadenus_break_worker(message, keyword, keycolumn, fitness):\n",
+    "#     message_chunks = chunks(message, 175)\n",
+    "#     plaintext = ''.join(cadenus_decipher(c, keyword, keycolumn) for c in message_chunks)\n",
+    "#     fit = fitness(plaintext)\n",
+    "#     return (keyword, keycolumn), fit"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 47,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# def cadenus_break(message, words=keywords, fitness=Pbigrams):\n",
+    "#     c = make_cadenus_keycolumn(reverse=True)\n",
+    "#     results = starmap(cadenus_break_worker, [(message, \n",
+    "#                                               w, \n",
+    "#                                               make_cadenus_keycolumn(doubled_letters='vw', start=s, reverse=r), \n",
+    "#                                               fitness)\n",
+    "#                                for w in words for s in string.ascii_lowercase for r in [True, False]])\n",
+    "#     # return list(results)\n",
+    "#     return max(results, key=lambda k: k[1])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 48,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('finalist',\n",
+       "  {'a': 3,\n",
+       "   'b': 2,\n",
+       "   'c': 1,\n",
+       "   'd': 0,\n",
+       "   'e': 24,\n",
+       "   'f': 23,\n",
+       "   'g': 22,\n",
+       "   'h': 21,\n",
+       "   'i': 20,\n",
+       "   'j': 19,\n",
+       "   'k': 18,\n",
+       "   'l': 17,\n",
+       "   'm': 16,\n",
+       "   'n': 15,\n",
+       "   'o': 14,\n",
+       "   'p': 13,\n",
+       "   'q': 12,\n",
+       "   'r': 11,\n",
+       "   's': 10,\n",
+       "   't': 9,\n",
+       "   'u': 8,\n",
+       "   'v': 7,\n",
+       "   'w': 7,\n",
+       "   'x': 6,\n",
+       "   'y': 5,\n",
+       "   'z': 4}),\n",
+       " -5436.133070290792)"
+      ]
+     },
+     "execution_count": 48,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key8b, fitness = cadenus_break(c8bl, words=hinted_keywords, fitness=Ptrigrams)\n",
+    "key8b, fitness"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 49,
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "IndexError",
+     "evalue": "string index out of range",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+      "\u001b[0;31mRemoteTraceback\u001b[0m                           Traceback (most recent call last)",
+      "\u001b[0;31mRemoteTraceback\u001b[0m: \n\"\"\"\nTraceback (most recent call last):\n  File \"/usr/lib/python3.6/multiprocessing/pool.py\", line 119, in worker\n    result = (True, func(*args, **kwds))\n  File \"/usr/lib/python3.6/multiprocessing/pool.py\", line 47, in starmapstar\n    return list(itertools.starmap(args[0], args[1]))\n  File \"/home/neil/Documents/programming/national-cipher-challenge/cipher/cadenus.py\", line 120, in cadenus_break_worker\n    plaintext = ''.join(cadenus_decipher(c, keyword, keycolumn) for c in message_chunks)\n  File \"/home/neil/Documents/programming/national-cipher-challenge/cipher/cadenus.py\", line 120, in <genexpr>\n    plaintext = ''.join(cadenus_decipher(c, keyword, keycolumn) for c in message_chunks)\n  File \"/home/neil/Documents/programming/national-cipher-challenge/cipher/cadenus.py\", line 89, in cadenus_decipher\n    untransposed_rows = [untranspose(r, transpositions) for r in rows]\n  File \"/home/neil/Documents/programming/national-cipher-challenge/cipher/cadenus.py\", line 89, in <listcomp>\n    untransposed_rows = [untranspose(r, transpositions) for r in rows]\n  File \"/home/neil/Documents/programming/national-cipher-challenge/support/utilities.py\", line 101, in untranspose\n    transposed[t] = items[p]\nIndexError: string index out of range\n\"\"\"",
+      "\nThe above exception was the direct cause of the following exception:\n",
+      "\u001b[0;31mIndexError\u001b[0m                                Traceback (most recent call last)",
+      "\u001b[0;32m<ipython-input-49-ef8b0c9b9c63>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mkey8b\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfitness\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcadenus_break\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mc8bl\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfitness\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mPtrigrams\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      2\u001b[0m \u001b[0mkey8b\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfitness\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+      "\u001b[0;32m~/Documents/programming/national-cipher-challenge/cipher/cadenus.py\u001b[0m in \u001b[0;36mcadenus_break\u001b[0;34m(message, words, doubled_letters, fitness)\u001b[0m\n\u001b[1;32m    106\u001b[0m                         start=s, reverse=r), \n\u001b[1;32m    107\u001b[0m                     fitness)\n\u001b[0;32m--> 108\u001b[0;31m                 \u001b[0;32mfor\u001b[0m \u001b[0mw\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mwords\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    109\u001b[0m                 \u001b[0;32mfor\u001b[0m \u001b[0ms\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mstring\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mascii_lowercase\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    110\u001b[0m                 \u001b[0;32mfor\u001b[0m \u001b[0mr\u001b[0m \u001b[0;32min\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+      "\u001b[0;32m/usr/lib/python3.6/multiprocessing/pool.py\u001b[0m in \u001b[0;36mstarmap\u001b[0;34m(self, func, iterable, chunksize)\u001b[0m\n\u001b[1;32m    272\u001b[0m         \u001b[0;31m`\u001b[0m\u001b[0mfunc\u001b[0m\u001b[0;31m`\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mb\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0mbecomes\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mb\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    273\u001b[0m         '''\n\u001b[0;32m--> 274\u001b[0;31m         \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_map_async\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfunc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0miterable\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mstarmapstar\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mchunksize\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    275\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    276\u001b[0m     def starmap_async(self, func, iterable, chunksize=None, callback=None,\n",
+      "\u001b[0;32m/usr/lib/python3.6/multiprocessing/pool.py\u001b[0m in \u001b[0;36mget\u001b[0;34m(self, timeout)\u001b[0m\n\u001b[1;32m    642\u001b[0m             \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_value\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    643\u001b[0m         \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 644\u001b[0;31m             \u001b[0;32mraise\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_value\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    645\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    646\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0m_set\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mobj\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
+      "\u001b[0;31mIndexError\u001b[0m: string index out of range"
+     ]
+    }
+   ],
+   "source": [
+    "key8b, fitness = cadenus_break(c8bl, fitness=Ptrigrams)\n",
+    "key8b, fitness"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "cadenus_decipher(first_chunk, key8b[0], key8b[1])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "[(w, s, d1+d2, r)\n",
+    " for w in hinted_keywords \n",
+    " for d1 in string.ascii_lowercase[:25]\n",
+    " for d2 in string.ascii_lowercase\n",
+    " for s in string.ascii_lowercase \n",
+    " for r in [True, False]\n",
+    " if d2 > d1\n",
+    " if cadenus_decipher(first_chunk, w, \n",
+    "                     make_cadenus_keycolumn(doubled_letters=d1+d2, start=s, reverse=r)).startswith('finalreport')]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "[(w, s, d1+d2, r, cadenus_decipher(first_chunk, w, \n",
+    "                                   make_cadenus_keycolumn(doubled_letters=d1+d2, start=s, reverse=r))[:50])\n",
+    " for w in hinted_keywords \n",
+    " for d1 in string.ascii_lowercase[:25]\n",
+    " for d2 in string.ascii_lowercase\n",
+    " for s in string.ascii_lowercase \n",
+    " for r in [True, False]\n",
+    " if d2 > d1\n",
+    " if cadenus_decipher(first_chunk, w, \n",
+    "                     make_cadenus_keycolumn(doubled_letters=d1+d2, start=s, reverse=r)).startswith('finalreport')]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "[(w, s, d1+chr(ord(d1)+1), r)\n",
+    " for w in hinted_keywords \n",
+    " for d1 in string.ascii_lowercase[:25]\n",
+    " # for d2 in string.ascii_lowercase\n",
+    " for s in string.ascii_lowercase \n",
+    " for r in [True, False]\n",
+    " # if d2 > d1\n",
+    " if cadenus_decipher(first_chunk, w, make_cadenus_keycolumn(doubled_letters=d1+chr(ord(d1)+1), start=s, reverse=r)).startswith('final')]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "cadenus_decipher(first_chunk, 'filbert', make_cadenus_keycolumn(doubled_letters='lu', start='m', reverse=False))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "chunks(first_chunk, 175)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/2014/2a.ciphertext b/2014/2a.ciphertext
new file mode 100644 (file)
index 0000000..3a2158d
--- /dev/null
@@ -0,0 +1,7 @@
+SXDK LDKB, 
+
+UMDQBP CVK UMX GDUXPU KXAVKU CKVL UMX VQ-PRUX UXDL. RU PMVJP UMDU UMX PMRAIVDKS HAP PTPUXL JDP NVLAGXUXGT PNKDLIGXS PV JX DKX QVU HVRQH UV IX DIGX UV UKDNX MXK LVEXLXQUP CKVL UMDU. SV JX MDEX DQT VSS UKDNXP CKVL VQPMVKX KDSDK UMDU HREX D MRQU VC JMXKX PMX LRHMU MDEX IXXQ? 
+
+UMX NVLLXQU RQ UMX GDPU LXPPDHX UMDU UMX ARKDUXP NVLAGXUXS UMX PZKEXT XEXQ UMVZHM UMXT MDS LVEXS PVZUM UV DEVRS SXUXNURVQ PMVZGS MDEX UVGS LX UMDU UMX PZKEXT JDP QVU HXVHKDAMRN. DU CRKPU R UMVZHMU RU LRHMU MDEX IXXQ KXCXKKRQH UV D UXGXNVLP PZKEXT PRQNX TVZ LXQURVQXS UMX GVQH DXKRDG, IZU DNUZDGGT UMX DUUDNMXS LXPPDHX RP EXKT KXEXDGRQH. PURGG QVU PZKX JMDU UMX PZKEXT JDP CVK UMVZHM, DQS MVJ UMDU RP NVQQXNUXS UV UMX LRPPRQH PZAXKPUKZNUZKX. NDQ TVZ HXU LX DQT ARNUZKXP? 
+
+MDKKT 
diff --git a/2014/2b.ciphertext b/2014/2b.ciphertext
new file mode 100644 (file)
index 0000000..cf8d9cc
--- /dev/null
@@ -0,0 +1 @@
+AFTU HMFCP MZ FT TWHMG DB C W AWU XTMCM CPM PDTT BDZEM J FVG MBCF LTQBP QCB QVCMO ZQCJ. VW U FRWZ ZMUMG QFT H WZSB HMZM ZMYDQ ZMG F VG CP M XDU XB FV G MIC ZF LD TSPMF GB HM ZM QV BCFTT MG WD C QV GMMX HFCMZ B WEM Z CPM VMIC NQEM GFJB . HM FZM V WH CM BCQVO CPM BJBCM U NWZ ZMTQ FLQTQ CJ FV G BFN MCJ L MNWZM UWEQ VO WV CW X PFBM CPZMM WN C PM WX MZFCQ WV. W XMZFC QWV C ZWRFV ZMUF QVB W V CFZ OMC.
\ No newline at end of file
diff --git a/2014/3a.ciphertext b/2014/3a.ciphertext
new file mode 100644 (file)
index 0000000..851ccaf
--- /dev/null
@@ -0,0 +1,4 @@
+KLQQP , 
+PJ X LBR DS ND LWJX M MKD OCLZ SLP LBBJH VLMDB . MKD P LQD L MQ LYB-Y LMVJY LC KL HRVYZ ZQJX U SDS VHLMD S MJ MKD J IDQMK QJT J O TDB MDQY HLUVM LCVBN . MKD P KLI D WDD Y VNU CVHLM DS VY BDID QLC N LGJQ UQJMD BMB, VYHCX SVYZ LY LM MDNUM MJ M LRD J IDQ M KD XR YLMV JYLC ZQVS, LMML HRB J Y QDB DQIJV Q BPB MDNB LYS V YMDQO DQDYH D VY WLYR MQLSV YZ YD MTJQR B. 
+
+VM C JJRB CVRD MKD O SL HL QQVDS JXM OLVQC P DEM DYBVI D NJS VOVHL MVJYB MJ M KD BK VU. M KDP S VS L ZJJS GJW M JJ. T D KLS Y’M YJMV HDS M KD LS SDS W XCRKD LSB X YMVC TD HJ NULQD S MKD CLPJ XM TV MK MK D UCL YB OQ JN CC JPS?? ?B QD ZVBMD Q. MK DP BD DN MJ WD M KDQD MJ LS S QVZ VSVMP , MKJ XZK M KDQD VB JY D LSS VMVJY LC UL YDC L M MKD BMDQ Y MKL M SJD BY’ M OVM MKD ULMMD QY LY S TD TVCC WD QD NJIVY Z MKL M MJY VZKM MJ BD D TKL M VM VB MK DQD O JQ. T D TJX CS KL ID SJ YD VM MKVB LOMD QYJJY WXM SDHVS DS TD BKJX CS HJ YSXHM JXQ JTY K XCC B XQIDP VY H LBD M KDQD VB L WJJWP MQLU . 
\ No newline at end of file
diff --git a/2014/3b.ciphertext b/2014/3b.ciphertext
new file mode 100644 (file)
index 0000000..f0957b9
--- /dev/null
@@ -0,0 +1 @@
+DUSIO JUGOO JUOBS KJVYK IIPIJ OZMSI RKYYP JOIJO HYSIJ BVTUJ MVJUA CZDYO JOIKA AOIIM OISVY OHMVJ UVBRC KGUKB HGOHZ OJGOI CRJUO JSGTO JSBHZ CBVJC GOHSY YGSHV CJGSR RVARC GJMCU CKGIM VJUBC IVTBJ USJMO MOGOE OVBTM SJAUO HCGMO GOOLO BBCJV AOHMO JUOBA CBHKA JOHSR KYYGS HSGIM OODCR JUOSG OSSBH RCKBH JUGOO HOSHI DCJIM UOGOM OACKY HMCGX CBJUO IUVDM VJUCK JHOJO AJVCB SIDYS BBOHM OACBL OGJOH JUOJM CSHWS AOBJO ZDJPA CBJSV BOGIV BJUOZ VHHYO CRJUO IJSAX VBJCS YSGTO MCGXI UCDSG OSSBH ASGGV OHCKJ SRKYY VBIDO AJVCB HGVYY BCMOL OBVRM OSGOE CSGHO HCKGM CGXIU CKYHG OZSVB KBHOJ OAJOH MOGOJ GVOLO HIOSU CGIOR GCZJU OJUVG HACBJ SVBOG SBHAS GGVOH CKJIJ STOCB OCRJU OSIIO ZEYP
\ No newline at end of file
diff --git a/2014/4a.ciphertext b/2014/4a.ciphertext
new file mode 100644 (file)
index 0000000..61ad02d
--- /dev/null
@@ -0,0 +1 @@
+WSHHP MNEDB FANJN RJWNI KHLNP SCRPD KSHNC DJVDX CVJDT NAXNL NMWSJ MNUDK CRTNW XCRJW NUSAI NTKAZ WNSRX CJWNI JNHCJ WNHNM SISAS HVNFK BFXCV IJSJX DCEDC CNEJN RJDSC KBTNH DUINS USEXC VDKJA NJIXJ ADDZI AXZNS IEKJJ AXCVL SALNI PIJNB IXBXA SHJDJ WNDCN IKINR DCKTD SJIXC MDHAR MSHJM DXESC JKCRN HIJSC RMWPJ WNPMD KARVD JDIDB KEWNU UDHJM WNCJW NPEDK ARWSL NIEKJ JANRW NHSJS CPJXB NMXJW SIBSA AGKSC JXJPD UFASI JXENO FADIX LNJWN JNSBT SEZSJ CISWS LNHKC IDBNS CSAPJ XEIDC JWNHN BSXCX CVJNO JUXAN IMNNO JHSEJ NRUHD BJWNI NHLNH IDCTD SHRJW NINEX FWNHI SHNVD XCVJD TNFHN JJPWS HRJDE HSEZJ WNSJJ SEWNR HNFDH JWSIU HNGKN CEPSC SAPIX IBSJE WXCVK IKSAN CVAXI WJNOJ IDMNE SCSII KBNJW SJJWN INCRN HMSIS CSJXL NIFNS ZNHRX RPDKW SLNSC PJWDK VWJID CMWSJ JWNCS KJXAK IIPIJ NBBXV WJWSL NTNNC DHMWS JXJMS IUDH
\ No newline at end of file
diff --git a/2014/4b.ciphertext b/2014/4b.ciphertext
new file mode 100644 (file)
index 0000000..cd9848f
--- /dev/null
@@ -0,0 +1,2 @@
+PRSAO EGERA UIADM WE
+HDN ISNRA SAWUA AESSR EFGDO SOGVO RBEEE AARTE SCTDF MENUI BRTTL MEYTU MTMEU AIKWH UTKWE RWAHM NPWRA EESON ONESE BATOI HACIN EETBR OTADA KTGFE ESYIO FLTTL STIIA EOSVI EONSR RTAUP MNNOA ENCOC NUVRS CLVDR GCTAI IHRIC IAIHR SDUOM RLEMC RNGLE OMARF HIUEW HALCS ASRAC UFRAW WSMEH ULSTO AOHCE LETMT OILSE PDMUM TPTRS LYRHH NTPAN WPMOA DPPDW BESEO ASSLT MLPES LETUN CORER LCLIT AOSVS INIIF WSEAF ORTAA DUYEN ENONN SOPFH ONTWK OERTC SLYVO EIOHL UFOEI OETST HTSBR ENEVE AOUEP GIEES OBDUO RSFEE RCDYA DUTAE PEADR DIGSE EBFUO GGOPO GALYF EWSOE EMDNT OHREB HAAES NEWOR GNFIA ULNLW ADUEO DCOTR ARGVU ENEWH IERTL AUILM SONIO TMUIN EWAIU EWLOE RSTTT ISDRS ASNUS SIESM ERDHE TRYRH PNLRT EREAD MREDE BNNTR NENWM OUTRD OSANE OWOMC GIDCI ASAON TIIOI ASCES ISSUP CRMOY BRINE YWEEL AYLEW TYRTI LHSTO
\ No newline at end of file
diff --git a/2014/5a.ciphertext b/2014/5a.ciphertext
new file mode 100644 (file)
index 0000000..c946bc4
--- /dev/null
@@ -0,0 +1 @@
+TSHHP UAHSA WIBKT SKXSJ KYIJJ SDIRC HYPJI XRSZB ZCKUA IBJCY IKTUZ DHISX XPCBB KTIKI OKJSU BUKNS JIZAH PFKIB LJUZD SACXL YZKHS ZJFCJ UKUCZ NUKTW IPNCH BJISE UHBEL KUKNS JIZAU FTIHI BLJUZ DSHSU XRIZA IAUFT IHUAS ZCZXP SJJLY IKTSK KTIKI OKNIH IKHUI MIBNS JSZSH ATUMI CRKTI CHUDU ZSXYI JJSDI HIIZA HPFKI BRCHJ SRIKP NTCIM IHKTI RXSDB SPSJJ CAUSK IJSHI KTIPT SMISF HIKKP JCFTU JKUAS KIBCF IHSKU CZURK TIPSH IRUXU ZDYIJ JSDIJ XUWIK TUJYC HIXUW ICZIC RKTIY SVCHK IHHCH UJKDH CLFJK TSZKT ILJLS XTSAW IHACX XIAKU MIKTI KIATD LPJKC CWSXC CWSKK TISIH USXRH CYKTI ECSKS ZBKTI PKIXX YIKTS KUKUJ SBHSD NUHIL JLSXX PLJIB KCACY YLZUA SKINU KTSJL EYSHU ZINTI ZJLEY IHDIB UKASH HUIBS ZSACL JKUAK HSZJB LAIHS HHSPS JNIXX SJSJT CHKNS MIKHS ZJYUK KIHSZ BXUJK IZUZD DISHC ZIKTU ZDKTS KFLQQ XIJYI ZCNUJ NTPNI NIHIS XXCNI BKCRU ZBKTI JTUFR XCSKU ZDSKS XXJLH IXPKT IPYLJ KTSMI FXSZZ IBKCJ UZWTI HLJUZ DKTIJ ALKKX UZDIG LUFYI ZKCKT IHNUJ INTSK NSJUK RCHKT IPJII YKCCJ YSHKK CXISM IUKRX CSKUZ DRCHL JKCRU ZBSZP KTCLD TKJYS HWFJV LJKEI RCHIU JIZKK TUJKT IAUFT IHAXI HWASY IUZNU KTSBI AHPFK CRKTI SKKSA TIBAC XLYZS HKHSZ JFCJU KUCZW IPNCH BTSJX IZDKT JUOKT UZWUK SZJNI HJJCY ICRCL HGLIJ KUCZJ SECLK KTIZS LKUXL JJPJK IY
diff --git a/2014/5b.ciphertext b/2014/5b.ciphertext
new file mode 100644 (file)
index 0000000..cd61026
--- /dev/null
@@ -0,0 +1 @@
+SSSATA NUELCL AENDEE HEEVRN HTAILS LTOCSO EOANUO DOEECA FERBET RTENOI IUCRWU RFAPRO EERCSS OEUATU LGTEMA TREMLI EAVEIE OGCELE SAEEEY YIUUOA IDAOSD MDECSS HTHUHA TCNXAE RERSEL TUNAGH ANRDTE VEPISY DTAEAM CINMRN WEORAM RVIBOD SDFDPA TIMRSS IETDAO SPECGR ACNETB LFIOEU SHSMEE IRLSHM ITTRLN ESEHMC LSSOSW FOTTWN BYTEYN GEYMTT GSTARI IXEEED RNASML TWGMIL DCRTSE OGOHRO LSSHMA WNDSST RABNDN ECFCAY EHOTDO RNONEN ECATNE AVOEAA TEHERC YRIGHS AYREFS OOATEM NCWTKA AAWNDA DMSLLN NNLUTF OEEENO YOEWTM ANRRSX HVOROL HISFUN NTHAEE OFOLPH EBAATM NORNOE ODNVTP HNOETE DEAEON PHPAEU RATVHN DETAHR AHPOOR SEFOVD DSTTPS VGRAAA TODSUR YIDOVT RELERL TMEMDH EOARSH OARRRE RXISGE IFAWFA IYIDUS IYIEEE SOTKEA ELATRE SNTIFE MTEIAI GHACEI ONDKTK ITTEAE ANECNN DICTNE DDDENS TSHEAN RTAMNE AHSHID AOCNUI SSCTEH SLNLEC THEETL LTIDLC TTNPNM CVSVNO SITDAE LXPIHS FATTYS FOEDCM WHTEBA ACHERT AIGRIU IRTNGI APHETR OWEHWS WAACMG COUWOO GOEGSM TARTEE IEMVAY INOGST ITAGBL NCSTCY COLRET EDAREH OPNEBY EGWCTE ETLTEY ETEENA NSAFMO
diff --git a/2014/6a.ciphertext b/2014/6a.ciphertext
new file mode 100644 (file)
index 0000000..c80f291
--- /dev/null
@@ -0,0 +1 @@
+MTAEG LATCL EPTEN OPEAU TELEB IIOOT ATWNA NTATE ITUII AGAEO STGVE TABDR ESIAC QOBWA VGRHR SIHSS AEKAJ BWWTT DRSME ETNYA FSEGI LEGTK RREOC UANTT EOMSG STNSI AELUU TRBAI AETEE SERHX GTOOA RRBHP CKLIA LHNAE SVEAR HBEPI YDCES EWTAX UYAER YWOEI NHTEE GEISI EIREA ASSRB ITNHT UOROO LEEWS TTERE OAHYA KHLSM SAEOD SLTHS UTIGQ IMNID SGETP MWTRN NOTFH VSELK AUMRN DVCNR LUCER YHYEE TLNIG OUNCN ANRHP NOSBH SHPSL RECLV RINFO EHNIA EENNH CRBEN RGUNR UESML REHIU TGTEO RDROE AEOIS OEUSI KNTEE SLOHT HDCRM ISUTE OTEAE OSHFA IAESE MRITR SEISA IGWYR MHRBT ETNCO ENUHO RCADE ODLCR NCOMN CTOSI HUDTC INAGE SNTIS UTIGY TMSHT HYALA TLSNH ILGUI MTLBF LDYHR FRNET SAOST EETAE FHLGO KHRET CAKUT EIHRL RTLSE TSHLC PEADH THYUT AEENN HRYRA EENNI HRNBH NSNEH YUTSD TOYWM TIATA LWHVB EPETL XIHUS CRTAD TIKHN XMSAE SNWLU EVGNR CPEGV NHTER UIGEU EALSD NTIKE AEOMC TWRYB USIIL EPHKY ODHRS YHECA ATRMR LTRAR RETST UOETN UESID UAIDO ESISA EETBL LERPN TROIS IATSI ASESO MIHSI EIAUN SAITN EELAC RFNRN NGVET TEENS LHVPE PTEON EDTNA OOUTG SOTAN CETIM IIWOE TIUIH CLSEW TCNII EOTSL FBEEC OHENP OELSD OCTCE EEMII IRTTM HBIUO VECEG AITJU ABORC LEENT ATRUY INETS IDLAE EHITW ENCCE OHWVO HOATW KTERO ARHCS EER
diff --git a/2014/6b.ciphertext b/2014/6b.ciphertext
new file mode 100644 (file)
index 0000000..84e0dcc
--- /dev/null
@@ -0,0 +1 @@
+HWSSS WXFEW HHRFE WPDRV TTDHX BCCLE AYPHA LNADH IEHAO UDROT WNRRV YSABJ LTTBA YTMEL RKAID OPTHA TLELR TWAAM ANEKS VVZRV LLATK CRJQU ICIZG TOQCP NRRKT TOWAN DQEHT QRVTB AYDQE ALANN OHULA NUZLW EXTLV JRVIV HNOHD QMGYK ACLMS WRUPD ETFIO FTFEL HZPXH ASWFT WPRRS WEISE OHEFP DRVTT NVAGD VSWGO ERBET NHARV AEEVT LLTBM GAIAT GELIN MDAWE VHATT ERDHR ZNBNV OUTNE FOTEV EAEHL AYMHA CGLZE PTVVD IMWOR FISGT UZLWI BEQOH UBTGH AMQOR NJNNR UMQVJ TXELT FOVGA WDAEE VLLGR TXIBG TIBEV MPSAA TEOAS EVAEY QOHAM EONNC FUIDO EFAFA TTEMU IMNFL ZNBEK OFOBR LIAEH HAUIH NNNWZ AEEVT LLTPA ALNAN VTZLZ UUCPT AELIN ANPAA HEWFT HAOSE TARIB NBNVH AEVDH YYTLM UXB
diff --git a/2014/7a.ciphertext b/2014/7a.ciphertext
new file mode 100644 (file)
index 0000000..597b991
--- /dev/null
@@ -0,0 +1 @@
+VEYJM YJKRZ ILYSY JEYDO RULCS RCJNM OIDDE UGURL OGFSN WCRLH CKHGH MWKEJ XLYKT LAGFL ALVTM GKYYO MVLMG KYJOS FDRZE PWAQG NRZEQ ZINOA QFORK CSLTJ WDUSS RZARL HCNAJ NEQZA BBAKE EBATJ GOIKL GCERZ EBJID LWMGD USSNM LJWDG FTMLH CEEAZ ALASK SNBTL MUKCV TFWIL DERHR CKUKS BJQTF WCPWW FSDYD RCSDW SBYFD MFEBL HCNEQ KEJOH GUHUS SJMCI QFMJU QOIRZ OSLTF WSFAP UWWMM LBZAT WHYVN MADCS TFSTR ZEDVA FSDZW ELGPC JARAN EANRZ EQWWY LEPKS CSHMJ SCASL GLMFG CJAKQ SRWRW LHCUU RSWYQ OLLHC KTYJB MSRBK IBWCJ WAPWD YFAPW AMXAP GULVF GNEKW TCJSQ IUYJE UATFS DGKTG FCRAV CHARL EPFOD TOJLS DSSRW NCVTM JEGFF MJCCV DCUKN DARWS GKAUK OKWTF ANEDI IWTFA SMFAQ MBPWS AMEKA SQAOL SCMMP JWODQ EYJSY YOUZE LLHCQ FGLTC VAJGC YDSFA PUATF SJSJY PAGEW DGFSN WCRAO LKYQL EKLHC VEACP JSTCK CYFCY JRWSC PSNCV EQAGL WDRGD CHLMQ ALJOT SRCEO RWONW RYLEB NEFAC JWDCK IEFEB XOPMN BWRQW AMHEP STGGN QAWYK AJJEY VYAGN AWRLW DYTOS LTFWR CXEPW NAWTM LHCUA ZDEQA NRZEJ SSRHA PLODL HCXDY DOETU RLHCF EVLSC UTGGN FSSKW RCSLJ QWMJR GWDGL IQWNA JYNLE BOIRZ AKGRC KEAMR CEOBA FGWDY ESAGT PSNQH OQATG GNAAP FWRYF DRWLJ KUQOH YLTFW YUWRC JEYDL WMPRG WFSTG VOLLU LVEPK TYFDG KHMOT FWWFG LCSSQ WMZDY GKPMO EPWDR ZEQGR RGFAG MNMTG FGRZE WEUQL BCVOG FGGKR CSLJQ ILLEL KITWA LVWMM LBTUP FTFJO SYHYT ARLEP QILVA WKILL HYLTG EERZE GJILL EPUEN LMGYH RFORU ARUHY FYRZI LYUQW FSDBS LTFWY ASNFS RBDYF SVCZI HSCIW DYDOA SLQGC IWTGF TFWMG VDJWO DLHCG CCSNA SNWGU EWTKW AAZAP LSFGW GFGRZ EBWEN KEYUA ZDEQA NRZEP WGGGN GVOLL IKSGG FERZE SKWGD LZWAN JOZDE KTURA TKSYL WEBKO KWDGH LMEAA QTMYE RLHCX UJDCM NEPSG CEANK FPGMR ZEMEA LAGMN EPFMC FTGXI YERGY HRATG KILLH CARZW SRANR WRCKT QLOND AWSLM FGUWA JDHYN EYDOR LOJGS CZEPW
diff --git a/2014/7b.ciphertext b/2014/7b.ciphertext
new file mode 100644 (file)
index 0000000..fb8e3dc
--- /dev/null
@@ -0,0 +1 @@
+ANWAE CNNDR TWTAN IREOA HSRDN TIEER DCTEW AYERE VAAAR PIOER OBSED ESCRE HLAOI TITHS DTRIN OSEPE PLTHT NIDTW SDULE DLHOT PEATE RHAAR EDEOA IODTA HREGE ROTHW HTSUR ETEEI NWIGI RESET POWIC OOONI TSEUD SEECH ACTEO FIILE ONEWI OTACT EODTE UNEAH SEDAP TRYEM RONMO MLEXO NTKEM EOYVI TSTEE NHANT RERTI EINEO TNDLH POPLY ITEWI TRSED EEVDY CFRMN SNAYP INMTE ENEEI NAHIN EPRIT EDEHV ELEAO RELLL VMOCN AHNCE PHERO HJUUV EHAUT ATHTT ETOAS IPOWW NEEDS ELOPG DESLF EDTER FCAAT EHJAS DTRPR LESEE RETET ECNEO RRSGC KAMII WAEFU TIASH AONGC THSRE NREHT RSTHH ACEIN WTPRL OGHET ODAER ALOEE DEATS OMLDW EDTWE FSBEL EVPDT EONOI GNSAV FTEGS EBOMC EHATI ETNRS PTONT HUSOR ECRED ENDCE TLWAE HESED RNCVE RACUH OIHAL EINAE MEUNH ERDES TTSTA SIPED EYLEE EMTII SIIGO THNTS SFOLN ITRET RWHEM TKHHS WTORC SSNER EROHT EENCS APEBL IRCNT HULEO FENRS ROMRN SHMAD DAODE ATIHI OROUT WEVTH APECE ETOVT ERDLE ADITE WDOTT TTCAT KMBHT HEICW ANTNI SEDWA TXANK EABOV OANMS WLPRG AISPO DFOGN DPEDE SWRDA CTTRE FHDES YABER RETLA VOD
diff --git a/2014/8a.ciphertext b/2014/8a.ciphertext
new file mode 100644 (file)
index 0000000..56e7884
--- /dev/null
@@ -0,0 +1 @@
+NYVLG GSYGL CHXFE UYTQC ESQXP ZIUFI GGRBJ HPAYN CRUYF PSXUF IUPSK YRECT MMCNC RUYRE GXIGR LGLBT IBLME CEBZS VRLPU XPBIB JAJRL JREOB AJRLU FIGJE HBEZY WTMGJ YXFQX ICTSG RDGTB JAFYO OCWTM JBLCT WWUCQ MGOFR LFMRF RLFWL BTIJL WUYPM CHJQX ICRFC HUMTS MZJBI MYVHC UVYRU GXJCW PDTPU ISRLF DHBAE NCYQU MUFEO GRHCR JMYTQ SMSXJ MRCSX JRMTT ISWZV JRFPE CJITN IDGEM DSSAI TASVJ HUYOF GXPSX GMVVQ FVRXI YXXMY MBXFJ PUFIG BEUFE UUIIY ZFAVB AOFBX ICMSA MQFIS QWPGR TRIBB MTSKH CWUUI MCXUF INBIT RVPWX SMNBL JPPYT UIXGP MLIFB GPMTF PEUGS ODVPK XICSN YRJES WCVOK IOREO YVNCH GGKIR ISHIU YRERL FDPJE LUASO RVPJW ZQXFK WGPSN YHSMR FKIBL AIGPF UIOCI ERSFL WVPIU USUFM OEWPL IUFEU UIEMR PRWFL HDPMU GGBJM ODSSK EUGSO YGSMW TRLFZ ECYPN YREYF TRVBG XBLHU USUFE UUIVQ IBLSO AVJRM DYPLC CHCRF PEUGS ONVPR SDMPP LXIYX DFEOL IMEMW CRUFI MCZFJ SGASN KMUKI ORXIC JEYLB TITFS XLMOB IWCPP NMOEX IGWQJ EOGEN QYSCX IYXUF IZUMM JVFGR TREUC XICTP UISQY QNPZU MUFMO YJFUQ PLXIQ FVRAJ RLMSG LRLFW AJJPO MXHSI TQXIY XXCOO MABZS VRMUY REUIX GPMNY UGXPS XPDFV QMOCW TDSSJ SOEIO MYHFX PASNC YQUMU FEQJE OMJPS VPURU MIYNP PGXJR MORLF KIBLX JKIXC RPUOO MAUFE URLFG VIGKI CWUQI DSVJR CDMQN SRJAE UGSOQ ESCIO AVZNX FBYTG RHYGB BIOSW DGTIC VTMAF AEOQX BPXIS RUGRH RLSMY HFXIC HBREC YWFDS SMXIC VJLXF PGFNX TUIDY RDPED IXIGW NYCCC XICFS CELRL SMYHF AFFEW CFFCR MMSLG RHDSS GRUFI GGKIR EHYMO QXUFI GBEMC XTLSU QGSCA JRYQY PMRLF ZITRL BPVZ
diff --git a/2014/8b.ciphertext b/2014/8b.ciphertext
new file mode 100644 (file)
index 0000000..9be6e62
--- /dev/null
@@ -0,0 +1 @@
+0000000101000100000000100101000111010011100110000000010100110011110001010000111001011001001001100010100100010010001100110011110010001111001110001000000011101010110000111010001011110010110001001100010001110000000001101111011110100101101001100101110011001001000101101001000010100100011100010101000011101000110011100100001100011011100010000100101000110010010000101000110100001001000101101001010010010011010110000000000001011001010011101100100000100011011001110001101010111001110011010010010001001111010000000001111000100000101010010010001001000010010011100101010110010010000010001011001110101101110100101001100011011100000001011011101100000000001001001001100011010110100011010000011001101011011000100111011100011100111100111001001101000000111001000010110110100010011011001010010010000001010001001000000001101011010010000100010000100001000001001000110110100110000001101001001001010001101010111000110010000010001000110001011010010100100001100110011111010101110010000000001000100100000001110000000010001110000000010000011100010110101000100111000101101101110010001000001101000101111100101001000111000000001100111000111001101110010000111100000000001001100100101110010001101011010010010010000000011010001011100000110011010110010010010100010110110001011100100010001110000111100001001100010000011000100101101011010001011000000010110000001011001000010001101010000011010001100010110110110110001000101011010000110001011011111001010011011100101100100001011001110001000110110010100000001000101000001000010000100010000100000000011100101101101001001011010010000000111000111100011001101011100101001101110000010010010011011011001001011101010010101000101010001101110101011001101111011100000000100001000100010010000100100001110001110100001111100100010010101001000010000011100110010010110001010000010001011010011100100000010101100100000000111010011011100011110011100111001100100011110110100010010100000001110011010011110110001001001101100101011100001111100011000100100011100110101101000001001000110000110010000011011100010000100001000111000000000000110010011000100100000010100111001101000001010110100000000111000100100100101000110011100100010010001011101001000100100111000100111000100100000010100110111110010000000000000100001110101100011001111001000101101111001001110000000111010011000101001100001000011001001110001000100010001011011001000000000110101111000100111000110001101000110110001000100010001111100111001100111100010010010100001110110101010100110000000010001000001000100001000101110001101100110101000100010010000100001000000000100100100010000100001000100000011010001001001110001100001000100011100110001101100011001100100010010011100000001100000000001100100010001101010001001101011101101001110001011010000101100010000010001011100100000010001001001001100100100101000101101001101001001101001110010000001010000111010010000110100000100011010000000101010110010001000100100000000111011100001001000001010010010101011000010100000100110000001101000001001110001011010100000000001100110100111000001001101101011000100000001011010100010100001010010001101100011001101110100111001110001011011100001111000000100000011110000100000100001100001101101011000010010001001110011101000011101001110001001001001100010001001001010010001000100001011000111000100001000100010001111100010100000110000000010010010011100000000011010111001100000001110100000100101010010000001100010001000100011010101100100101010000010010000000001101101011011001100111011010010001000100110010001000010001001000000001111010000111001111010000000011000111001101001000010111000001110101101110011011011000111000000010000100001000010001110100100110100100001001100000000011010010001000100100010010011011100011011000010001001100100100010101101000001111001100010011000100001110010001000100000100010010100011011100010010011011010100000111100110110100100001110100001000010100000001100100010001101100011010000000011000000110100000011100001110010001001001000100010001100000010010111001001000000000110110011000000111001011100110001001000110000110001000000110010001101100111001100111010111001101101000111011110011100111001101100000001001000001010110010000000001000010010011010110100010010010001000110011101101001110100100010111100101000000100001011100110010000000011100010000101001000100010010010000100001000110000100010010010000101010101100111011001000100100111110001000011001001000011010010001011011110011110001011000111000111010000000000110011010101110010010111010101000100110111000011000000100010010000110111101101110000001100011000100000000000011101001100000001110001000100001111001110100001000100010001100010010000011000000010000010100110111010010011011000100111101010110100000011100001101110010000101001110001001001100010010000110100100011010010010100100011000101000100100001100010011101010010001000000011001011101010100001100011001010001111011110001101000100110010000000011010001101000100110110000000000000100000000010000010001011001000111001101011011000100100001000001100000011100001100001011100100010100011000010001011100010111010011011011001110011100110011001000100110110110001010111000101000001000110101101010000101001011110001001001110001101001010011000100100000101110000111101000011111010101000000111010110010100100110001101000100010001000000001001001000010001001110010011010110100100000001001101000100110111001100100010011100001011010011101101010000001101111100010101110001001000111101110110000110100000010111001001101101011001000011011101001000000011010010010010010001001100101000000010001101010111001100110011100001100000100111001100100001000000001000100100100000010100010111001110100110110010010011000010100111000001010000100011010100010001100100011000111110000110110110001000100001101100110010000110011100001101000010000101100100001000001110011000001000101101011101001010001000100000000000001000110100011100110001010100100111001100101000111000100001001000011110011011000010101000100110111001110100010001110001101000100000000011101100000000000000110101110001000010001011000110111001000011010011110100100100011001000100110010000000011101000101000001000001000100101010010001100011011001110001000001001101100100110010101111001001010000010101001001100000001110000001100100110110100100101100111001101010000001000011001000010001100100010111100000011100101101000100110111000000001010010010010011100111010010100100111100101011010101101101001000010001110011101001100000000100011101011010110100010001100101001010111100100111000101011110001100101100110010110001011010111110001000000010000100000001100001011011100110100000001110000010100100110110110011000100110110011000100000100000101100101101110011010010000101100110111000000100110010000010101010111010110000110101110110101010110101101001000010000011100110100001000011100100000110100110010000110011001001100000001110010000100000001001100100001010000000000001000111110001100010001010001011101001000111001000010010001100010111100000010110010000011010000010001101001100100000011100011000100100011101010000111101010010010010101001000101110110001001101101100100111010010010000110110100010001010001000011100010101111100010001100000
diff --git a/2015/1a.ciphertext b/2015/1a.ciphertext
new file mode 100644 (file)
index 0000000..d222977
--- /dev/null
@@ -0,0 +1,4 @@
+TMDDK, EADDK FA PDMS KAG NMOW UZ , IQ IQDQ TABUZS FA SUHQ KAG EAYQ FUYQ ARR MRFQD FTQ XMEF OMEQ, NGF EAYQFTUZS OMYQ GB MZP IQ ZQQP KAGD TQXB. 
+
+MF M YQQFUZS AR FTQ RAGD BAIQDE MXXUQP OAZFDAX OAGZOUX FIA IQQWE MSA FTQ RDQZOT MOOGEQP FTQ DGEEUMZE AR ETQXFQDUZS M ZMLU YQPUO WZAIZ ME FTQ DQUOTEPAWFAD. MBBMDQZFXK FTQK UZFQDOQBFQP M YADEQ OAPQ DMPUA NDAMPOMEF RDAY FTQ DGEEUMZ EQOFAD AR NQDXUZ UZ ITUOT FTQ PAOFAD IME ARRQDUZS UZFQXXUSQZOQ MNAGF FTQ DMFXUZQE UZ QJOTMZSQ RAD MEKXGY. FTQ DGEEUMZE OXMUYQP ZAF FA WZAI MZKFTUZS MNAGF UF, MZP YMKNQ FTQK MDQ FQXXUZS FTQ FDGFT, NGF FTUZSE TMHQ NQQZ M XUFFXQ RDAEFK EUZOQ FDGYMZ’E EBQQOT AZ YMDOT FIQXRFT MZP IQ DQMXXK PAZ’F ZQQP YADQ OAZRXUOF DUSTF ZAI. IQ RUSGDQ IUFT KAGD OAZFMOFE AHQD TQDQ KAG YUSTF NQ MNXQ FA RUZP AGF UR FTQ DGEEUMZE MDQ FQXXUZS FTQ FDGFT. U TMHQ MFFMOTQP FTQ QZODKBFQP FDMZEODUBF AR FTQ NDAMPOMEF. 
+OTMDXUQ
\ No newline at end of file
diff --git a/2015/1b.ciphertext b/2015/1b.ciphertext
new file mode 100644 (file)
index 0000000..98a9dd3
--- /dev/null
@@ -0,0 +1 @@
+WT MCI KOBH HC YBCK HVS GSQFSH CT HVS FOHZWBSG W AOM PS OPZS HC VSZD PIH HVS DFWQS KWZZ PS VWUV OBR WG BCH BSUCHWOPZS ZWTS VSFS WB PSFZWB VOG ZCGH WHG ZIGHFS OBR W KOBH GOBQHIOFM WB O ACFS QCBUSBWOZ QZWAOHS KWHV GSQIFWHM TCF AM TIHIFS W QOB DFCJWRS RSHOWZG CT DSFGCBBSZ DCZWQM GSQIFWHM OBR FCIHSG OBR QOB TIFBWGV MCI KWHV RCQIASBHOFM SJWRSBQS CT HVS FSOQV CT HVS CFUOBWNOHWCB HVS FSWQVGRCYHCF 
diff --git a/2015/2015-challenge1.ipynb b/2015/2015-challenge1.ipynb
new file mode 100644 (file)
index 0000000..47cdd36
--- /dev/null
@@ -0,0 +1,133 @@
+{
+ "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.caesar import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "\n",
+    "c1a = open('1a.ciphertext').read()\n",
+    "c1b = open('1b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(12, -883.4816832492597)"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score = caesar_break(c1a)\n",
+    "key_a, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "HARRY, SORRY TO DRAG YOU BACK IN , WE WERE HOPING TO GIVE YOU SOME TIME OFF AFTER THE LAST CASE, BUT SOMETHING CAME UP AND WE NEED YOUR HELP. \n",
+      "\n",
+      "AT A MEETING OF THE FOUR POWERS ALLIED CONTROL COUNCIL TWO WEEKS AGO THE FRENCH ACCUSED THE RUSSIANS OF SHELTERING A NAZI MEDIC KNOWN AS THE REICHSDOKTOR. APPARENTLY THEY INTERCEPTED A MORSE CODE RADIO BROADCAST FROM THE RUSSIAN SECTOR OF BERLIN IN WHICH THE DOCTOR WAS OFFERING INTELLIGENCE ABOUT THE RATLINES IN EXCHANGE FOR ASYLUM. THE RUSSIANS CLAIMED NOT TO KNOW ANYTHING ABOUT IT, AND MAYBE THEY ARE TELLING THE TRUTH, BUT THINGS HAVE BEEN A LITTLE FROSTY SINCE TRUMAN'S SPEECH ON MARCH TWELFTH AND WE REALLY DON'T NEED MORE CONFLICT RIGHT NOW. WE FIGURE WITH YOUR CONTACTS OVER HERE YOU MIGHT BE ABLE TO FIND OUT IF THE RUSSIANS ARE TELLING THE TRUTH. I HAVE ATTACHED THE ENCRYPTED TRANSCRIPT OF THE BROADCAST. \n",
+      "CHARLIE\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(caesar_decipher(c1a, key_a))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(14, -403.53308240183975)"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score = caesar_break(c1b)\n",
+    "key_b, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "if you want to know the secret of the rat lines i maybe able to help but the price will be high and is not negotiable life herein berlin has lost its lustre and i want sanctuary in a more congenial climate with security for my future i can provide details of personnel policy security and routes and can furnish you with documentary evidence of the reach of the organization the reichs doktor\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(' '.join(segment(sanitise(caesar_decipher(c1b, key_b)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/2015/2015-challenge2.ipynb b/2015/2015-challenge2.ipynb
new file mode 100644 (file)
index 0000000..2413072
--- /dev/null
@@ -0,0 +1,133 @@
+{
+ "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.caesar import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "\n",
+    "c2a = open('2a.ciphertext').read()\n",
+    "c2b = open('2b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(15, -1150.5844346071483)"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score = caesar_break(c2a)\n",
+    "key_a, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "CHARLIE, NO NEED TO APOLOGISE, LIFE WAS GETTING DULL BEHIND A DESK AND I WAS GLAD TO HAVE AN EXCUSE TO FLY BACK TO EUROPE. I AM INTRIGUED ABOUT THE REICHSDOKTOR - I HADN'T COME ACROSS THIS BEFORE, WHEN DID YOU FIRST COME HEAR OF IT? \n",
+      "I THINK I MAY ALREADY BE MAKING SOME PROGRESS. ON ARRIVAL I FOUND A POSTCARD WAITING FOR ME ON THE MAT AT THE EMBASSY WITH NO MESSAGE ON IT . AT LEAST THAT'S WHAT IT LOOKED LIKE AT FIRST. I DID NOTICE THAT THE LETTERS ON THE FRONT COULD BE HIGHLIGHTED TO PICK OUT THE PHRASE THE REICHSDOKTOR SO UNLESS THAT IS AN EXTRAORDINARY COINCIDENCE I FIGURED IT MUST BE RELATED TO OUR INVESTIGATION. THE STRANGEST THING WAS THAT THE POSTCARD HAD A STAMP BUT NO POSTMARK ON IT, SO IT CAN'T HAVE BEEN POSTED. SINCE IT WASN'T SIGNED I ASSUME THEY WANTED TO STAY ANONYMOUS AND I COULDN'T SEE WHY THEY WOULD HAVE TAKEN THE RISK OF HAND DELIVERING IT, BUT IN THE END I WORKED IT OUT. THERE WAS A HIDDEN MESSAGE. I'LL LEAVE IT TO YOU TO FIGURE OUT WHERE IT WAS HIDDEN. ANYWAY I'VE ATTACHED THE MESSAGE I FOUND. I KNOW THAT RELATIONS WITH THREE OF THE FOUR POWERS ARE RELATIVELY STABLE, BUT I THINK WE NEED TO KEEP THIS TO OURSELVES FOR NOW. ALL THE BEST, \n",
+      "HARRY\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(caesar_decipher(c2a, key_a))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(21, -574.2402792119872)"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score = caesar_break(c2b)\n",
+    "key_b, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "if you really want to get in the middle of this you will have to pay i know you will be hunting me and i can forgive the arrogance but i will not forgive your ignorance before you can learn more about the rat lines from me you will have to ask your colleagues in french and british intelligence what they already know powerful forces are working to keep the rat lines running and we both need to know who our enemies are before we can meet you should understand that without me your investigations will gain little negotiations with me may gain everything\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(' '.join(segment(sanitise(caesar_decipher(c2b, key_b)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/2015/2015-challenge3.ipynb b/2015/2015-challenge3.ipynb
new file mode 100644 (file)
index 0000000..118f461
--- /dev/null
@@ -0,0 +1,131 @@
+{
+ "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.affine import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "\n",
+    "c3a = open('3a.ciphertext').read()\n",
+    "c3b = open('3b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "((3, 5, True), -901.37737042341)"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(key_a_m, key_a_a, key_a_o), score = affine_break(c3a)\n",
+    "(key_a_m, key_a_a, key_a_o), score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "HARRY, THE PUZZLE OF THE STAMPED POSTCARD HAD ME FOOLED FOR A WHILE, BUT I THINK I FIGURED IT OUT. WAS THE MESSAGE ON THE BACK OF THE STAMP? I AM GUESSING YOU STEAMED IT OFF AND FOUND IT THERE. IT WAS A PRETTY INGENIOUS PLOY. MY MASTERS BACK IN WASHINGTON ARE INCREASINGLY WORRIED ABOUT OUR RELATIONSHIP WITH THE REST OF THE FOUR POWERS. FOLLOWING THE BREAKDOWN IN TRUST WITH THE SOVIETS THEY ARE COUNTING ON THE UK AND FRANCE AS ALLIES. IF THEY ARE GOING BEHIND OUR BACKS WITH THIS REICHSDOKTOR, THAT DOES NOT BODE WELL FOR FUTURE DIPLOMACY. DO YOU HAVE CONTACTS THERE YOU CAN EXPLOIT TO FIND OUT WHAT THEY ARE INTENDING? WE REALLY CANNOT AFFORD TO FALL OUT RIGHT NOW. THE ATTACHED MESSAGE IS ANOTHER INTERCEPT, THIS TIME FROM THE BRITISH EMBASSY WIRELESS. WHILE THINGS ARE DICEY I DON’T FEEL I CAN ASK THEM ABOUT IT, MAYBE YOU COULD CRACK IT FOR US. DOES IT MENTION THE RATLINES? BEST, CHARLIE\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(affine_decipher(c3a, multiplier=key_a_m, adder=key_a_a, one_based=key_a_o))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "((5, 7, True), -574.5522852453349)"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(key_b_m, key_b_a, key_b_o), score = affine_break(c3b)\n",
+    "(key_b_m, key_b_a, key_b_o), score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "eyes only rumours of a source in berlin with access to the rat lines source seems to go by name of reichs doktor russian intercepts suggest has been seen in vicinity of us embassy not clear how to make direct contact also not clear why our us friends are keeping this to themselves detailed info about rat i lines hard to obtain but high value could lead to arrest of major targets of nuremberg investigations vital we reach reichs doktor at earliest opportunity discreet enquiries in french and us sectors only request funds for further investigation\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(' '.join(segment(sanitise(affine_decipher(c3b, multiplier=key_b_m, adder=key_b_a, one_based=key_b_o)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/2015/2015-challenge4.ipynb b/2015/2015-challenge4.ipynb
new file mode 100644 (file)
index 0000000..3d00e6e
--- /dev/null
@@ -0,0 +1,292 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.keyword_cipher import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "from support.language_models import *\n",
+    "\n",
+    "c4a = open('4a.ciphertext').read()\n",
+    "c4b = open('4b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('reanimates', <KeywordWrapAlphabet.from_last: 2>), -911.6411317751041)"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(key_a_word, key_a_wrap), score = keyword_break_mp(c4a)\n",
+    "(key_a_word, key_a_wrap), score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "gharlie, the attaghew note fas ledt in one od my weaw wrops last nibht anw appears to ce drom our mysterious sourge. it gontains tfo really sibnidigant pieges od intellibenge. the dirst is that the rieghswoktor mibht not reder to an inwiviwual adter all. it seems to ce the gowename dor the orbanization runninb the ratlines. aggorwinb to my other sourges this is a gollegtion od routes, abents anw sade houses usew to transport nazi sympathisers anw far griminals out od bermany anw on to south ameriga. fe have knofn that sugh an orbanisation exists singe the enw od the far, cut this is the dirst time i have seen it namew. the other piege od indormation is mugh more suctle. i am cebinninb to fonwer id our sourge is gloser to home than fe haw realisew. anw i am not rederrinb to drangois! see id you gan spot the tfo thinbs i notigew. cy the fay, fho transgricew the rawio intergept you sent me last feek? harry\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(keyword_decipher(c4a, key_a_word, wrap_alphabet=key_a_wrap))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'a': 'c',\n",
+       " 'b': 'o',\n",
+       " 'c': 'p',\n",
+       " 'd': 'q',\n",
+       " 'e': 'b',\n",
+       " 'f': 'r',\n",
+       " 'g': 's',\n",
+       " 'h': 't',\n",
+       " 'i': 'e',\n",
+       " 'j': 'u',\n",
+       " 'k': 'v',\n",
+       " 'l': 'w',\n",
+       " 'm': 'f',\n",
+       " 'n': 'd',\n",
+       " 'o': 'x',\n",
+       " 'p': 'y',\n",
+       " 'q': 'z',\n",
+       " 'r': 'a',\n",
+       " 's': 'h',\n",
+       " 't': 'g',\n",
+       " 'u': 'i',\n",
+       " 'v': 'j',\n",
+       " 'w': 'k',\n",
+       " 'x': 'l',\n",
+       " 'y': 'm',\n",
+       " 'z': 'n'}"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "trans = ''.maketrans(keyword_cipher_alphabet_of(key_a_word, wrap_alphabet=key_a_wrap), string.ascii_lowercase)\n",
+    "t2 = {chr(c): chr(trans[c]) for c in trans}\n",
+    "t2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[('r', 'a'),\n",
+       " ('a', 'b'),\n",
+       " ('t', 'c'),\n",
+       " ('l', 'd'),\n",
+       " ('i', 'e'),\n",
+       " ('n', 'f'),\n",
+       " ('e', 'g'),\n",
+       " ('s', 'h'),\n",
+       " ('u', 'i'),\n",
+       " ('v', 'j'),\n",
+       " ('w', 'k'),\n",
+       " ('x', 'l'),\n",
+       " ('y', 'm'),\n",
+       " ('z', 'n'),\n",
+       " ('b', 'o'),\n",
+       " ('c', 'p'),\n",
+       " ('d', 'q'),\n",
+       " ('f', 'r'),\n",
+       " ('g', 's'),\n",
+       " ('h', 't'),\n",
+       " ('j', 'u'),\n",
+       " ('k', 'v'),\n",
+       " ('m', 'w'),\n",
+       " ('o', 'x'),\n",
+       " ('p', 'y'),\n",
+       " ('q', 'z')]"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "t2['t'] = 'c'\n",
+    "t2['a'] = 'b'\n",
+    "t2['e'] = 'g'\n",
+    "\n",
+    "t2['l'] = 'd'\n",
+    "t2['n'] = 'f'\n",
+    "t2['m'] = 'w'\n",
+    "\n",
+    "sorted(((c, t2[c]) for c in t2), key=lambda p: p[1])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "charlie, the attached note was left in one of my dead drops last night and appears to be from our mysterious source. it contains two really significant pieces of intelligence. the first is that the riechsdoktor might not refer to an individual after all. it seems to be the codename for the organization running the ratlines. according to my other sources this is a collection of routes, agents and safe houses used to transport nazi sympathisers and war criminals out of germany and on to south america. we have known that such an organisation exists since the end of the war, but this is the first time i have seen it named. the other piece of information is much more subtle. i am beginning to wonder if our source is closer to home than we had realised. and i am not referring to francois! see if you can spot the two things i noticed. by the way, who transcribed the radio intercept you sent me last week? harry\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(keyword_decipher(c4a, 'ratlines', wrap_alphabet=key_a_wrap))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('francois', <KeywordWrapAlphabet.from_last: 2>), -1082.7018217012803)"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(key_b_word, key_b_wrap), score =keyword_break_mp(c4b)\n",
+    "(key_b_word, key_b_wrap), score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "the french maybe your allies but they are not your friends they plan to infiltrate the rat i lines and to try to turn the high value targets for themselves they have a particular interest in nazi scientists from the die alchemist en project if you want to break the reichs doktor network before they can do so take care not to share any intelligence with them you have been warned i think it is time to begin negotiations i have a number in mind and i think once you know what i am offering you will find it very reasonable as a sign of good faith ioffer you the following information one of the local rat i line coordinators will be leaving the us sector tomorrow night in a black limousine under the backseat of his car you will find hidden a juniors s officer who is trying to escape and in the trunk you will find a number of papers relating to stolen artworks that he hopes to trade to the french for his freedom you might want to consider carefully whether you can trust your friend charlie with this information after all her husband francois is french\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(' '.join(segment(sanitise(keyword_decipher(c4b, key_b_word, wrap_alphabet=key_b_wrap)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'reanimtsuvwxyzbcdfghjklopq'"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "keyword_cipher_alphabet_of(key_a_word, wrap_alphabet=key_a_wrap)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('firzuyhgjkmopqatlnesvwxbcd', -2435.9305949573036)"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "monoalphabetic_break_hillclimbing(c4a, \n",
+    "            plain_alphabet=keyword_cipher_alphabet_of(key_a_word, wrap_alphabet=key_a_wrap),\n",
+    "            fitness=Ptrigrams)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/2015/2015-challenge5.ipynb b/2015/2015-challenge5.ipynb
new file mode 100644 (file)
index 0000000..299bedb
--- /dev/null
@@ -0,0 +1,140 @@
+{
+ "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.keyword_cipher import *\n",
+    "from cipher.vigenere import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "\n",
+    "c5a = open('5a.ciphertext').read()\n",
+    "c5b = open('5b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('cornfield', <KeywordWrapAlphabet.from_largest: 3>), -1557.5551917175146)"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(key_a_word, key_a_wrap), score = keyword_break_mp(c5a)\n",
+    "(key_a_word, key_a_wrap), score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "harry, i checked out who transcribed the radio transmission like you asked. it was a junior cipher clerk in room 5. i would have offered to set up a meeting with her, but she has disappeared and hasn’t been seen since last friday. the marines saw her leave at her usual time, and she was booked out for some leave on monday and tuesday so no one noticed she was missing until today. we sent an officer out to her usual haunts and i will get back to you if we find anything. what made you ask? did you have a reason to believe she was involved in something? \n",
+      "\n",
+      "i took another look at the messages. were you referring to the typos? the word ratlines keeps being spelt as ratilines. is that important? what did you mean about our source being close to home? \n",
+      "\n",
+      "also did some digging about the reichsdoktor. seems you were right and it refers to an underground nazi organisation dedicated to rebuilding the reich. maybe they think of it as healing? a bunch of rich nazi sympathisers took over the ratlines from a group of ss officers who set them up at the tail of the war and have been active in shipping scientists, engineers and soldiers to towns across south america. if our source has inside information then maybe we could intercept the lines and pick up some of the high value targets the french are after. what was “die alchemisten project”? \n",
+      "\n",
+      "the enclosed message was handed to the marines, but they didn’t get a name. initial analysis shows it must be a vigenere cipher with period two so it should be reasonably straightforward to crack. \n",
+      "\n",
+      "all the best, charlie \n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(keyword_decipher(c5a, key_a_word, wrap_alphabet=key_a_wrap))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('de', -885.6842458313828)"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score = vigenere_frequency_break(c5b, max_key_length=2)\n",
+    "key_b, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "the first item in our little auction will be the location of a safehouse in the uk sector of berlin it is a minor stopover on the rat lines but you never know you might get lucky and find someone interesting hiding there at the very least you will inconvenience the reichs doktor if you take possession of it how much would that be worth to you do i hear a bid of five hundred thousand francs from our french friends perhaps the british would pay more or maybe they can not afford to i wonder how they feel about that perhaps you should ask them if you want to outbid your so called friends then leave the money in unmarked treasury bills in locker at the far end of the platform in friedrichstrasse i will leave the details in locker you will find the key in do not try to double cross me it will not work and our little game will end before it has even properly begun\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(' '.join(segment(sanitise(vigenere_decipher(sanitise(c5b), key_b)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/2015/2015-challenge6.ipynb b/2015/2015-challenge6.ipynb
new file mode 100644 (file)
index 0000000..33b5b7b
--- /dev/null
@@ -0,0 +1,294 @@
+{
+ "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.keyword_cipher import *\n",
+    "from cipher.vigenere import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "\n",
+    "c6a = sanitise(open('6a.ciphertext').read())\n",
+    "c6b = sanitise(open('6b.ciphertext').read())"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('hammering', <KeywordWrapAlphabet.from_largest: 3>), -2247.716859509375)"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(key_a_word, key_a_wrap), score = keyword_break_mp(c6a)\n",
+    "(key_a_word, key_a_wrap), score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "freslitiacehartaypoinseailinthareagevtiaeceyiaepptestwboarinartayptwmthhegthctpifktwupenwinartasenhfsipaodartsewiomthhegtpstaayunliktlyfoinfiwtnfthoidigustyousjuniosfiprtsfltskcehinvolvtwmigrabtcosarfrtfkingrtsbefkgsounwenwbenkeffounahareaihellimtenacrtniheiwarthousftcehflohtaoromtbuaarinkingebouaiaiemnoahustiamekthhtnhtaoarinkhrtceharthousftartmthhegthhaillkttpfomingenwiemguthhingareahrtrehgonthoartstmuhabthomtoartshousftdosousinatlligtnfthomtaringihboartsingmtebouaartaontodartmthhegthcrywothousenaegonihakttpaeunainguhebouaousellithiaihnoaliktartaringhctestbtingehktwaobiwdosestaringhctestliktlyaoriwtdsomontenoartsedatsellenyceyidolloctwontodousdstnfrfollteguthaodsitwsifrhasehhtenwceafrtwrtsasyaopifkupartktydsomlofktshttmhaorevtbttnefonifoulwnaflteslyhttcreacehgoingonbuahrtwiwnahttmaobtebltaooptnlofktsenwltdaobviouhlyuphtaedatshrtrewgontiaookelookealofktsiarehedelhtbefkhoiemguthhingartmontycehaektnbuanoaringpsoviwtwintxfrengtfoulwyouwigesounwciaryousfonaefahinartbsiaihrenwsuhhientmbehhithenwhttidartyestgtaaingarthemthosaodfommunifeaionhmeybtyoufoulwcesnartmbyartceywitelfrtmihatnpsojtfacehartfowtnemtdosartnezieaombombtddosairewesuninciarartmwusingartcescrtnctctstasyingaokttpartisrenwhoddartrtevyceatshupplystmtmbtsartbombinginvtmoskareacehuhosseartsousnoswifellithenyceyiaihhaillaophtfstahoartdefaouspsoaegonihaknochebouaiaihhignidifenaihuhptfaartktyaoarihcroltmyhatsylithinartisiwtnaiayidctkntccroartyctstcoskingdosctmigrabtebltaodigustouacreaartyestupaoontlehaaringefaingonerunfriaookelookeahomtodartdstnfrwtewwsophedatsartdsitwsifrhasehhtinfiwtnaenwdounwarteaaefrtwfommunifeaionirevtnarewaimtaofsefkiabuaiarinkiameybtevigtntstegeinbuairevtnarewefrenftaoasybebbegthasifkoniaytagivtiaaoyousblefkfrembtsenwhttcreaartyfenmektodiaellartbtharessy\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(keyword_decipher(c6a, key_a_word, wrap_alphabet=key_a_wrap))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'icrdvsfshmrghcfhpzysxdrhsvsxfghcrhnrkfshrmrpshrzzfrdflayhcsxhcfhpzflwfggrnfgmfzsiufljzrxlsxhcfhdrxgidszhyehcfdrlsywfggrnfzdfhhpjxvsufvpiysxislfxifgysesnjdfpyjdtjxsydiszcfdivfdumrgsxkyvkflwsnchafmydhcicfiusxncfdariundyjxlrxlarxuriiyjxhghcrhsgrvvswfrxhmcfxsgrslhcfgyjdifmrgivygfhycywfajhhcsxusxnrayjhshsrwxyhgjdfshwrufggfxgfhyhcsxugcfmrghcfgyjdifhcfwfggrnfgghsvvuffziywsxnrxlsrwnjfggsxnhcrhgcfcrgnyxfgyhcfdfwjghafgywfyhcfdgyjdifeydyjdsxhfvvsnfxifgywfhcsxnsgayhcfdsxnwfrayjhhcfhyxfyehcfwfggrnfgmcplyfgyjdrxhrnyxsghuffzhrjxhsxnjgrayjhyjdrvvsfgshsgxyhvsufhcfhcsxngmfrdfafsxnrguflhyasleydrdfhcsxngmfrdfvsufvphycslfedywyxfrxyhcfdrehfdrvvrxpmrpseyvvymflyxfyeyjdedfxiciyvvfrnjfghyedsfldsicghdrggfrxlmrhicflcfdhdphyzsiujzhcfufpedywvyiufdgffwghycrkfaffxriyxsiyjvlxhivfrdvpgffmcrhmrgnysxnyxajhgcflslxhgffwhyafravfhyyzfxvyiufdrxlvfehyaksyjgvpjzgfhrehfdgcfcrlnyxfshyyurvyyurhvyiufdshcrgrervgfariugysrwnjfggsxnhcfwyxfpmrghrufxajhxyhcsxnzdykslflsxfoicrxnfiyjvlpyjlsnrdyjxlmshcpyjdiyxhrihgsxhcfadshsgcrxldjggsrxfwarggsfgrxlgffsehcfprdfnfhhsxnhcfgrwfgydhyeiywwjxsirhsyxgwrpafpyjiyjvlmrdxhcfwaphcfmrplsfrvicfwsghfxzdytfihmrghcfiylfxrwfeydhcfxrqsrhywaywafeeydhscrlrdjxsxmshchcfwljdsxnhcfmrdmcfxmfmfdfhdpsxnhyuffzhcfsdcrxlgyeehcfcfrkpmrhfdgjzzvpdfwfwafdhcfaywasxnsxkfwyduhcrhmrgjgyddrhcfdyjdxydlsirvvsfgrxpmrpshsgghsvvhyzgfidfhgyhcferihyjdzdyhrnyxsghuxymgrayjhshsggsnxsesirxhsgjgzfihhcfufphyhcsgmcyvfwpghfdpvsfgsxhcfsdslfxhshpsemfuxfmmcyhcfpmfdfmydusxneydmfwsnchafravfhyesnjdfyjhmcrhhcfprdfjzhyyxfvrghhcsxnrihsxnyxrcjxicshyyurvyyurhgywfyehcfedfxiclfrlldyzgrehfdhcfedsfldsicghdrggfsxislfxhrxleyjxlhcfrhhricfliywwjxsirhsyxscrkfxhcrlhswfhyidriushajhshcsxushwrpafrksnfxfdfrnrsxajhscrkfxhcrlricrxifhyhdparaarnfghdsiuyxshpfhnskfshhypyjdavriuicrwafdrxlgffmcrhhcfpirxwrufyeshrvvhcfafghcrddp'"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c6a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'CHARLIE IT WAS THE TYPO IN RAT I LINES THAT GAVE IT AWAY IT APPEARED BOTH IN THE TYPED MESSAGES WE PICKED UP AND IN THE TRANSCRIPT OF THE RADIO MESSAGE PRETTY UNLIKELY COINCIDENCE SO I FIGURE YOUR JUNIOR CIPHER CLERK WAS INVOLVED MIGHT BE WORTH CHECKING HER BACKGROUND AND BANK ACCOUNTS THAT IS ALL I MEANT WHEN I SAID THE SOURCE WAS CLOSE TO HOME BUT THINKING ABOUT IT I AM NOT SURE IT MAKES SENSE TO THINK SHE WAS THE SOURCE THE MESSAGES STILL KEEP COMING AND I AM GUESSING THAT SHE HAS GONE SO THERE MUST BE SOME OTHER SOURCE FOR OUR INTELLIGENCE SOMETHING IS BOTHERING ME ABOUT THE TONE OF THE MESSAGES WHY DOES OUR ANTAGONIST KEEP TAUNTING US ABOUT OUR ALLIES IT IS NOT LIKE THE THINGS WE ARE BEING ASKED TO BID FOR ARE THINGS WE ARE LIKELY TO HIDE FROM ONE ANOTHER AFTER ALL ANYWAY I FOLLOWED ONE OF OUR FRENCH COLLEAGUES TO FRIEDRICHSTRASSE AND WATCHED HER TRY TO PICKUP THE KEY FROM LOCKER SEEMS TO HAVE BEEN A CON I COULDNT CLEARLY SEE WHAT WAS GOING ON BUT SHE DIDNT SEEM TO BE ABLE TO OPEN LOCKER AND LEFT OBVIOUSLY UPSET AFTER SHE HAD GONE I TOOK A LOOK AT LOCKER IT HAS A FALSE BACK SO I AM GUESSING THE MONEY WAS TAKEN BUT NOTHING PROVIDED IN EXCHANGE COULD YOU DIG AROUND WITH YOUR CONTACTS IN THE BRITISH AND RUSSIAN EMBASSIES AND SEE IF THEY ARE GETTING THE SAME SORT OF COMMUNICATIONS MAYBE YOU COULD WARN THEM BY THE WAY DIE ALCHEMIST EN PROJECT WAS THE CODENAME FOR THE NAZI ATOM BOMB EFFORT I HAD A RUN IN WITH THEM DURING THE WAR WHEN WE WERE TRYING TO KEEP THEIR HANDS OFF THE HEAVY WATER SUPPLY REMEMBER THE BOMBING IN VE MORK THAT WAS US OR RATHER OUR NORDIC ALLIES ANYWAY IT IS STILL TOP SECRET SO THE FACT OUR PROTAGONIST KNOWS ABOUT IT IS SIGNIFICANT I SUSPECT THE KEY TO THIS WHOLE MYSTERY LIES IN THEIR IDENTITY IF WE KNEW WHO THEY WERE WORKING FOR WE MIGHT BE ABLE TO FIGURE OUT WHAT THEY ARE UP TO ONE LAST THING ACTING ON A HUNCH I TOOK A LOOK AT SOME OF THE FRENCH DEAD DROPS AFTER THE FRIEDRICHSTRASSE INCIDENT AND FOUND THE ATTACHED COMMUNICATION I HAVENT HAD TIME TO CRACK IT BUT I THINK IT MAYBE AVI GENERE AGAIN BUT I HAVENT HAD A CHANCE TO TRY BABBAGE STRICK ON IT YET GIVE IT TO YOUR BLACK CHAMBER AND SEE WHAT THEY CAN MAKE OF IT ALL THE BEST HARRY'"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "translations = {'c': 'H', 'r': 'A', 'd': 'R', 'p': 'Y', 'i': 'C', 'd': 'R', 'v': 'L', 's': 'I', 'f': 'E', \n",
+    "                'h': 'T', 'a': 'B', 'g': 'S', 'm': 'W', 'y': 'O', 'z': 'P', 'n': 'G', 'j': 'U', 't': 'J',\n",
+    "               'x': 'N', 'k': 'V', 'l': 'D', 'w': 'M', 'u': 'K', 'e': 'F', 'q': 'Z', 'o': 'X'}\n",
+    "translation_table = ''.maketrans(translations)\n",
+    "plaintext = ' '.join(segment(c6a.translate(translation_table)))\n",
+    "plaintext"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'BHRFESTCUVDWGXYZAIJKLMNOP'"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "''.join(translations[l] for l in sorted(translations))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'railfencstuvwxyzdghjkmopq'"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "inverted_translations = {translations[a]: a for a in translations}\n",
+    "''.join(inverted_translations[l] for l in sorted(inverted_translations))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'railfencstuvwxyzbdghjkmopq'"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "keyword_cipher_alphabet_of('railfences', wrap_alphabet=KeywordWrapAlphabet.from_last)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "charlie it was the typo in rat i lines that gave it away it appeared both in the typed messages we picked up and in the transcript of the radio message pretty unlikely coincidence so i figure your junior cipher clerk was involved might be worth checking her background and bank accounts that is all i meant when i said the source was close to home but thinking about it i am not sure it makes sense to think she was the source the messages still keep coming and i am guessing that she has gone so there must be some other source for our intelligence something is bothering me about the tone of the messages why does our antagonist keep taunting us about our allies it is not like the things we are being asked to bid for are things we are likely to hide from one another after all anyway i followed one of our french colleagues to friedrichstrasse and watched her try to pickup the key from locker seems to have been a con i couldnt clearly see what was going on but she didnt seem to be able to open locker and left obviously upset after she had gone i took a look at locker it has a false back so i am guessing the money was taken but nothing provided in exchange could you dig around with your contacts in the british and russian embassies and see if they are getting the same sort of communications maybe you could warn them by the way die alchemist en project was the codename for the nazi atom bomb effort i had a run in with them during the war when we were trying to keep their hands off the heavy water supply remember the bombing in ve mork that was us or rather our nordic allies anyway it is still top secret so the fact our protagonist knows about it is significant i suspect the key to this whole mystery lies in their identity if we knew who they were working for we might be able to figure out what they are up to one last thing acting on a hunch i took a look at some of the french dead drops after the friedrichstrasse incident and found the attached communication i havent had time to crack it but i think it maybe avi genere again but i havent had a chance to try babbage strick on it yet give it to your black chamber and see what they can make of it all the best harry\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(' '.join(segment(keyword_decipher(c6a, 'railfences', wrap_alphabet=KeywordWrapAlphabet.from_last))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('kremlin', -908.5396262316657)"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score = vigenere_frequency_break(c6b)\n",
+    "key_b, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "the americans have robbed you rather than trying to outbid you they got to the lockers first and arranged to steal your money and the valuable intelligence i provided for you they can not be trusted none of your allies can be trusted they believe that they can cheat you but they do not understand that you can only cheat in a game and this is not a game if you try to playa game of chess like your allies we will find ourselves in a stalemate you have been warned so let us start again i can let you have the address of another safehouse at a small discount on our original price and i will include the identity of a british double agent working in your embassy shall we say four hundred thousand francs to be paid directly to an account of my choosing if you want to know more about the treachery of your so called friends then let us meet in the park by the british embassy on friday at eleven\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(' '.join(segment(sanitise(vigenere_decipher(sanitise(c6b), key_b)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('railfencstuvwxyzbdghjkmopq', -5965.858211099189)"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "simulated_annealing_break(c6a, fitness=Ptrigrams)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'charlieitwasthetypoinratilinesthatgaveitawayitappearedbothinthetypedmessageswepickedupandinthetranscriptoftheradiomessageprettyunlikelycoincidencesoifigureyourjuniorcipherclerkwasinvolvedmightbeworthcheckingherbackgroundandbankaccountsthatisallimeantwhenisaidthesourcewasclosetohomebutthinkingaboutitiamnotsureitmakessensetothinkshewasthesourcethemessagesstillkeepcomingandiamguessingthatshehasgonesotheremustbesomeothersourceforourintelligencesomethingisbotheringmeaboutthetoneofthemessageswhydoesourantagonistkeeptauntingusaboutouralliesitisnotlikethethingswearebeingaskedtobidforarethingswearelikelytohidefromoneanotherafterallanywayifollowedoneofourfrenchcolleaguestofriedrichstrasseandwatchedhertrytopickupthekeyfromlockerseemstohavebeenaconicouldntclearlyseewhatwasgoingonbutshedidntseemtobeabletoopenlockerandleftobviouslyupsetaftershehadgoneitookalookatlockerithasafalsebacksoiamguessingthemoneywastakenbutnothingprovidedinexchangecouldyoudigaroundwithyourcontactsinthebritishandrussianembassiesandseeiftheyaregettingthesamesortofcommunicationsmaybeyoucouldwarnthembythewaydiealchemistenprojectwasthecodenameforthenaziatombombeffortihadaruninwiththemduringthewarwhenweweretryingtokeeptheirhandsofftheheavywatersupplyrememberthebombinginvemorkthatwasusorratherournordicalliesanywayitisstilltopsecretsothefactourprotagonistknowsaboutitissignificantisuspectthekeytothiswholemysteryliesintheiridentityifweknewwhotheywereworkingforwemightbeabletofigureoutwhattheyareuptoonelastthingactingonahunchitookalookatsomeofthefrenchdeaddropsafterthefriedrichstrasseincidentandfoundtheattachedcommunicationihaventhadtimetocrackitbutithinkitmaybeavigenereagainbutihaventhadachancetotrybabbagestrickonityetgiveittoyourblackchamberandseewhattheycanmakeofitallthebestharry'"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "keyword_decipher(c6a, 'railfencstuvwxyzbdghjkmopq')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/2015/2015-challenge7.ipynb b/2015/2015-challenge7.ipynb
new file mode 100644 (file)
index 0000000..dcfa205
--- /dev/null
@@ -0,0 +1,1613 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.column_transposition import *\n",
+    "from cipher.keyword_cipher import *\n",
+    "from cipher.amsco import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "from support.language_models import *\n",
+    "\n",
+    "c7a = sanitise(open('7a.ciphertext').read())\n",
+    "c7b = sanitise(open('7b.ciphertext').read())"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('annmarie', <KeywordWrapAlphabet.from_largest: 3>), -1865.8708508162845)"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(key_a_word, key_a_wrap), score = keyword_break_mp(c7a)\n",
+    "(key_a_word, key_a_wrap), score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "dhorlieithinkiknacchotisgainganfutineewtadhedkobecthingsfebareirepartcemoyhoveonappartunityhereidhedkewthedipherdlerksfodkgraunwonwitturnsautsheischiterussionherbomilylebtmasdacinfutshehosrelotivesinthegulogotpermshedleorlyhosnalavebarthesavietgavernmentsaiomstillnatsurechashecoscarkingbarfutithinkthisiskeyintelligendeinthemeontimeihovefeencotdhingthefritstheyseemtahovefeenindantodtcithaurbrienwsinthereidhswaktaronwtheyinturnhovefeencotdhingthebrendhitseemslikeceoreollcarkingogoinstaneonatherchidhireollywiwntexpedtonwgivenchotcereowinthebrendhwadumentlostceekiwantthinkthotisodaindiwendemyacnguessisthottherussionsknacchotisgainganonwthotaurfesthapeabundaveringitistafreokintatheirhqonwtrytabinwsamethingthereunbartunotelyoddarwingtamysaurdeyuritheyhovetokentausingonecdiphersalitoirebarordhivestarogeabtapsedretbilessaevenibcemonogetasteoltherelevontbileitcilltokeolatabdamputingtafreokthedipheriottodhofriebmessogebramyuriendryptewusingonomsdadipherkeycarwlengthissixinchidhhewesdrifesthedipheritisverydleversimpletaimplementfutoweviltadrodkonwmyanehapeisthotcedonolsabinwthedipherkeychileinthehqarotleostportabitiplontaenterintcaceeksanwedemfersixteenththerussionsorehastingolorgeprapogonwoeventosportabtheinternotianolefouousstellungcithleowingpalitfuramemfersinottenwondemastabthesedurityteomcillfeaddupiewciththotonwhqseduritycillferelotivelylightcithludkicillgetinonwautciththebilesceneewthotnightonwthencedongettathefattamabthechalereidhswaktarstrotogemollthefesthorry\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(keyword_decipher(c7a, key_a_word, wrap_alphabet=key_a_wrap))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'A': 'a',\n",
+       " 'B': 'o',\n",
+       " 'C': 'p',\n",
+       " 'D': 'q',\n",
+       " 'E': 'f',\n",
+       " 'F': 'r',\n",
+       " 'G': 's',\n",
+       " 'H': 't',\n",
+       " 'I': 'e',\n",
+       " 'J': 'u',\n",
+       " 'K': 'v',\n",
+       " 'L': 'w',\n",
+       " 'M': 'c',\n",
+       " 'N': 'b',\n",
+       " 'O': 'x',\n",
+       " 'P': 'y',\n",
+       " 'Q': 'z',\n",
+       " 'R': 'd',\n",
+       " 'S': 'g',\n",
+       " 'T': 'h',\n",
+       " 'U': 'i',\n",
+       " 'V': 'j',\n",
+       " 'W': 'k',\n",
+       " 'X': 'l',\n",
+       " 'Y': 'm',\n",
+       " 'Z': 'n'}"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "trans_a = {p.upper(): c for p, c in zip(keyword_cipher_alphabet_of(key_a_word, wrap_alphabet=key_a_wrap), string.ascii_lowercase, )}\n",
+    "trans_a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'charlie i think i know what is going on but i need to check a few things before i report we may have an opportunity here i checked the cipher clerks background and it turns out she is white russian her family left moscow in but she has relatives in the gulag at perm she clearly has no love for the soviet government so i am still not sure who she was working for but i think this is key intelligence in the meantime i have been watching the brits they seem to have been in contact with our friends in the reichs doktor and they in turn have been watching the french it seems like we are all working against one another which i really didnt expect and given what we read in the french document last week i dont think that is a coincidence my own guess is that the russians know what is going on and that our best hope of uncovering it is to break into their hq and try to find something there unfortunately according to my source yuri they have taken to using a new cipher solitaire for archive storage of top secret files so even if we manage to steal the relevant file it will take alot of computing to break the cipher i attach a brief message from yuri encrypted using an amsco cipher keyword length is six in which he describes the cipher it is very clever simple to implement but a devil to crack and my one hope is that we can also find the cipher key while in the hq or atleast part of it i plan to enter in two weeks on december sixteenth the russians are hosting a large propaganda event as part of the international ebau ausstellung with leading politburo members in attendance most of the security team will be occupied with that and hq security will be relatively light with luck i will get in and out with the files we need that night and then we can get to the bottom of the whole reichs doktor stratagem all the best harry'"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "translations = {\n",
+    " 'A': 'o',\n",
+    " 'B': 'a',\n",
+    " 'C': 'p',\n",
+    " 'D': 'q',\n",
+    " 'E': 'b',\n",
+    " 'F': 'r',\n",
+    " 'G': 's',\n",
+    " 'H': 't',\n",
+    " 'I': 'e',\n",
+    " 'J': 'u',\n",
+    " 'K': 'v',\n",
+    " 'L': 'd',\n",
+    " 'M': 'w',\n",
+    " 'N': 'f',\n",
+    " 'O': 'x',\n",
+    " 'P': 'y',\n",
+    " 'Q': 'z',\n",
+    " 'R': 'c',\n",
+    " 'S': 'g',\n",
+    " 'T': 'h',\n",
+    " 'U': 'i',\n",
+    " 'V': 'j',\n",
+    " 'W': 'k',\n",
+    " 'X': 'l',\n",
+    " 'Y': 'm',\n",
+    " 'Z': 'n'}\n",
+    "translation_table = ''.maketrans(translations)\n",
+    "plaintext = ' '.join(segment(c7a.upper().translate(translation_table)))\n",
+    "plaintext"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'oapqbrsteuvdwfxyzcghijklmn'"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "''.join(translations[l] for l in sorted(translations))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'BERLINSTUVWXYZACDFGHJKMOPQ'"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "inverted_translations = {translations[a]: a for a in translations}\n",
+    "''.join(inverted_translations[l] for l in sorted(inverted_translations))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'berlinstuvwxyzacdfghjkmopq'"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "keyword_cipher_alphabet_of('berlin', wrap_alphabet=KeywordWrapAlphabet.from_largest)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('berlinstudwxyzacvfghjkmopq', -5028.125895049484)"
+      ]
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "k7a, fit7a = simulated_annealing_break(c7a, fitness=Ptrigrams)\n",
+    "k7a, fit7a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "charlie i think i know what is going on but i need to check a few things before i report we may have\n",
+      "an opportunity here i checked the cipher clerks background and it turns out she is white russian her\n",
+      "family left moscow in but she has relatives in the gulag at perm she clearly has no love for the\n",
+      "soviet government so i am still not sure who she was working for but i think this is key\n",
+      "intelligence in the meantime i have been watching the brits they seem to have been in contact with\n",
+      "our friends in the reichs doktor and they in turn have been watching the french it seems like we are\n",
+      "all working against one another which i really didnt expect and given what we read in the french\n",
+      "document last week i dont think that is a coincidence my own guess is that the russians know what is\n",
+      "going on and that our best hope of uncovering it is to break into their hj and try to find something\n",
+      "there unfortunately according to my source yuri they have taken to using a new cipher solitaire for\n",
+      "archive storage of top secret files so even if we manage to steal the relevant file it will take\n",
+      "alot of computing to break the cipher i attach a brief message from yuri encrypted using an amsco\n",
+      "cipher keyword length is six in which he describes the cipher it is very clever simple to implement\n",
+      "but a devil to crack and my one hope is that we can also find the cipher key while in the hj or\n",
+      "atleast part of it i plan to enter in two weeks on december sixteenth the russians are hosting a\n",
+      "large propaganda event as part of the international ebau ausstellung with leading politburo members\n",
+      "in attendance most of the security team will be occupied with that and hj security will be\n",
+      "relatively light with luck i will get in and out with the files we need that night and then we can\n",
+      "get to the bottom of the whole reichs doktor stratagem all the best harry\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(keyword_decipher(c7a, k7a)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "charlie i think i know what is going on but i need to check a few things before i report we may have an opportunity here i checked the cipher clerks background and it turns out she is white russian her family left moscow in but she has relatives in the gulag at perm she clearly has no love for the soviet government so i am still not sure who she was working for but i think this is key intelligence in the meantime i have been watching the brits they seem to have been in contact with our friends in the reichs doktor and they in turn have been watching the french it seems like we are all working against one another which i really didnt expect and given what we read in the french document last week i dont think that is a coincidence my own guess is that the russians know what is going on and that our best hope of uncovering it is to break into their hq and try to find something there unfortunately according to my source yuri they have taken to using a new cipher solitaire for archive storage of top secret files so even if we manage to steal the relevant file it will take alot of computing to break the cipher i attach a brief message from yuri encrypted using an amsco cipher keyword length is six in which he describes the cipher it is very clever simple to implement but a devil to crack and my one hope is that we can also find the cipher key while in the hq or atleast part of it i plan to enter in two weeks on december sixteenth the russians are hosting a large propaganda event as part of the international ebau ausstellung with leading politburo members in attendance most of the security team will be occupied with that and hq security will be relatively light with luck i will get in and out with the files we need that night and then we can get to the bottom of the whole reichs doktor stratagem all the best harry\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(' '.join(segment(keyword_decipher(c7a, 'berlin', wrap_alphabet=KeywordWrapAlphabet.from_largest))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{(0, 1, 2, 3, 4, 5): (0, 1, 2, 3, 4, 5),\n",
+       " (0, 1, 2, 3, 5, 4): (0, 1, 2, 3, 5, 4),\n",
+       " (0, 1, 2, 4, 3, 5): (0, 1, 2, 4, 3, 5),\n",
+       " (0, 1, 2, 4, 5, 3): (0, 1, 2, 4, 5, 3),\n",
+       " (0, 1, 2, 5, 3, 4): (0, 1, 2, 5, 3, 4),\n",
+       " (0, 1, 2, 5, 4, 3): (0, 1, 2, 5, 4, 3),\n",
+       " (0, 1, 3, 2, 4, 5): (0, 1, 3, 2, 4, 5),\n",
+       " (0, 1, 3, 2, 5, 4): (0, 1, 3, 2, 5, 4),\n",
+       " (0, 1, 3, 4, 2, 5): (0, 1, 3, 4, 2, 5),\n",
+       " (0, 1, 3, 4, 5, 2): (0, 1, 3, 4, 5, 2),\n",
+       " (0, 1, 3, 5, 2, 4): (0, 1, 3, 5, 2, 4),\n",
+       " (0, 1, 3, 5, 4, 2): (0, 1, 3, 5, 4, 2),\n",
+       " (0, 1, 4, 2, 3, 5): (0, 1, 4, 2, 3, 5),\n",
+       " (0, 1, 4, 2, 5, 3): (0, 1, 4, 2, 5, 3),\n",
+       " (0, 1, 4, 3, 2, 5): (0, 1, 4, 3, 2, 5),\n",
+       " (0, 1, 4, 3, 5, 2): (0, 1, 4, 3, 5, 2),\n",
+       " (0, 1, 4, 5, 2, 3): (0, 1, 4, 5, 2, 3),\n",
+       " (0, 1, 4, 5, 3, 2): (0, 1, 4, 5, 3, 2),\n",
+       " (0, 1, 5, 2, 3, 4): (0, 1, 5, 2, 3, 4),\n",
+       " (0, 1, 5, 2, 4, 3): (0, 1, 5, 2, 4, 3),\n",
+       " (0, 1, 5, 3, 2, 4): (0, 1, 5, 3, 2, 4),\n",
+       " (0, 1, 5, 3, 4, 2): (0, 1, 5, 3, 4, 2),\n",
+       " (0, 1, 5, 4, 2, 3): (0, 1, 5, 4, 2, 3),\n",
+       " (0, 1, 5, 4, 3, 2): (0, 1, 5, 4, 3, 2),\n",
+       " (0, 2, 1, 3, 4, 5): (0, 2, 1, 3, 4, 5),\n",
+       " (0, 2, 1, 3, 5, 4): (0, 2, 1, 3, 5, 4),\n",
+       " (0, 2, 1, 4, 3, 5): (0, 2, 1, 4, 3, 5),\n",
+       " (0, 2, 1, 4, 5, 3): (0, 2, 1, 4, 5, 3),\n",
+       " (0, 2, 1, 5, 3, 4): (0, 2, 1, 5, 3, 4),\n",
+       " (0, 2, 1, 5, 4, 3): (0, 2, 1, 5, 4, 3),\n",
+       " (0, 2, 3, 1, 4, 5): (0, 2, 3, 1, 4, 5),\n",
+       " (0, 2, 3, 1, 5, 4): (0, 2, 3, 1, 5, 4),\n",
+       " (0, 2, 3, 4, 1, 5): (0, 2, 3, 4, 1, 5),\n",
+       " (0, 2, 3, 4, 5, 1): (0, 2, 3, 4, 5, 1),\n",
+       " (0, 2, 3, 5, 1, 4): (0, 2, 3, 5, 1, 4),\n",
+       " (0, 2, 3, 5, 4, 1): (0, 2, 3, 5, 4, 1),\n",
+       " (0, 2, 4, 1, 3, 5): (0, 2, 4, 1, 3, 5),\n",
+       " (0, 2, 4, 1, 5, 3): (0, 2, 4, 1, 5, 3),\n",
+       " (0, 2, 4, 3, 1, 5): (0, 2, 4, 3, 1, 5),\n",
+       " (0, 2, 4, 3, 5, 1): (0, 2, 4, 3, 5, 1),\n",
+       " (0, 2, 4, 5, 1, 3): (0, 2, 4, 5, 1, 3),\n",
+       " (0, 2, 4, 5, 3, 1): (0, 2, 4, 5, 3, 1),\n",
+       " (0, 2, 5, 1, 3, 4): (0, 2, 5, 1, 3, 4),\n",
+       " (0, 2, 5, 1, 4, 3): (0, 2, 5, 1, 4, 3),\n",
+       " (0, 2, 5, 3, 1, 4): (0, 2, 5, 3, 1, 4),\n",
+       " (0, 2, 5, 3, 4, 1): (0, 2, 5, 3, 4, 1),\n",
+       " (0, 2, 5, 4, 1, 3): (0, 2, 5, 4, 1, 3),\n",
+       " (0, 2, 5, 4, 3, 1): (0, 2, 5, 4, 3, 1),\n",
+       " (0, 3, 1, 2, 4, 5): (0, 3, 1, 2, 4, 5),\n",
+       " (0, 3, 1, 2, 5, 4): (0, 3, 1, 2, 5, 4),\n",
+       " (0, 3, 1, 4, 2, 5): (0, 3, 1, 4, 2, 5),\n",
+       " (0, 3, 1, 4, 5, 2): (0, 3, 1, 4, 5, 2),\n",
+       " (0, 3, 1, 5, 2, 4): (0, 3, 1, 5, 2, 4),\n",
+       " (0, 3, 1, 5, 4, 2): (0, 3, 1, 5, 4, 2),\n",
+       " (0, 3, 2, 1, 4, 5): (0, 3, 2, 1, 4, 5),\n",
+       " (0, 3, 2, 1, 5, 4): (0, 3, 2, 1, 5, 4),\n",
+       " (0, 3, 2, 4, 1, 5): (0, 3, 2, 4, 1, 5),\n",
+       " (0, 3, 2, 4, 5, 1): (0, 3, 2, 4, 5, 1),\n",
+       " (0, 3, 2, 5, 1, 4): (0, 3, 2, 5, 1, 4),\n",
+       " (0, 3, 2, 5, 4, 1): (0, 3, 2, 5, 4, 1),\n",
+       " (0, 3, 4, 1, 2, 5): (0, 3, 4, 1, 2, 5),\n",
+       " (0, 3, 4, 1, 5, 2): (0, 3, 4, 1, 5, 2),\n",
+       " (0, 3, 4, 2, 1, 5): (0, 3, 4, 2, 1, 5),\n",
+       " (0, 3, 4, 2, 5, 1): (0, 3, 4, 2, 5, 1),\n",
+       " (0, 3, 4, 5, 1, 2): (0, 3, 4, 5, 1, 2),\n",
+       " (0, 3, 4, 5, 2, 1): (0, 3, 4, 5, 2, 1),\n",
+       " (0, 3, 5, 1, 2, 4): (0, 3, 5, 1, 2, 4),\n",
+       " (0, 3, 5, 1, 4, 2): (0, 3, 5, 1, 4, 2),\n",
+       " (0, 3, 5, 2, 1, 4): (0, 3, 5, 2, 1, 4),\n",
+       " (0, 3, 5, 2, 4, 1): (0, 3, 5, 2, 4, 1),\n",
+       " (0, 3, 5, 4, 1, 2): (0, 3, 5, 4, 1, 2),\n",
+       " (0, 3, 5, 4, 2, 1): (0, 3, 5, 4, 2, 1),\n",
+       " (0, 4, 1, 2, 3, 5): (0, 4, 1, 2, 3, 5),\n",
+       " (0, 4, 1, 2, 5, 3): (0, 4, 1, 2, 5, 3),\n",
+       " (0, 4, 1, 3, 2, 5): (0, 4, 1, 3, 2, 5),\n",
+       " (0, 4, 1, 3, 5, 2): (0, 4, 1, 3, 5, 2),\n",
+       " (0, 4, 1, 5, 2, 3): (0, 4, 1, 5, 2, 3),\n",
+       " (0, 4, 1, 5, 3, 2): (0, 4, 1, 5, 3, 2),\n",
+       " (0, 4, 2, 1, 3, 5): (0, 4, 2, 1, 3, 5),\n",
+       " (0, 4, 2, 1, 5, 3): (0, 4, 2, 1, 5, 3),\n",
+       " (0, 4, 2, 3, 1, 5): (0, 4, 2, 3, 1, 5),\n",
+       " (0, 4, 2, 3, 5, 1): (0, 4, 2, 3, 5, 1),\n",
+       " (0, 4, 2, 5, 1, 3): (0, 4, 2, 5, 1, 3),\n",
+       " (0, 4, 2, 5, 3, 1): (0, 4, 2, 5, 3, 1),\n",
+       " (0, 4, 3, 1, 2, 5): (0, 4, 3, 1, 2, 5),\n",
+       " (0, 4, 3, 1, 5, 2): (0, 4, 3, 1, 5, 2),\n",
+       " (0, 4, 3, 2, 1, 5): (0, 4, 3, 2, 1, 5),\n",
+       " (0, 4, 3, 2, 5, 1): (0, 4, 3, 2, 5, 1),\n",
+       " (0, 4, 3, 5, 1, 2): (0, 4, 3, 5, 1, 2),\n",
+       " (0, 4, 3, 5, 2, 1): (0, 4, 3, 5, 2, 1),\n",
+       " (0, 4, 5, 1, 2, 3): (0, 4, 5, 1, 2, 3),\n",
+       " (0, 4, 5, 1, 3, 2): (0, 4, 5, 1, 3, 2),\n",
+       " (0, 4, 5, 2, 1, 3): (0, 4, 5, 2, 1, 3),\n",
+       " (0, 4, 5, 2, 3, 1): (0, 4, 5, 2, 3, 1),\n",
+       " (0, 4, 5, 3, 1, 2): (0, 4, 5, 3, 1, 2),\n",
+       " (0, 4, 5, 3, 2, 1): (0, 4, 5, 3, 2, 1),\n",
+       " (0, 5, 1, 2, 3, 4): (0, 5, 1, 2, 3, 4),\n",
+       " (0, 5, 1, 2, 4, 3): (0, 5, 1, 2, 4, 3),\n",
+       " (0, 5, 1, 3, 2, 4): (0, 5, 1, 3, 2, 4),\n",
+       " (0, 5, 1, 3, 4, 2): (0, 5, 1, 3, 4, 2),\n",
+       " (0, 5, 1, 4, 2, 3): (0, 5, 1, 4, 2, 3),\n",
+       " (0, 5, 1, 4, 3, 2): (0, 5, 1, 4, 3, 2),\n",
+       " (0, 5, 2, 1, 3, 4): (0, 5, 2, 1, 3, 4),\n",
+       " (0, 5, 2, 1, 4, 3): (0, 5, 2, 1, 4, 3),\n",
+       " (0, 5, 2, 3, 1, 4): (0, 5, 2, 3, 1, 4),\n",
+       " (0, 5, 2, 3, 4, 1): (0, 5, 2, 3, 4, 1),\n",
+       " (0, 5, 2, 4, 1, 3): (0, 5, 2, 4, 1, 3),\n",
+       " (0, 5, 2, 4, 3, 1): (0, 5, 2, 4, 3, 1),\n",
+       " (0, 5, 3, 1, 2, 4): (0, 5, 3, 1, 2, 4),\n",
+       " (0, 5, 3, 1, 4, 2): (0, 5, 3, 1, 4, 2),\n",
+       " (0, 5, 3, 2, 1, 4): (0, 5, 3, 2, 1, 4),\n",
+       " (0, 5, 3, 2, 4, 1): (0, 5, 3, 2, 4, 1),\n",
+       " (0, 5, 3, 4, 1, 2): (0, 5, 3, 4, 1, 2),\n",
+       " (0, 5, 3, 4, 2, 1): (0, 5, 3, 4, 2, 1),\n",
+       " (0, 5, 4, 1, 2, 3): (0, 5, 4, 1, 2, 3),\n",
+       " (0, 5, 4, 1, 3, 2): (0, 5, 4, 1, 3, 2),\n",
+       " (0, 5, 4, 2, 1, 3): (0, 5, 4, 2, 1, 3),\n",
+       " (0, 5, 4, 2, 3, 1): (0, 5, 4, 2, 3, 1),\n",
+       " (0, 5, 4, 3, 1, 2): (0, 5, 4, 3, 1, 2),\n",
+       " (0, 5, 4, 3, 2, 1): (0, 5, 4, 3, 2, 1),\n",
+       " (1, 0, 2, 3, 4, 5): (1, 0, 2, 3, 4, 5),\n",
+       " (1, 0, 2, 3, 5, 4): (1, 0, 2, 3, 5, 4),\n",
+       " (1, 0, 2, 4, 3, 5): (1, 0, 2, 4, 3, 5),\n",
+       " (1, 0, 2, 4, 5, 3): (1, 0, 2, 4, 5, 3),\n",
+       " (1, 0, 2, 5, 3, 4): (1, 0, 2, 5, 3, 4),\n",
+       " (1, 0, 2, 5, 4, 3): (1, 0, 2, 5, 4, 3),\n",
+       " (1, 0, 3, 2, 4, 5): (1, 0, 3, 2, 4, 5),\n",
+       " (1, 0, 3, 2, 5, 4): (1, 0, 3, 2, 5, 4),\n",
+       " (1, 0, 3, 4, 2, 5): (1, 0, 3, 4, 2, 5),\n",
+       " (1, 0, 3, 4, 5, 2): (1, 0, 3, 4, 5, 2),\n",
+       " (1, 0, 3, 5, 2, 4): (1, 0, 3, 5, 2, 4),\n",
+       " (1, 0, 3, 5, 4, 2): (1, 0, 3, 5, 4, 2),\n",
+       " (1, 0, 4, 2, 3, 5): (1, 0, 4, 2, 3, 5),\n",
+       " (1, 0, 4, 2, 5, 3): (1, 0, 4, 2, 5, 3),\n",
+       " (1, 0, 4, 3, 2, 5): (1, 0, 4, 3, 2, 5),\n",
+       " (1, 0, 4, 3, 5, 2): (1, 0, 4, 3, 5, 2),\n",
+       " (1, 0, 4, 5, 2, 3): (1, 0, 4, 5, 2, 3),\n",
+       " (1, 0, 4, 5, 3, 2): (1, 0, 4, 5, 3, 2),\n",
+       " (1, 0, 5, 2, 3, 4): (1, 0, 5, 2, 3, 4),\n",
+       " (1, 0, 5, 2, 4, 3): (1, 0, 5, 2, 4, 3),\n",
+       " (1, 0, 5, 3, 2, 4): (1, 0, 5, 3, 2, 4),\n",
+       " (1, 0, 5, 3, 4, 2): (1, 0, 5, 3, 4, 2),\n",
+       " (1, 0, 5, 4, 2, 3): (1, 0, 5, 4, 2, 3),\n",
+       " (1, 0, 5, 4, 3, 2): (1, 0, 5, 4, 3, 2),\n",
+       " (1, 2, 0, 3, 4, 5): (1, 2, 0, 3, 4, 5),\n",
+       " (1, 2, 0, 3, 5, 4): (1, 2, 0, 3, 5, 4),\n",
+       " (1, 2, 0, 4, 3, 5): (1, 2, 0, 4, 3, 5),\n",
+       " (1, 2, 0, 4, 5, 3): (1, 2, 0, 4, 5, 3),\n",
+       " (1, 2, 0, 5, 3, 4): (1, 2, 0, 5, 3, 4),\n",
+       " (1, 2, 0, 5, 4, 3): (1, 2, 0, 5, 4, 3),\n",
+       " (1, 2, 3, 0, 4, 5): (1, 2, 3, 0, 4, 5),\n",
+       " (1, 2, 3, 0, 5, 4): (1, 2, 3, 0, 5, 4),\n",
+       " (1, 2, 3, 4, 0, 5): (1, 2, 3, 4, 0, 5),\n",
+       " (1, 2, 3, 4, 5, 0): (1, 2, 3, 4, 5, 0),\n",
+       " (1, 2, 3, 5, 0, 4): (1, 2, 3, 5, 0, 4),\n",
+       " (1, 2, 3, 5, 4, 0): (1, 2, 3, 5, 4, 0),\n",
+       " (1, 2, 4, 0, 3, 5): (1, 2, 4, 0, 3, 5),\n",
+       " (1, 2, 4, 0, 5, 3): (1, 2, 4, 0, 5, 3),\n",
+       " (1, 2, 4, 3, 0, 5): (1, 2, 4, 3, 0, 5),\n",
+       " (1, 2, 4, 3, 5, 0): (1, 2, 4, 3, 5, 0),\n",
+       " (1, 2, 4, 5, 0, 3): (1, 2, 4, 5, 0, 3),\n",
+       " (1, 2, 4, 5, 3, 0): (1, 2, 4, 5, 3, 0),\n",
+       " (1, 2, 5, 0, 3, 4): (1, 2, 5, 0, 3, 4),\n",
+       " (1, 2, 5, 0, 4, 3): (1, 2, 5, 0, 4, 3),\n",
+       " (1, 2, 5, 3, 0, 4): (1, 2, 5, 3, 0, 4),\n",
+       " (1, 2, 5, 3, 4, 0): (1, 2, 5, 3, 4, 0),\n",
+       " (1, 2, 5, 4, 0, 3): (1, 2, 5, 4, 0, 3),\n",
+       " (1, 2, 5, 4, 3, 0): (1, 2, 5, 4, 3, 0),\n",
+       " (1, 3, 0, 2, 4, 5): (1, 3, 0, 2, 4, 5),\n",
+       " (1, 3, 0, 2, 5, 4): (1, 3, 0, 2, 5, 4),\n",
+       " (1, 3, 0, 4, 2, 5): (1, 3, 0, 4, 2, 5),\n",
+       " (1, 3, 0, 4, 5, 2): (1, 3, 0, 4, 5, 2),\n",
+       " (1, 3, 0, 5, 2, 4): (1, 3, 0, 5, 2, 4),\n",
+       " (1, 3, 0, 5, 4, 2): (1, 3, 0, 5, 4, 2),\n",
+       " (1, 3, 2, 0, 4, 5): (1, 3, 2, 0, 4, 5),\n",
+       " (1, 3, 2, 0, 5, 4): (1, 3, 2, 0, 5, 4),\n",
+       " (1, 3, 2, 4, 0, 5): (1, 3, 2, 4, 0, 5),\n",
+       " (1, 3, 2, 4, 5, 0): (1, 3, 2, 4, 5, 0),\n",
+       " (1, 3, 2, 5, 0, 4): (1, 3, 2, 5, 0, 4),\n",
+       " (1, 3, 2, 5, 4, 0): (1, 3, 2, 5, 4, 0),\n",
+       " (1, 3, 4, 0, 2, 5): (1, 3, 4, 0, 2, 5),\n",
+       " (1, 3, 4, 0, 5, 2): (1, 3, 4, 0, 5, 2),\n",
+       " (1, 3, 4, 2, 0, 5): (1, 3, 4, 2, 0, 5),\n",
+       " (1, 3, 4, 2, 5, 0): (1, 3, 4, 2, 5, 0),\n",
+       " (1, 3, 4, 5, 0, 2): (1, 3, 4, 5, 0, 2),\n",
+       " (1, 3, 4, 5, 2, 0): (1, 3, 4, 5, 2, 0),\n",
+       " (1, 3, 5, 0, 2, 4): (1, 3, 5, 0, 2, 4),\n",
+       " (1, 3, 5, 0, 4, 2): (1, 3, 5, 0, 4, 2),\n",
+       " (1, 3, 5, 2, 0, 4): (1, 3, 5, 2, 0, 4),\n",
+       " (1, 3, 5, 2, 4, 0): (1, 3, 5, 2, 4, 0),\n",
+       " (1, 3, 5, 4, 0, 2): (1, 3, 5, 4, 0, 2),\n",
+       " (1, 3, 5, 4, 2, 0): (1, 3, 5, 4, 2, 0),\n",
+       " (1, 4, 0, 2, 3, 5): (1, 4, 0, 2, 3, 5),\n",
+       " (1, 4, 0, 2, 5, 3): (1, 4, 0, 2, 5, 3),\n",
+       " (1, 4, 0, 3, 2, 5): (1, 4, 0, 3, 2, 5),\n",
+       " (1, 4, 0, 3, 5, 2): (1, 4, 0, 3, 5, 2),\n",
+       " (1, 4, 0, 5, 2, 3): (1, 4, 0, 5, 2, 3),\n",
+       " (1, 4, 0, 5, 3, 2): (1, 4, 0, 5, 3, 2),\n",
+       " (1, 4, 2, 0, 3, 5): (1, 4, 2, 0, 3, 5),\n",
+       " (1, 4, 2, 0, 5, 3): (1, 4, 2, 0, 5, 3),\n",
+       " (1, 4, 2, 3, 0, 5): (1, 4, 2, 3, 0, 5),\n",
+       " (1, 4, 2, 3, 5, 0): (1, 4, 2, 3, 5, 0),\n",
+       " (1, 4, 2, 5, 0, 3): (1, 4, 2, 5, 0, 3),\n",
+       " (1, 4, 2, 5, 3, 0): (1, 4, 2, 5, 3, 0),\n",
+       " (1, 4, 3, 0, 2, 5): (1, 4, 3, 0, 2, 5),\n",
+       " (1, 4, 3, 0, 5, 2): (1, 4, 3, 0, 5, 2),\n",
+       " (1, 4, 3, 2, 0, 5): (1, 4, 3, 2, 0, 5),\n",
+       " (1, 4, 3, 2, 5, 0): (1, 4, 3, 2, 5, 0),\n",
+       " (1, 4, 3, 5, 0, 2): (1, 4, 3, 5, 0, 2),\n",
+       " (1, 4, 3, 5, 2, 0): (1, 4, 3, 5, 2, 0),\n",
+       " (1, 4, 5, 0, 2, 3): (1, 4, 5, 0, 2, 3),\n",
+       " (1, 4, 5, 0, 3, 2): (1, 4, 5, 0, 3, 2),\n",
+       " (1, 4, 5, 2, 0, 3): (1, 4, 5, 2, 0, 3),\n",
+       " (1, 4, 5, 2, 3, 0): (1, 4, 5, 2, 3, 0),\n",
+       " (1, 4, 5, 3, 0, 2): (1, 4, 5, 3, 0, 2),\n",
+       " (1, 4, 5, 3, 2, 0): (1, 4, 5, 3, 2, 0),\n",
+       " (1, 5, 0, 2, 3, 4): (1, 5, 0, 2, 3, 4),\n",
+       " (1, 5, 0, 2, 4, 3): (1, 5, 0, 2, 4, 3),\n",
+       " (1, 5, 0, 3, 2, 4): (1, 5, 0, 3, 2, 4),\n",
+       " (1, 5, 0, 3, 4, 2): (1, 5, 0, 3, 4, 2),\n",
+       " (1, 5, 0, 4, 2, 3): (1, 5, 0, 4, 2, 3),\n",
+       " (1, 5, 0, 4, 3, 2): (1, 5, 0, 4, 3, 2),\n",
+       " (1, 5, 2, 0, 3, 4): (1, 5, 2, 0, 3, 4),\n",
+       " (1, 5, 2, 0, 4, 3): (1, 5, 2, 0, 4, 3),\n",
+       " (1, 5, 2, 3, 0, 4): (1, 5, 2, 3, 0, 4),\n",
+       " (1, 5, 2, 3, 4, 0): (1, 5, 2, 3, 4, 0),\n",
+       " (1, 5, 2, 4, 0, 3): (1, 5, 2, 4, 0, 3),\n",
+       " (1, 5, 2, 4, 3, 0): (1, 5, 2, 4, 3, 0),\n",
+       " (1, 5, 3, 0, 2, 4): (1, 5, 3, 0, 2, 4),\n",
+       " (1, 5, 3, 0, 4, 2): (1, 5, 3, 0, 4, 2),\n",
+       " (1, 5, 3, 2, 0, 4): (1, 5, 3, 2, 0, 4),\n",
+       " (1, 5, 3, 2, 4, 0): (1, 5, 3, 2, 4, 0),\n",
+       " (1, 5, 3, 4, 0, 2): (1, 5, 3, 4, 0, 2),\n",
+       " (1, 5, 3, 4, 2, 0): (1, 5, 3, 4, 2, 0),\n",
+       " (1, 5, 4, 0, 2, 3): (1, 5, 4, 0, 2, 3),\n",
+       " (1, 5, 4, 0, 3, 2): (1, 5, 4, 0, 3, 2),\n",
+       " (1, 5, 4, 2, 0, 3): (1, 5, 4, 2, 0, 3),\n",
+       " (1, 5, 4, 2, 3, 0): (1, 5, 4, 2, 3, 0),\n",
+       " (1, 5, 4, 3, 0, 2): (1, 5, 4, 3, 0, 2),\n",
+       " (1, 5, 4, 3, 2, 0): (1, 5, 4, 3, 2, 0),\n",
+       " (2, 0, 1, 3, 4, 5): (2, 0, 1, 3, 4, 5),\n",
+       " (2, 0, 1, 3, 5, 4): (2, 0, 1, 3, 5, 4),\n",
+       " (2, 0, 1, 4, 3, 5): (2, 0, 1, 4, 3, 5),\n",
+       " (2, 0, 1, 4, 5, 3): (2, 0, 1, 4, 5, 3),\n",
+       " (2, 0, 1, 5, 3, 4): (2, 0, 1, 5, 3, 4),\n",
+       " (2, 0, 1, 5, 4, 3): (2, 0, 1, 5, 4, 3),\n",
+       " (2, 0, 3, 1, 4, 5): (2, 0, 3, 1, 4, 5),\n",
+       " (2, 0, 3, 1, 5, 4): (2, 0, 3, 1, 5, 4),\n",
+       " (2, 0, 3, 4, 1, 5): (2, 0, 3, 4, 1, 5),\n",
+       " (2, 0, 3, 4, 5, 1): (2, 0, 3, 4, 5, 1),\n",
+       " (2, 0, 3, 5, 1, 4): (2, 0, 3, 5, 1, 4),\n",
+       " (2, 0, 3, 5, 4, 1): (2, 0, 3, 5, 4, 1),\n",
+       " (2, 0, 4, 1, 3, 5): (2, 0, 4, 1, 3, 5),\n",
+       " (2, 0, 4, 1, 5, 3): (2, 0, 4, 1, 5, 3),\n",
+       " (2, 0, 4, 3, 1, 5): (2, 0, 4, 3, 1, 5),\n",
+       " (2, 0, 4, 3, 5, 1): (2, 0, 4, 3, 5, 1),\n",
+       " (2, 0, 4, 5, 1, 3): (2, 0, 4, 5, 1, 3),\n",
+       " (2, 0, 4, 5, 3, 1): (2, 0, 4, 5, 3, 1),\n",
+       " (2, 0, 5, 1, 3, 4): (2, 0, 5, 1, 3, 4),\n",
+       " (2, 0, 5, 1, 4, 3): (2, 0, 5, 1, 4, 3),\n",
+       " (2, 0, 5, 3, 1, 4): (2, 0, 5, 3, 1, 4),\n",
+       " (2, 0, 5, 3, 4, 1): (2, 0, 5, 3, 4, 1),\n",
+       " (2, 0, 5, 4, 1, 3): (2, 0, 5, 4, 1, 3),\n",
+       " (2, 0, 5, 4, 3, 1): (2, 0, 5, 4, 3, 1),\n",
+       " (2, 1, 0, 3, 4, 5): (2, 1, 0, 3, 4, 5),\n",
+       " (2, 1, 0, 3, 5, 4): (2, 1, 0, 3, 5, 4),\n",
+       " (2, 1, 0, 4, 3, 5): (2, 1, 0, 4, 3, 5),\n",
+       " (2, 1, 0, 4, 5, 3): (2, 1, 0, 4, 5, 3),\n",
+       " (2, 1, 0, 5, 3, 4): (2, 1, 0, 5, 3, 4),\n",
+       " (2, 1, 0, 5, 4, 3): (2, 1, 0, 5, 4, 3),\n",
+       " (2, 1, 3, 0, 4, 5): (2, 1, 3, 0, 4, 5),\n",
+       " (2, 1, 3, 0, 5, 4): (2, 1, 3, 0, 5, 4),\n",
+       " (2, 1, 3, 4, 0, 5): (2, 1, 3, 4, 0, 5),\n",
+       " (2, 1, 3, 4, 5, 0): (2, 1, 3, 4, 5, 0),\n",
+       " (2, 1, 3, 5, 0, 4): (2, 1, 3, 5, 0, 4),\n",
+       " (2, 1, 3, 5, 4, 0): (2, 1, 3, 5, 4, 0),\n",
+       " (2, 1, 4, 0, 3, 5): (2, 1, 4, 0, 3, 5),\n",
+       " (2, 1, 4, 0, 5, 3): (2, 1, 4, 0, 5, 3),\n",
+       " (2, 1, 4, 3, 0, 5): (2, 1, 4, 3, 0, 5),\n",
+       " (2, 1, 4, 3, 5, 0): (2, 1, 4, 3, 5, 0),\n",
+       " (2, 1, 4, 5, 0, 3): (2, 1, 4, 5, 0, 3),\n",
+       " (2, 1, 4, 5, 3, 0): (2, 1, 4, 5, 3, 0),\n",
+       " (2, 1, 5, 0, 3, 4): (2, 1, 5, 0, 3, 4),\n",
+       " (2, 1, 5, 0, 4, 3): (2, 1, 5, 0, 4, 3),\n",
+       " (2, 1, 5, 3, 0, 4): (2, 1, 5, 3, 0, 4),\n",
+       " (2, 1, 5, 3, 4, 0): (2, 1, 5, 3, 4, 0),\n",
+       " (2, 1, 5, 4, 0, 3): (2, 1, 5, 4, 0, 3),\n",
+       " (2, 1, 5, 4, 3, 0): (2, 1, 5, 4, 3, 0),\n",
+       " (2, 3, 0, 1, 4, 5): (2, 3, 0, 1, 4, 5),\n",
+       " (2, 3, 0, 1, 5, 4): (2, 3, 0, 1, 5, 4),\n",
+       " (2, 3, 0, 4, 1, 5): (2, 3, 0, 4, 1, 5),\n",
+       " (2, 3, 0, 4, 5, 1): (2, 3, 0, 4, 5, 1),\n",
+       " (2, 3, 0, 5, 1, 4): (2, 3, 0, 5, 1, 4),\n",
+       " (2, 3, 0, 5, 4, 1): (2, 3, 0, 5, 4, 1),\n",
+       " (2, 3, 1, 0, 4, 5): (2, 3, 1, 0, 4, 5),\n",
+       " (2, 3, 1, 0, 5, 4): (2, 3, 1, 0, 5, 4),\n",
+       " (2, 3, 1, 4, 0, 5): (2, 3, 1, 4, 0, 5),\n",
+       " (2, 3, 1, 4, 5, 0): (2, 3, 1, 4, 5, 0),\n",
+       " (2, 3, 1, 5, 0, 4): (2, 3, 1, 5, 0, 4),\n",
+       " (2, 3, 1, 5, 4, 0): (2, 3, 1, 5, 4, 0),\n",
+       " (2, 3, 4, 0, 1, 5): (2, 3, 4, 0, 1, 5),\n",
+       " (2, 3, 4, 0, 5, 1): (2, 3, 4, 0, 5, 1),\n",
+       " (2, 3, 4, 1, 0, 5): (2, 3, 4, 1, 0, 5),\n",
+       " (2, 3, 4, 1, 5, 0): (2, 3, 4, 1, 5, 0),\n",
+       " (2, 3, 4, 5, 0, 1): (2, 3, 4, 5, 0, 1),\n",
+       " (2, 3, 4, 5, 1, 0): (2, 3, 4, 5, 1, 0),\n",
+       " (2, 3, 5, 0, 1, 4): (2, 3, 5, 0, 1, 4),\n",
+       " (2, 3, 5, 0, 4, 1): (2, 3, 5, 0, 4, 1),\n",
+       " (2, 3, 5, 1, 0, 4): (2, 3, 5, 1, 0, 4),\n",
+       " (2, 3, 5, 1, 4, 0): (2, 3, 5, 1, 4, 0),\n",
+       " (2, 3, 5, 4, 0, 1): (2, 3, 5, 4, 0, 1),\n",
+       " (2, 3, 5, 4, 1, 0): (2, 3, 5, 4, 1, 0),\n",
+       " (2, 4, 0, 1, 3, 5): (2, 4, 0, 1, 3, 5),\n",
+       " (2, 4, 0, 1, 5, 3): (2, 4, 0, 1, 5, 3),\n",
+       " (2, 4, 0, 3, 1, 5): (2, 4, 0, 3, 1, 5),\n",
+       " (2, 4, 0, 3, 5, 1): (2, 4, 0, 3, 5, 1),\n",
+       " (2, 4, 0, 5, 1, 3): (2, 4, 0, 5, 1, 3),\n",
+       " (2, 4, 0, 5, 3, 1): (2, 4, 0, 5, 3, 1),\n",
+       " (2, 4, 1, 0, 3, 5): (2, 4, 1, 0, 3, 5),\n",
+       " (2, 4, 1, 0, 5, 3): (2, 4, 1, 0, 5, 3),\n",
+       " (2, 4, 1, 3, 0, 5): (2, 4, 1, 3, 0, 5),\n",
+       " (2, 4, 1, 3, 5, 0): (2, 4, 1, 3, 5, 0),\n",
+       " (2, 4, 1, 5, 0, 3): (2, 4, 1, 5, 0, 3),\n",
+       " (2, 4, 1, 5, 3, 0): (2, 4, 1, 5, 3, 0),\n",
+       " (2, 4, 3, 0, 1, 5): (2, 4, 3, 0, 1, 5),\n",
+       " (2, 4, 3, 0, 5, 1): (2, 4, 3, 0, 5, 1),\n",
+       " (2, 4, 3, 1, 0, 5): (2, 4, 3, 1, 0, 5),\n",
+       " (2, 4, 3, 1, 5, 0): (2, 4, 3, 1, 5, 0),\n",
+       " (2, 4, 3, 5, 0, 1): (2, 4, 3, 5, 0, 1),\n",
+       " (2, 4, 3, 5, 1, 0): (2, 4, 3, 5, 1, 0),\n",
+       " (2, 4, 5, 0, 1, 3): (2, 4, 5, 0, 1, 3),\n",
+       " (2, 4, 5, 0, 3, 1): (2, 4, 5, 0, 3, 1),\n",
+       " (2, 4, 5, 1, 0, 3): (2, 4, 5, 1, 0, 3),\n",
+       " (2, 4, 5, 1, 3, 0): (2, 4, 5, 1, 3, 0),\n",
+       " (2, 4, 5, 3, 0, 1): (2, 4, 5, 3, 0, 1),\n",
+       " (2, 4, 5, 3, 1, 0): (2, 4, 5, 3, 1, 0),\n",
+       " (2, 5, 0, 1, 3, 4): (2, 5, 0, 1, 3, 4),\n",
+       " (2, 5, 0, 1, 4, 3): (2, 5, 0, 1, 4, 3),\n",
+       " (2, 5, 0, 3, 1, 4): (2, 5, 0, 3, 1, 4),\n",
+       " (2, 5, 0, 3, 4, 1): (2, 5, 0, 3, 4, 1),\n",
+       " (2, 5, 0, 4, 1, 3): (2, 5, 0, 4, 1, 3),\n",
+       " (2, 5, 0, 4, 3, 1): (2, 5, 0, 4, 3, 1),\n",
+       " (2, 5, 1, 0, 3, 4): (2, 5, 1, 0, 3, 4),\n",
+       " (2, 5, 1, 0, 4, 3): (2, 5, 1, 0, 4, 3),\n",
+       " (2, 5, 1, 3, 0, 4): (2, 5, 1, 3, 0, 4),\n",
+       " (2, 5, 1, 3, 4, 0): (2, 5, 1, 3, 4, 0),\n",
+       " (2, 5, 1, 4, 0, 3): (2, 5, 1, 4, 0, 3),\n",
+       " (2, 5, 1, 4, 3, 0): (2, 5, 1, 4, 3, 0),\n",
+       " (2, 5, 3, 0, 1, 4): (2, 5, 3, 0, 1, 4),\n",
+       " (2, 5, 3, 0, 4, 1): (2, 5, 3, 0, 4, 1),\n",
+       " (2, 5, 3, 1, 0, 4): (2, 5, 3, 1, 0, 4),\n",
+       " (2, 5, 3, 1, 4, 0): (2, 5, 3, 1, 4, 0),\n",
+       " (2, 5, 3, 4, 0, 1): (2, 5, 3, 4, 0, 1),\n",
+       " (2, 5, 3, 4, 1, 0): (2, 5, 3, 4, 1, 0),\n",
+       " (2, 5, 4, 0, 1, 3): (2, 5, 4, 0, 1, 3),\n",
+       " (2, 5, 4, 0, 3, 1): (2, 5, 4, 0, 3, 1),\n",
+       " (2, 5, 4, 1, 0, 3): (2, 5, 4, 1, 0, 3),\n",
+       " (2, 5, 4, 1, 3, 0): (2, 5, 4, 1, 3, 0),\n",
+       " (2, 5, 4, 3, 0, 1): (2, 5, 4, 3, 0, 1),\n",
+       " (2, 5, 4, 3, 1, 0): (2, 5, 4, 3, 1, 0),\n",
+       " (3, 0, 1, 2, 4, 5): (3, 0, 1, 2, 4, 5),\n",
+       " (3, 0, 1, 2, 5, 4): (3, 0, 1, 2, 5, 4),\n",
+       " (3, 0, 1, 4, 2, 5): (3, 0, 1, 4, 2, 5),\n",
+       " (3, 0, 1, 4, 5, 2): (3, 0, 1, 4, 5, 2),\n",
+       " (3, 0, 1, 5, 2, 4): (3, 0, 1, 5, 2, 4),\n",
+       " (3, 0, 1, 5, 4, 2): (3, 0, 1, 5, 4, 2),\n",
+       " (3, 0, 2, 1, 4, 5): (3, 0, 2, 1, 4, 5),\n",
+       " (3, 0, 2, 1, 5, 4): (3, 0, 2, 1, 5, 4),\n",
+       " (3, 0, 2, 4, 1, 5): (3, 0, 2, 4, 1, 5),\n",
+       " (3, 0, 2, 4, 5, 1): (3, 0, 2, 4, 5, 1),\n",
+       " (3, 0, 2, 5, 1, 4): (3, 0, 2, 5, 1, 4),\n",
+       " (3, 0, 2, 5, 4, 1): (3, 0, 2, 5, 4, 1),\n",
+       " (3, 0, 4, 1, 2, 5): (3, 0, 4, 1, 2, 5),\n",
+       " (3, 0, 4, 1, 5, 2): (3, 0, 4, 1, 5, 2),\n",
+       " (3, 0, 4, 2, 1, 5): (3, 0, 4, 2, 1, 5),\n",
+       " (3, 0, 4, 2, 5, 1): (3, 0, 4, 2, 5, 1),\n",
+       " (3, 0, 4, 5, 1, 2): (3, 0, 4, 5, 1, 2),\n",
+       " (3, 0, 4, 5, 2, 1): (3, 0, 4, 5, 2, 1),\n",
+       " (3, 0, 5, 1, 2, 4): (3, 0, 5, 1, 2, 4),\n",
+       " (3, 0, 5, 1, 4, 2): (3, 0, 5, 1, 4, 2),\n",
+       " (3, 0, 5, 2, 1, 4): (3, 0, 5, 2, 1, 4),\n",
+       " (3, 0, 5, 2, 4, 1): (3, 0, 5, 2, 4, 1),\n",
+       " (3, 0, 5, 4, 1, 2): (3, 0, 5, 4, 1, 2),\n",
+       " (3, 0, 5, 4, 2, 1): (3, 0, 5, 4, 2, 1),\n",
+       " (3, 1, 0, 2, 4, 5): (3, 1, 0, 2, 4, 5),\n",
+       " (3, 1, 0, 2, 5, 4): (3, 1, 0, 2, 5, 4),\n",
+       " (3, 1, 0, 4, 2, 5): (3, 1, 0, 4, 2, 5),\n",
+       " (3, 1, 0, 4, 5, 2): (3, 1, 0, 4, 5, 2),\n",
+       " (3, 1, 0, 5, 2, 4): (3, 1, 0, 5, 2, 4),\n",
+       " (3, 1, 0, 5, 4, 2): (3, 1, 0, 5, 4, 2),\n",
+       " (3, 1, 2, 0, 4, 5): (3, 1, 2, 0, 4, 5),\n",
+       " (3, 1, 2, 0, 5, 4): (3, 1, 2, 0, 5, 4),\n",
+       " (3, 1, 2, 4, 0, 5): (3, 1, 2, 4, 0, 5),\n",
+       " (3, 1, 2, 4, 5, 0): (3, 1, 2, 4, 5, 0),\n",
+       " (3, 1, 2, 5, 0, 4): (3, 1, 2, 5, 0, 4),\n",
+       " (3, 1, 2, 5, 4, 0): (3, 1, 2, 5, 4, 0),\n",
+       " (3, 1, 4, 0, 2, 5): (3, 1, 4, 0, 2, 5),\n",
+       " (3, 1, 4, 0, 5, 2): (3, 1, 4, 0, 5, 2),\n",
+       " (3, 1, 4, 2, 0, 5): (3, 1, 4, 2, 0, 5),\n",
+       " (3, 1, 4, 2, 5, 0): (3, 1, 4, 2, 5, 0),\n",
+       " (3, 1, 4, 5, 0, 2): (3, 1, 4, 5, 0, 2),\n",
+       " (3, 1, 4, 5, 2, 0): (3, 1, 4, 5, 2, 0),\n",
+       " (3, 1, 5, 0, 2, 4): (3, 1, 5, 0, 2, 4),\n",
+       " (3, 1, 5, 0, 4, 2): (3, 1, 5, 0, 4, 2),\n",
+       " (3, 1, 5, 2, 0, 4): (3, 1, 5, 2, 0, 4),\n",
+       " (3, 1, 5, 2, 4, 0): (3, 1, 5, 2, 4, 0),\n",
+       " (3, 1, 5, 4, 0, 2): (3, 1, 5, 4, 0, 2),\n",
+       " (3, 1, 5, 4, 2, 0): (3, 1, 5, 4, 2, 0),\n",
+       " (3, 2, 0, 1, 4, 5): (3, 2, 0, 1, 4, 5),\n",
+       " (3, 2, 0, 1, 5, 4): (3, 2, 0, 1, 5, 4),\n",
+       " (3, 2, 0, 4, 1, 5): (3, 2, 0, 4, 1, 5),\n",
+       " (3, 2, 0, 4, 5, 1): (3, 2, 0, 4, 5, 1),\n",
+       " (3, 2, 0, 5, 1, 4): (3, 2, 0, 5, 1, 4),\n",
+       " (3, 2, 0, 5, 4, 1): (3, 2, 0, 5, 4, 1),\n",
+       " (3, 2, 1, 0, 4, 5): (3, 2, 1, 0, 4, 5),\n",
+       " (3, 2, 1, 0, 5, 4): (3, 2, 1, 0, 5, 4),\n",
+       " (3, 2, 1, 4, 0, 5): (3, 2, 1, 4, 0, 5),\n",
+       " (3, 2, 1, 4, 5, 0): (3, 2, 1, 4, 5, 0),\n",
+       " (3, 2, 1, 5, 0, 4): (3, 2, 1, 5, 0, 4),\n",
+       " (3, 2, 1, 5, 4, 0): (3, 2, 1, 5, 4, 0),\n",
+       " (3, 2, 4, 0, 1, 5): (3, 2, 4, 0, 1, 5),\n",
+       " (3, 2, 4, 0, 5, 1): (3, 2, 4, 0, 5, 1),\n",
+       " (3, 2, 4, 1, 0, 5): (3, 2, 4, 1, 0, 5),\n",
+       " (3, 2, 4, 1, 5, 0): (3, 2, 4, 1, 5, 0),\n",
+       " (3, 2, 4, 5, 0, 1): (3, 2, 4, 5, 0, 1),\n",
+       " (3, 2, 4, 5, 1, 0): (3, 2, 4, 5, 1, 0),\n",
+       " (3, 2, 5, 0, 1, 4): (3, 2, 5, 0, 1, 4),\n",
+       " (3, 2, 5, 0, 4, 1): (3, 2, 5, 0, 4, 1),\n",
+       " (3, 2, 5, 1, 0, 4): (3, 2, 5, 1, 0, 4),\n",
+       " (3, 2, 5, 1, 4, 0): (3, 2, 5, 1, 4, 0),\n",
+       " (3, 2, 5, 4, 0, 1): (3, 2, 5, 4, 0, 1),\n",
+       " (3, 2, 5, 4, 1, 0): (3, 2, 5, 4, 1, 0),\n",
+       " (3, 4, 0, 1, 2, 5): (3, 4, 0, 1, 2, 5),\n",
+       " (3, 4, 0, 1, 5, 2): (3, 4, 0, 1, 5, 2),\n",
+       " (3, 4, 0, 2, 1, 5): (3, 4, 0, 2, 1, 5),\n",
+       " (3, 4, 0, 2, 5, 1): (3, 4, 0, 2, 5, 1),\n",
+       " (3, 4, 0, 5, 1, 2): (3, 4, 0, 5, 1, 2),\n",
+       " (3, 4, 0, 5, 2, 1): (3, 4, 0, 5, 2, 1),\n",
+       " (3, 4, 1, 0, 2, 5): (3, 4, 1, 0, 2, 5),\n",
+       " (3, 4, 1, 0, 5, 2): (3, 4, 1, 0, 5, 2),\n",
+       " (3, 4, 1, 2, 0, 5): (3, 4, 1, 2, 0, 5),\n",
+       " (3, 4, 1, 2, 5, 0): (3, 4, 1, 2, 5, 0),\n",
+       " (3, 4, 1, 5, 0, 2): (3, 4, 1, 5, 0, 2),\n",
+       " (3, 4, 1, 5, 2, 0): (3, 4, 1, 5, 2, 0),\n",
+       " (3, 4, 2, 0, 1, 5): (3, 4, 2, 0, 1, 5),\n",
+       " (3, 4, 2, 0, 5, 1): (3, 4, 2, 0, 5, 1),\n",
+       " (3, 4, 2, 1, 0, 5): (3, 4, 2, 1, 0, 5),\n",
+       " (3, 4, 2, 1, 5, 0): (3, 4, 2, 1, 5, 0),\n",
+       " (3, 4, 2, 5, 0, 1): (3, 4, 2, 5, 0, 1),\n",
+       " (3, 4, 2, 5, 1, 0): (3, 4, 2, 5, 1, 0),\n",
+       " (3, 4, 5, 0, 1, 2): (3, 4, 5, 0, 1, 2),\n",
+       " (3, 4, 5, 0, 2, 1): (3, 4, 5, 0, 2, 1),\n",
+       " (3, 4, 5, 1, 0, 2): (3, 4, 5, 1, 0, 2),\n",
+       " (3, 4, 5, 1, 2, 0): (3, 4, 5, 1, 2, 0),\n",
+       " (3, 4, 5, 2, 0, 1): (3, 4, 5, 2, 0, 1),\n",
+       " (3, 4, 5, 2, 1, 0): (3, 4, 5, 2, 1, 0),\n",
+       " (3, 5, 0, 1, 2, 4): (3, 5, 0, 1, 2, 4),\n",
+       " (3, 5, 0, 1, 4, 2): (3, 5, 0, 1, 4, 2),\n",
+       " (3, 5, 0, 2, 1, 4): (3, 5, 0, 2, 1, 4),\n",
+       " (3, 5, 0, 2, 4, 1): (3, 5, 0, 2, 4, 1),\n",
+       " (3, 5, 0, 4, 1, 2): (3, 5, 0, 4, 1, 2),\n",
+       " (3, 5, 0, 4, 2, 1): (3, 5, 0, 4, 2, 1),\n",
+       " (3, 5, 1, 0, 2, 4): (3, 5, 1, 0, 2, 4),\n",
+       " (3, 5, 1, 0, 4, 2): (3, 5, 1, 0, 4, 2),\n",
+       " (3, 5, 1, 2, 0, 4): (3, 5, 1, 2, 0, 4),\n",
+       " (3, 5, 1, 2, 4, 0): (3, 5, 1, 2, 4, 0),\n",
+       " (3, 5, 1, 4, 0, 2): (3, 5, 1, 4, 0, 2),\n",
+       " (3, 5, 1, 4, 2, 0): (3, 5, 1, 4, 2, 0),\n",
+       " (3, 5, 2, 0, 1, 4): (3, 5, 2, 0, 1, 4),\n",
+       " (3, 5, 2, 0, 4, 1): (3, 5, 2, 0, 4, 1),\n",
+       " (3, 5, 2, 1, 0, 4): (3, 5, 2, 1, 0, 4),\n",
+       " (3, 5, 2, 1, 4, 0): (3, 5, 2, 1, 4, 0),\n",
+       " (3, 5, 2, 4, 0, 1): (3, 5, 2, 4, 0, 1),\n",
+       " (3, 5, 2, 4, 1, 0): (3, 5, 2, 4, 1, 0),\n",
+       " (3, 5, 4, 0, 1, 2): (3, 5, 4, 0, 1, 2),\n",
+       " (3, 5, 4, 0, 2, 1): (3, 5, 4, 0, 2, 1),\n",
+       " (3, 5, 4, 1, 0, 2): (3, 5, 4, 1, 0, 2),\n",
+       " (3, 5, 4, 1, 2, 0): (3, 5, 4, 1, 2, 0),\n",
+       " (3, 5, 4, 2, 0, 1): (3, 5, 4, 2, 0, 1),\n",
+       " (3, 5, 4, 2, 1, 0): (3, 5, 4, 2, 1, 0),\n",
+       " (4, 0, 1, 2, 3, 5): (4, 0, 1, 2, 3, 5),\n",
+       " (4, 0, 1, 2, 5, 3): (4, 0, 1, 2, 5, 3),\n",
+       " (4, 0, 1, 3, 2, 5): (4, 0, 1, 3, 2, 5),\n",
+       " (4, 0, 1, 3, 5, 2): (4, 0, 1, 3, 5, 2),\n",
+       " (4, 0, 1, 5, 2, 3): (4, 0, 1, 5, 2, 3),\n",
+       " (4, 0, 1, 5, 3, 2): (4, 0, 1, 5, 3, 2),\n",
+       " (4, 0, 2, 1, 3, 5): (4, 0, 2, 1, 3, 5),\n",
+       " (4, 0, 2, 1, 5, 3): (4, 0, 2, 1, 5, 3),\n",
+       " (4, 0, 2, 3, 1, 5): (4, 0, 2, 3, 1, 5),\n",
+       " (4, 0, 2, 3, 5, 1): (4, 0, 2, 3, 5, 1),\n",
+       " (4, 0, 2, 5, 1, 3): (4, 0, 2, 5, 1, 3),\n",
+       " (4, 0, 2, 5, 3, 1): (4, 0, 2, 5, 3, 1),\n",
+       " (4, 0, 3, 1, 2, 5): (4, 0, 3, 1, 2, 5),\n",
+       " (4, 0, 3, 1, 5, 2): (4, 0, 3, 1, 5, 2),\n",
+       " (4, 0, 3, 2, 1, 5): (4, 0, 3, 2, 1, 5),\n",
+       " (4, 0, 3, 2, 5, 1): (4, 0, 3, 2, 5, 1),\n",
+       " (4, 0, 3, 5, 1, 2): (4, 0, 3, 5, 1, 2),\n",
+       " (4, 0, 3, 5, 2, 1): (4, 0, 3, 5, 2, 1),\n",
+       " (4, 0, 5, 1, 2, 3): (4, 0, 5, 1, 2, 3),\n",
+       " (4, 0, 5, 1, 3, 2): (4, 0, 5, 1, 3, 2),\n",
+       " (4, 0, 5, 2, 1, 3): (4, 0, 5, 2, 1, 3),\n",
+       " (4, 0, 5, 2, 3, 1): (4, 0, 5, 2, 3, 1),\n",
+       " (4, 0, 5, 3, 1, 2): (4, 0, 5, 3, 1, 2),\n",
+       " (4, 0, 5, 3, 2, 1): (4, 0, 5, 3, 2, 1),\n",
+       " (4, 1, 0, 2, 3, 5): (4, 1, 0, 2, 3, 5),\n",
+       " (4, 1, 0, 2, 5, 3): (4, 1, 0, 2, 5, 3),\n",
+       " (4, 1, 0, 3, 2, 5): (4, 1, 0, 3, 2, 5),\n",
+       " (4, 1, 0, 3, 5, 2): (4, 1, 0, 3, 5, 2),\n",
+       " (4, 1, 0, 5, 2, 3): (4, 1, 0, 5, 2, 3),\n",
+       " (4, 1, 0, 5, 3, 2): (4, 1, 0, 5, 3, 2),\n",
+       " (4, 1, 2, 0, 3, 5): (4, 1, 2, 0, 3, 5),\n",
+       " (4, 1, 2, 0, 5, 3): (4, 1, 2, 0, 5, 3),\n",
+       " (4, 1, 2, 3, 0, 5): (4, 1, 2, 3, 0, 5),\n",
+       " (4, 1, 2, 3, 5, 0): (4, 1, 2, 3, 5, 0),\n",
+       " (4, 1, 2, 5, 0, 3): (4, 1, 2, 5, 0, 3),\n",
+       " (4, 1, 2, 5, 3, 0): (4, 1, 2, 5, 3, 0),\n",
+       " (4, 1, 3, 0, 2, 5): (4, 1, 3, 0, 2, 5),\n",
+       " (4, 1, 3, 0, 5, 2): (4, 1, 3, 0, 5, 2),\n",
+       " (4, 1, 3, 2, 0, 5): (4, 1, 3, 2, 0, 5),\n",
+       " (4, 1, 3, 2, 5, 0): (4, 1, 3, 2, 5, 0),\n",
+       " (4, 1, 3, 5, 0, 2): (4, 1, 3, 5, 0, 2),\n",
+       " (4, 1, 3, 5, 2, 0): (4, 1, 3, 5, 2, 0),\n",
+       " (4, 1, 5, 0, 2, 3): (4, 1, 5, 0, 2, 3),\n",
+       " (4, 1, 5, 0, 3, 2): (4, 1, 5, 0, 3, 2),\n",
+       " (4, 1, 5, 2, 0, 3): (4, 1, 5, 2, 0, 3),\n",
+       " (4, 1, 5, 2, 3, 0): (4, 1, 5, 2, 3, 0),\n",
+       " (4, 1, 5, 3, 0, 2): (4, 1, 5, 3, 0, 2),\n",
+       " (4, 1, 5, 3, 2, 0): (4, 1, 5, 3, 2, 0),\n",
+       " (4, 2, 0, 1, 3, 5): (4, 2, 0, 1, 3, 5),\n",
+       " (4, 2, 0, 1, 5, 3): (4, 2, 0, 1, 5, 3),\n",
+       " (4, 2, 0, 3, 1, 5): (4, 2, 0, 3, 1, 5),\n",
+       " (4, 2, 0, 3, 5, 1): (4, 2, 0, 3, 5, 1),\n",
+       " (4, 2, 0, 5, 1, 3): (4, 2, 0, 5, 1, 3),\n",
+       " (4, 2, 0, 5, 3, 1): (4, 2, 0, 5, 3, 1),\n",
+       " (4, 2, 1, 0, 3, 5): (4, 2, 1, 0, 3, 5),\n",
+       " (4, 2, 1, 0, 5, 3): (4, 2, 1, 0, 5, 3),\n",
+       " (4, 2, 1, 3, 0, 5): (4, 2, 1, 3, 0, 5),\n",
+       " (4, 2, 1, 3, 5, 0): (4, 2, 1, 3, 5, 0),\n",
+       " (4, 2, 1, 5, 0, 3): (4, 2, 1, 5, 0, 3),\n",
+       " (4, 2, 1, 5, 3, 0): (4, 2, 1, 5, 3, 0),\n",
+       " (4, 2, 3, 0, 1, 5): (4, 2, 3, 0, 1, 5),\n",
+       " (4, 2, 3, 0, 5, 1): (4, 2, 3, 0, 5, 1),\n",
+       " (4, 2, 3, 1, 0, 5): (4, 2, 3, 1, 0, 5),\n",
+       " (4, 2, 3, 1, 5, 0): (4, 2, 3, 1, 5, 0),\n",
+       " (4, 2, 3, 5, 0, 1): (4, 2, 3, 5, 0, 1),\n",
+       " (4, 2, 3, 5, 1, 0): (4, 2, 3, 5, 1, 0),\n",
+       " (4, 2, 5, 0, 1, 3): (4, 2, 5, 0, 1, 3),\n",
+       " (4, 2, 5, 0, 3, 1): (4, 2, 5, 0, 3, 1),\n",
+       " (4, 2, 5, 1, 0, 3): (4, 2, 5, 1, 0, 3),\n",
+       " (4, 2, 5, 1, 3, 0): (4, 2, 5, 1, 3, 0),\n",
+       " (4, 2, 5, 3, 0, 1): (4, 2, 5, 3, 0, 1),\n",
+       " (4, 2, 5, 3, 1, 0): (4, 2, 5, 3, 1, 0),\n",
+       " (4, 3, 0, 1, 2, 5): (4, 3, 0, 1, 2, 5),\n",
+       " (4, 3, 0, 1, 5, 2): (4, 3, 0, 1, 5, 2),\n",
+       " (4, 3, 0, 2, 1, 5): (4, 3, 0, 2, 1, 5),\n",
+       " (4, 3, 0, 2, 5, 1): (4, 3, 0, 2, 5, 1),\n",
+       " (4, 3, 0, 5, 1, 2): (4, 3, 0, 5, 1, 2),\n",
+       " (4, 3, 0, 5, 2, 1): (4, 3, 0, 5, 2, 1),\n",
+       " (4, 3, 1, 0, 2, 5): (4, 3, 1, 0, 2, 5),\n",
+       " (4, 3, 1, 0, 5, 2): (4, 3, 1, 0, 5, 2),\n",
+       " (4, 3, 1, 2, 0, 5): (4, 3, 1, 2, 0, 5),\n",
+       " (4, 3, 1, 2, 5, 0): (4, 3, 1, 2, 5, 0),\n",
+       " (4, 3, 1, 5, 0, 2): (4, 3, 1, 5, 0, 2),\n",
+       " (4, 3, 1, 5, 2, 0): (4, 3, 1, 5, 2, 0),\n",
+       " (4, 3, 2, 0, 1, 5): (4, 3, 2, 0, 1, 5),\n",
+       " (4, 3, 2, 0, 5, 1): (4, 3, 2, 0, 5, 1),\n",
+       " (4, 3, 2, 1, 0, 5): (4, 3, 2, 1, 0, 5),\n",
+       " (4, 3, 2, 1, 5, 0): (4, 3, 2, 1, 5, 0),\n",
+       " (4, 3, 2, 5, 0, 1): (4, 3, 2, 5, 0, 1),\n",
+       " (4, 3, 2, 5, 1, 0): (4, 3, 2, 5, 1, 0),\n",
+       " (4, 3, 5, 0, 1, 2): (4, 3, 5, 0, 1, 2),\n",
+       " (4, 3, 5, 0, 2, 1): (4, 3, 5, 0, 2, 1),\n",
+       " (4, 3, 5, 1, 0, 2): (4, 3, 5, 1, 0, 2),\n",
+       " (4, 3, 5, 1, 2, 0): (4, 3, 5, 1, 2, 0),\n",
+       " (4, 3, 5, 2, 0, 1): (4, 3, 5, 2, 0, 1),\n",
+       " (4, 3, 5, 2, 1, 0): (4, 3, 5, 2, 1, 0),\n",
+       " (4, 5, 0, 1, 2, 3): (4, 5, 0, 1, 2, 3),\n",
+       " (4, 5, 0, 1, 3, 2): (4, 5, 0, 1, 3, 2),\n",
+       " (4, 5, 0, 2, 1, 3): (4, 5, 0, 2, 1, 3),\n",
+       " (4, 5, 0, 2, 3, 1): (4, 5, 0, 2, 3, 1),\n",
+       " (4, 5, 0, 3, 1, 2): (4, 5, 0, 3, 1, 2),\n",
+       " (4, 5, 0, 3, 2, 1): (4, 5, 0, 3, 2, 1),\n",
+       " (4, 5, 1, 0, 2, 3): (4, 5, 1, 0, 2, 3),\n",
+       " (4, 5, 1, 0, 3, 2): (4, 5, 1, 0, 3, 2),\n",
+       " (4, 5, 1, 2, 0, 3): (4, 5, 1, 2, 0, 3),\n",
+       " (4, 5, 1, 2, 3, 0): (4, 5, 1, 2, 3, 0),\n",
+       " (4, 5, 1, 3, 0, 2): (4, 5, 1, 3, 0, 2),\n",
+       " (4, 5, 1, 3, 2, 0): (4, 5, 1, 3, 2, 0),\n",
+       " (4, 5, 2, 0, 1, 3): (4, 5, 2, 0, 1, 3),\n",
+       " (4, 5, 2, 0, 3, 1): (4, 5, 2, 0, 3, 1),\n",
+       " (4, 5, 2, 1, 0, 3): (4, 5, 2, 1, 0, 3),\n",
+       " (4, 5, 2, 1, 3, 0): (4, 5, 2, 1, 3, 0),\n",
+       " (4, 5, 2, 3, 0, 1): (4, 5, 2, 3, 0, 1),\n",
+       " (4, 5, 2, 3, 1, 0): (4, 5, 2, 3, 1, 0),\n",
+       " (4, 5, 3, 0, 1, 2): (4, 5, 3, 0, 1, 2),\n",
+       " (4, 5, 3, 0, 2, 1): (4, 5, 3, 0, 2, 1),\n",
+       " (4, 5, 3, 1, 0, 2): (4, 5, 3, 1, 0, 2),\n",
+       " (4, 5, 3, 1, 2, 0): (4, 5, 3, 1, 2, 0),\n",
+       " (4, 5, 3, 2, 0, 1): (4, 5, 3, 2, 0, 1),\n",
+       " (4, 5, 3, 2, 1, 0): (4, 5, 3, 2, 1, 0),\n",
+       " (5, 0, 1, 2, 3, 4): (5, 0, 1, 2, 3, 4),\n",
+       " (5, 0, 1, 2, 4, 3): (5, 0, 1, 2, 4, 3),\n",
+       " (5, 0, 1, 3, 2, 4): (5, 0, 1, 3, 2, 4),\n",
+       " (5, 0, 1, 3, 4, 2): (5, 0, 1, 3, 4, 2),\n",
+       " (5, 0, 1, 4, 2, 3): (5, 0, 1, 4, 2, 3),\n",
+       " (5, 0, 1, 4, 3, 2): (5, 0, 1, 4, 3, 2),\n",
+       " (5, 0, 2, 1, 3, 4): (5, 0, 2, 1, 3, 4),\n",
+       " (5, 0, 2, 1, 4, 3): (5, 0, 2, 1, 4, 3),\n",
+       " (5, 0, 2, 3, 1, 4): (5, 0, 2, 3, 1, 4),\n",
+       " (5, 0, 2, 3, 4, 1): (5, 0, 2, 3, 4, 1),\n",
+       " (5, 0, 2, 4, 1, 3): (5, 0, 2, 4, 1, 3),\n",
+       " (5, 0, 2, 4, 3, 1): (5, 0, 2, 4, 3, 1),\n",
+       " (5, 0, 3, 1, 2, 4): (5, 0, 3, 1, 2, 4),\n",
+       " (5, 0, 3, 1, 4, 2): (5, 0, 3, 1, 4, 2),\n",
+       " (5, 0, 3, 2, 1, 4): (5, 0, 3, 2, 1, 4),\n",
+       " (5, 0, 3, 2, 4, 1): (5, 0, 3, 2, 4, 1),\n",
+       " (5, 0, 3, 4, 1, 2): (5, 0, 3, 4, 1, 2),\n",
+       " (5, 0, 3, 4, 2, 1): (5, 0, 3, 4, 2, 1),\n",
+       " (5, 0, 4, 1, 2, 3): (5, 0, 4, 1, 2, 3),\n",
+       " (5, 0, 4, 1, 3, 2): (5, 0, 4, 1, 3, 2),\n",
+       " (5, 0, 4, 2, 1, 3): (5, 0, 4, 2, 1, 3),\n",
+       " (5, 0, 4, 2, 3, 1): (5, 0, 4, 2, 3, 1),\n",
+       " (5, 0, 4, 3, 1, 2): (5, 0, 4, 3, 1, 2),\n",
+       " (5, 0, 4, 3, 2, 1): (5, 0, 4, 3, 2, 1),\n",
+       " (5, 1, 0, 2, 3, 4): (5, 1, 0, 2, 3, 4),\n",
+       " (5, 1, 0, 2, 4, 3): (5, 1, 0, 2, 4, 3),\n",
+       " (5, 1, 0, 3, 2, 4): (5, 1, 0, 3, 2, 4),\n",
+       " (5, 1, 0, 3, 4, 2): (5, 1, 0, 3, 4, 2),\n",
+       " (5, 1, 0, 4, 2, 3): (5, 1, 0, 4, 2, 3),\n",
+       " (5, 1, 0, 4, 3, 2): (5, 1, 0, 4, 3, 2),\n",
+       " (5, 1, 2, 0, 3, 4): (5, 1, 2, 0, 3, 4),\n",
+       " (5, 1, 2, 0, 4, 3): (5, 1, 2, 0, 4, 3),\n",
+       " (5, 1, 2, 3, 0, 4): (5, 1, 2, 3, 0, 4),\n",
+       " (5, 1, 2, 3, 4, 0): (5, 1, 2, 3, 4, 0),\n",
+       " (5, 1, 2, 4, 0, 3): (5, 1, 2, 4, 0, 3),\n",
+       " (5, 1, 2, 4, 3, 0): (5, 1, 2, 4, 3, 0),\n",
+       " (5, 1, 3, 0, 2, 4): (5, 1, 3, 0, 2, 4),\n",
+       " (5, 1, 3, 0, 4, 2): (5, 1, 3, 0, 4, 2),\n",
+       " (5, 1, 3, 2, 0, 4): (5, 1, 3, 2, 0, 4),\n",
+       " (5, 1, 3, 2, 4, 0): (5, 1, 3, 2, 4, 0),\n",
+       " (5, 1, 3, 4, 0, 2): (5, 1, 3, 4, 0, 2),\n",
+       " (5, 1, 3, 4, 2, 0): (5, 1, 3, 4, 2, 0),\n",
+       " (5, 1, 4, 0, 2, 3): (5, 1, 4, 0, 2, 3),\n",
+       " (5, 1, 4, 0, 3, 2): (5, 1, 4, 0, 3, 2),\n",
+       " (5, 1, 4, 2, 0, 3): (5, 1, 4, 2, 0, 3),\n",
+       " (5, 1, 4, 2, 3, 0): (5, 1, 4, 2, 3, 0),\n",
+       " (5, 1, 4, 3, 0, 2): (5, 1, 4, 3, 0, 2),\n",
+       " (5, 1, 4, 3, 2, 0): (5, 1, 4, 3, 2, 0),\n",
+       " (5, 2, 0, 1, 3, 4): (5, 2, 0, 1, 3, 4),\n",
+       " (5, 2, 0, 1, 4, 3): (5, 2, 0, 1, 4, 3),\n",
+       " (5, 2, 0, 3, 1, 4): (5, 2, 0, 3, 1, 4),\n",
+       " (5, 2, 0, 3, 4, 1): (5, 2, 0, 3, 4, 1),\n",
+       " (5, 2, 0, 4, 1, 3): (5, 2, 0, 4, 1, 3),\n",
+       " (5, 2, 0, 4, 3, 1): (5, 2, 0, 4, 3, 1),\n",
+       " (5, 2, 1, 0, 3, 4): (5, 2, 1, 0, 3, 4),\n",
+       " (5, 2, 1, 0, 4, 3): (5, 2, 1, 0, 4, 3),\n",
+       " (5, 2, 1, 3, 0, 4): (5, 2, 1, 3, 0, 4),\n",
+       " (5, 2, 1, 3, 4, 0): (5, 2, 1, 3, 4, 0),\n",
+       " (5, 2, 1, 4, 0, 3): (5, 2, 1, 4, 0, 3),\n",
+       " (5, 2, 1, 4, 3, 0): (5, 2, 1, 4, 3, 0),\n",
+       " (5, 2, 3, 0, 1, 4): (5, 2, 3, 0, 1, 4),\n",
+       " (5, 2, 3, 0, 4, 1): (5, 2, 3, 0, 4, 1),\n",
+       " (5, 2, 3, 1, 0, 4): (5, 2, 3, 1, 0, 4),\n",
+       " (5, 2, 3, 1, 4, 0): (5, 2, 3, 1, 4, 0),\n",
+       " (5, 2, 3, 4, 0, 1): (5, 2, 3, 4, 0, 1),\n",
+       " (5, 2, 3, 4, 1, 0): (5, 2, 3, 4, 1, 0),\n",
+       " (5, 2, 4, 0, 1, 3): (5, 2, 4, 0, 1, 3),\n",
+       " (5, 2, 4, 0, 3, 1): (5, 2, 4, 0, 3, 1),\n",
+       " (5, 2, 4, 1, 0, 3): (5, 2, 4, 1, 0, 3),\n",
+       " (5, 2, 4, 1, 3, 0): (5, 2, 4, 1, 3, 0),\n",
+       " (5, 2, 4, 3, 0, 1): (5, 2, 4, 3, 0, 1),\n",
+       " (5, 2, 4, 3, 1, 0): (5, 2, 4, 3, 1, 0),\n",
+       " (5, 3, 0, 1, 2, 4): (5, 3, 0, 1, 2, 4),\n",
+       " (5, 3, 0, 1, 4, 2): (5, 3, 0, 1, 4, 2),\n",
+       " (5, 3, 0, 2, 1, 4): (5, 3, 0, 2, 1, 4),\n",
+       " (5, 3, 0, 2, 4, 1): (5, 3, 0, 2, 4, 1),\n",
+       " (5, 3, 0, 4, 1, 2): (5, 3, 0, 4, 1, 2),\n",
+       " (5, 3, 0, 4, 2, 1): (5, 3, 0, 4, 2, 1),\n",
+       " (5, 3, 1, 0, 2, 4): (5, 3, 1, 0, 2, 4),\n",
+       " (5, 3, 1, 0, 4, 2): (5, 3, 1, 0, 4, 2),\n",
+       " (5, 3, 1, 2, 0, 4): (5, 3, 1, 2, 0, 4),\n",
+       " (5, 3, 1, 2, 4, 0): (5, 3, 1, 2, 4, 0),\n",
+       " (5, 3, 1, 4, 0, 2): (5, 3, 1, 4, 0, 2),\n",
+       " (5, 3, 1, 4, 2, 0): (5, 3, 1, 4, 2, 0),\n",
+       " (5, 3, 2, 0, 1, 4): (5, 3, 2, 0, 1, 4),\n",
+       " (5, 3, 2, 0, 4, 1): (5, 3, 2, 0, 4, 1),\n",
+       " (5, 3, 2, 1, 0, 4): (5, 3, 2, 1, 0, 4),\n",
+       " (5, 3, 2, 1, 4, 0): (5, 3, 2, 1, 4, 0),\n",
+       " (5, 3, 2, 4, 0, 1): (5, 3, 2, 4, 0, 1),\n",
+       " (5, 3, 2, 4, 1, 0): (5, 3, 2, 4, 1, 0),\n",
+       " (5, 3, 4, 0, 1, 2): (5, 3, 4, 0, 1, 2),\n",
+       " (5, 3, 4, 0, 2, 1): (5, 3, 4, 0, 2, 1),\n",
+       " (5, 3, 4, 1, 0, 2): (5, 3, 4, 1, 0, 2),\n",
+       " (5, 3, 4, 1, 2, 0): (5, 3, 4, 1, 2, 0),\n",
+       " (5, 3, 4, 2, 0, 1): (5, 3, 4, 2, 0, 1),\n",
+       " (5, 3, 4, 2, 1, 0): (5, 3, 4, 2, 1, 0),\n",
+       " (5, 4, 0, 1, 2, 3): (5, 4, 0, 1, 2, 3),\n",
+       " (5, 4, 0, 1, 3, 2): (5, 4, 0, 1, 3, 2),\n",
+       " (5, 4, 0, 2, 1, 3): (5, 4, 0, 2, 1, 3),\n",
+       " (5, 4, 0, 2, 3, 1): (5, 4, 0, 2, 3, 1),\n",
+       " (5, 4, 0, 3, 1, 2): (5, 4, 0, 3, 1, 2),\n",
+       " (5, 4, 0, 3, 2, 1): (5, 4, 0, 3, 2, 1),\n",
+       " (5, 4, 1, 0, 2, 3): (5, 4, 1, 0, 2, 3),\n",
+       " (5, 4, 1, 0, 3, 2): (5, 4, 1, 0, 3, 2),\n",
+       " (5, 4, 1, 2, 0, 3): (5, 4, 1, 2, 0, 3),\n",
+       " (5, 4, 1, 2, 3, 0): (5, 4, 1, 2, 3, 0),\n",
+       " (5, 4, 1, 3, 0, 2): (5, 4, 1, 3, 0, 2),\n",
+       " (5, 4, 1, 3, 2, 0): (5, 4, 1, 3, 2, 0),\n",
+       " (5, 4, 2, 0, 1, 3): (5, 4, 2, 0, 1, 3),\n",
+       " (5, 4, 2, 0, 3, 1): (5, 4, 2, 0, 3, 1),\n",
+       " (5, 4, 2, 1, 0, 3): (5, 4, 2, 1, 0, 3),\n",
+       " (5, 4, 2, 1, 3, 0): (5, 4, 2, 1, 3, 0),\n",
+       " (5, 4, 2, 3, 0, 1): (5, 4, 2, 3, 0, 1),\n",
+       " (5, 4, 2, 3, 1, 0): (5, 4, 2, 3, 1, 0),\n",
+       " (5, 4, 3, 0, 1, 2): (5, 4, 3, 0, 1, 2),\n",
+       " (5, 4, 3, 0, 2, 1): (5, 4, 3, 0, 2, 1),\n",
+       " (5, 4, 3, 1, 0, 2): (5, 4, 3, 1, 0, 2),\n",
+       " (5, 4, 3, 1, 2, 0): (5, 4, 3, 1, 2, 0),\n",
+       " (5, 4, 3, 2, 0, 1): (5, 4, 3, 2, 0, 1),\n",
+       " (5, 4, 3, 2, 1, 0): (5, 4, 3, 2, 1, 0)}"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "transpositions6 = {t: t for t in set(itertools.permutations(list(range(6))))}\n",
+    "transpositions6"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(((2, 4, 3, 5, 0, 1), (1, 2), <AmscoFillStyle.reverse_each_row: 3>),\n",
+       " -1437.9908206760847)"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score = amsco_break(c7b, translist=transpositions6)\n",
+    "key_b, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[[AmscoSlice(index=0, start=0, end=1),\n",
+       "  AmscoSlice(index=1, start=1, end=3),\n",
+       "  AmscoSlice(index=2, start=3, end=4),\n",
+       "  AmscoSlice(index=3, start=4, end=6),\n",
+       "  AmscoSlice(index=4, start=6, end=7),\n",
+       "  AmscoSlice(index=5, start=7, end=9)],\n",
+       " [AmscoSlice(index=6, start=9, end=11),\n",
+       "  AmscoSlice(index=7, start=11, end=12),\n",
+       "  AmscoSlice(index=8, start=12, end=14),\n",
+       "  AmscoSlice(index=9, start=14, end=15),\n",
+       "  AmscoSlice(index=10, start=15, end=17),\n",
+       "  AmscoSlice(index=11, start=17, end=18)],\n",
+       " [AmscoSlice(index=12, start=18, end=19),\n",
+       "  AmscoSlice(index=13, start=19, end=21),\n",
+       "  AmscoSlice(index=14, start=21, end=22),\n",
+       "  AmscoSlice(index=15, start=22, end=24),\n",
+       "  AmscoSlice(index=16, start=24, end=25),\n",
+       "  AmscoSlice(index=17, start=25, end=27)],\n",
+       " [AmscoSlice(index=18, start=27, end=29),\n",
+       "  AmscoSlice(index=19, start=29, end=30),\n",
+       "  AmscoSlice(index=20, start=30, end=32),\n",
+       "  AmscoSlice(index=21, start=32, end=33),\n",
+       "  AmscoSlice(index=22, start=33, end=35),\n",
+       "  AmscoSlice(index=23, start=35, end=36)],\n",
+       " [AmscoSlice(index=24, start=36, end=37),\n",
+       "  AmscoSlice(index=25, start=37, end=39),\n",
+       "  AmscoSlice(index=26, start=39, end=40),\n",
+       "  AmscoSlice(index=27, start=40, end=42),\n",
+       "  AmscoSlice(index=28, start=42, end=43),\n",
+       "  AmscoSlice(index=29, start=43, end=45)],\n",
+       " [AmscoSlice(index=30, start=45, end=47),\n",
+       "  AmscoSlice(index=31, start=47, end=48),\n",
+       "  AmscoSlice(index=32, start=48, end=50),\n",
+       "  AmscoSlice(index=33, start=50, end=51),\n",
+       "  AmscoSlice(index=34, start=51, end=53),\n",
+       "  AmscoSlice(index=35, start=53, end=54)],\n",
+       " [AmscoSlice(index=36, start=54, end=55),\n",
+       "  AmscoSlice(index=37, start=55, end=57),\n",
+       "  AmscoSlice(index=38, start=57, end=58),\n",
+       "  AmscoSlice(index=39, start=58, end=60),\n",
+       "  AmscoSlice(index=40, start=60, end=61),\n",
+       "  AmscoSlice(index=41, start=61, end=63)],\n",
+       " [AmscoSlice(index=42, start=63, end=65),\n",
+       "  AmscoSlice(index=43, start=65, end=66),\n",
+       "  AmscoSlice(index=44, start=66, end=68),\n",
+       "  AmscoSlice(index=45, start=68, end=69),\n",
+       "  AmscoSlice(index=46, start=69, end=71),\n",
+       "  AmscoSlice(index=47, start=71, end=72)],\n",
+       " [AmscoSlice(index=48, start=72, end=73),\n",
+       "  AmscoSlice(index=49, start=73, end=75),\n",
+       "  AmscoSlice(index=50, start=75, end=76),\n",
+       "  AmscoSlice(index=51, start=76, end=78),\n",
+       "  AmscoSlice(index=52, start=78, end=79),\n",
+       "  AmscoSlice(index=53, start=79, end=81)],\n",
+       " [AmscoSlice(index=54, start=81, end=83),\n",
+       "  AmscoSlice(index=55, start=83, end=84),\n",
+       "  AmscoSlice(index=56, start=84, end=86),\n",
+       "  AmscoSlice(index=57, start=86, end=87),\n",
+       "  AmscoSlice(index=58, start=87, end=89),\n",
+       "  AmscoSlice(index=59, start=89, end=90)],\n",
+       " [AmscoSlice(index=60, start=90, end=91),\n",
+       "  AmscoSlice(index=61, start=91, end=93),\n",
+       "  AmscoSlice(index=62, start=93, end=94),\n",
+       "  AmscoSlice(index=63, start=94, end=96),\n",
+       "  AmscoSlice(index=64, start=96, end=97),\n",
+       "  AmscoSlice(index=65, start=97, end=99)],\n",
+       " [AmscoSlice(index=66, start=99, end=101),\n",
+       "  AmscoSlice(index=67, start=101, end=102),\n",
+       "  AmscoSlice(index=68, start=102, end=104),\n",
+       "  AmscoSlice(index=69, start=104, end=105),\n",
+       "  AmscoSlice(index=70, start=105, end=107),\n",
+       "  AmscoSlice(index=71, start=107, end=108)],\n",
+       " [AmscoSlice(index=72, start=108, end=109),\n",
+       "  AmscoSlice(index=73, start=109, end=111),\n",
+       "  AmscoSlice(index=74, start=111, end=112),\n",
+       "  AmscoSlice(index=75, start=112, end=114),\n",
+       "  AmscoSlice(index=76, start=114, end=115),\n",
+       "  AmscoSlice(index=77, start=115, end=117)],\n",
+       " [AmscoSlice(index=78, start=117, end=119),\n",
+       "  AmscoSlice(index=79, start=119, end=120),\n",
+       "  AmscoSlice(index=80, start=120, end=122),\n",
+       "  AmscoSlice(index=81, start=122, end=123),\n",
+       "  AmscoSlice(index=82, start=123, end=125),\n",
+       "  AmscoSlice(index=83, start=125, end=126)],\n",
+       " [AmscoSlice(index=84, start=126, end=127),\n",
+       "  AmscoSlice(index=85, start=127, end=129),\n",
+       "  AmscoSlice(index=86, start=129, end=130),\n",
+       "  AmscoSlice(index=87, start=130, end=132),\n",
+       "  AmscoSlice(index=88, start=132, end=133),\n",
+       "  AmscoSlice(index=89, start=133, end=135)],\n",
+       " [AmscoSlice(index=90, start=135, end=137),\n",
+       "  AmscoSlice(index=91, start=137, end=138),\n",
+       "  AmscoSlice(index=92, start=138, end=140),\n",
+       "  AmscoSlice(index=93, start=140, end=141),\n",
+       "  AmscoSlice(index=94, start=141, end=143),\n",
+       "  AmscoSlice(index=95, start=143, end=144)],\n",
+       " [AmscoSlice(index=96, start=144, end=145),\n",
+       "  AmscoSlice(index=97, start=145, end=147),\n",
+       "  AmscoSlice(index=98, start=147, end=148),\n",
+       "  AmscoSlice(index=99, start=148, end=150),\n",
+       "  AmscoSlice(index=100, start=150, end=151),\n",
+       "  AmscoSlice(index=101, start=151, end=153)],\n",
+       " [AmscoSlice(index=102, start=153, end=155),\n",
+       "  AmscoSlice(index=103, start=155, end=156),\n",
+       "  AmscoSlice(index=104, start=156, end=158),\n",
+       "  AmscoSlice(index=105, start=158, end=159),\n",
+       "  AmscoSlice(index=106, start=159, end=161),\n",
+       "  AmscoSlice(index=107, start=161, end=162)],\n",
+       " [AmscoSlice(index=108, start=162, end=163),\n",
+       "  AmscoSlice(index=109, start=163, end=165),\n",
+       "  AmscoSlice(index=110, start=165, end=166),\n",
+       "  AmscoSlice(index=111, start=166, end=168),\n",
+       "  AmscoSlice(index=112, start=168, end=169),\n",
+       "  AmscoSlice(index=113, start=169, end=171)],\n",
+       " [AmscoSlice(index=114, start=171, end=173),\n",
+       "  AmscoSlice(index=115, start=173, end=174),\n",
+       "  AmscoSlice(index=116, start=174, end=176),\n",
+       "  AmscoSlice(index=117, start=176, end=177),\n",
+       "  AmscoSlice(index=118, start=177, end=179),\n",
+       "  AmscoSlice(index=119, start=179, end=180)],\n",
+       " [AmscoSlice(index=120, start=180, end=181),\n",
+       "  AmscoSlice(index=121, start=181, end=183),\n",
+       "  AmscoSlice(index=122, start=183, end=184),\n",
+       "  AmscoSlice(index=123, start=184, end=186),\n",
+       "  AmscoSlice(index=124, start=186, end=187),\n",
+       "  AmscoSlice(index=125, start=187, end=189)],\n",
+       " [AmscoSlice(index=126, start=189, end=191),\n",
+       "  AmscoSlice(index=127, start=191, end=192),\n",
+       "  AmscoSlice(index=128, start=192, end=194),\n",
+       "  AmscoSlice(index=129, start=194, end=195),\n",
+       "  AmscoSlice(index=130, start=195, end=197),\n",
+       "  AmscoSlice(index=131, start=197, end=198)],\n",
+       " [AmscoSlice(index=132, start=198, end=199),\n",
+       "  AmscoSlice(index=133, start=199, end=201),\n",
+       "  AmscoSlice(index=134, start=201, end=202),\n",
+       "  AmscoSlice(index=135, start=202, end=204),\n",
+       "  AmscoSlice(index=136, start=204, end=205),\n",
+       "  AmscoSlice(index=137, start=205, end=207)],\n",
+       " [AmscoSlice(index=138, start=207, end=209),\n",
+       "  AmscoSlice(index=139, start=209, end=210),\n",
+       "  AmscoSlice(index=140, start=210, end=212),\n",
+       "  AmscoSlice(index=141, start=212, end=213),\n",
+       "  AmscoSlice(index=142, start=213, end=215),\n",
+       "  AmscoSlice(index=143, start=215, end=216)],\n",
+       " [AmscoSlice(index=144, start=216, end=217),\n",
+       "  AmscoSlice(index=145, start=217, end=219),\n",
+       "  AmscoSlice(index=146, start=219, end=220),\n",
+       "  AmscoSlice(index=147, start=220, end=222),\n",
+       "  AmscoSlice(index=148, start=222, end=223),\n",
+       "  AmscoSlice(index=149, start=223, end=225)],\n",
+       " [AmscoSlice(index=150, start=225, end=227),\n",
+       "  AmscoSlice(index=151, start=227, end=228),\n",
+       "  AmscoSlice(index=152, start=228, end=230),\n",
+       "  AmscoSlice(index=153, start=230, end=231),\n",
+       "  AmscoSlice(index=154, start=231, end=233),\n",
+       "  AmscoSlice(index=155, start=233, end=234)],\n",
+       " [AmscoSlice(index=156, start=234, end=235),\n",
+       "  AmscoSlice(index=157, start=235, end=237),\n",
+       "  AmscoSlice(index=158, start=237, end=238),\n",
+       "  AmscoSlice(index=159, start=238, end=240),\n",
+       "  AmscoSlice(index=160, start=240, end=241),\n",
+       "  AmscoSlice(index=161, start=241, end=243)],\n",
+       " [AmscoSlice(index=162, start=243, end=245),\n",
+       "  AmscoSlice(index=163, start=245, end=246),\n",
+       "  AmscoSlice(index=164, start=246, end=248),\n",
+       "  AmscoSlice(index=165, start=248, end=249),\n",
+       "  AmscoSlice(index=166, start=249, end=251),\n",
+       "  AmscoSlice(index=167, start=251, end=252)],\n",
+       " [AmscoSlice(index=168, start=252, end=253),\n",
+       "  AmscoSlice(index=169, start=253, end=255),\n",
+       "  AmscoSlice(index=170, start=255, end=256),\n",
+       "  AmscoSlice(index=171, start=256, end=258),\n",
+       "  AmscoSlice(index=172, start=258, end=259),\n",
+       "  AmscoSlice(index=173, start=259, end=261)],\n",
+       " [AmscoSlice(index=174, start=261, end=263),\n",
+       "  AmscoSlice(index=175, start=263, end=264),\n",
+       "  AmscoSlice(index=176, start=264, end=266),\n",
+       "  AmscoSlice(index=177, start=266, end=267),\n",
+       "  AmscoSlice(index=178, start=267, end=269),\n",
+       "  AmscoSlice(index=179, start=269, end=270)],\n",
+       " [AmscoSlice(index=180, start=270, end=271),\n",
+       "  AmscoSlice(index=181, start=271, end=273),\n",
+       "  AmscoSlice(index=182, start=273, end=274),\n",
+       "  AmscoSlice(index=183, start=274, end=276),\n",
+       "  AmscoSlice(index=184, start=276, end=277),\n",
+       "  AmscoSlice(index=185, start=277, end=279)],\n",
+       " [AmscoSlice(index=186, start=279, end=281),\n",
+       "  AmscoSlice(index=187, start=281, end=282),\n",
+       "  AmscoSlice(index=188, start=282, end=284),\n",
+       "  AmscoSlice(index=189, start=284, end=285),\n",
+       "  AmscoSlice(index=190, start=285, end=287),\n",
+       "  AmscoSlice(index=191, start=287, end=288)],\n",
+       " [AmscoSlice(index=192, start=288, end=289),\n",
+       "  AmscoSlice(index=193, start=289, end=291),\n",
+       "  AmscoSlice(index=194, start=291, end=292),\n",
+       "  AmscoSlice(index=195, start=292, end=294),\n",
+       "  AmscoSlice(index=196, start=294, end=295),\n",
+       "  AmscoSlice(index=197, start=295, end=297)],\n",
+       " [AmscoSlice(index=198, start=297, end=299),\n",
+       "  AmscoSlice(index=199, start=299, end=300),\n",
+       "  AmscoSlice(index=200, start=300, end=302),\n",
+       "  AmscoSlice(index=201, start=302, end=303),\n",
+       "  AmscoSlice(index=202, start=303, end=305),\n",
+       "  AmscoSlice(index=203, start=305, end=306)],\n",
+       " [AmscoSlice(index=204, start=306, end=307),\n",
+       "  AmscoSlice(index=205, start=307, end=309),\n",
+       "  AmscoSlice(index=206, start=309, end=310),\n",
+       "  AmscoSlice(index=207, start=310, end=312),\n",
+       "  AmscoSlice(index=208, start=312, end=313),\n",
+       "  AmscoSlice(index=209, start=313, end=315)],\n",
+       " [AmscoSlice(index=210, start=315, end=317),\n",
+       "  AmscoSlice(index=211, start=317, end=318),\n",
+       "  AmscoSlice(index=212, start=318, end=320),\n",
+       "  AmscoSlice(index=213, start=320, end=321),\n",
+       "  AmscoSlice(index=214, start=321, end=323),\n",
+       "  AmscoSlice(index=215, start=323, end=324)],\n",
+       " [AmscoSlice(index=216, start=324, end=325),\n",
+       "  AmscoSlice(index=217, start=325, end=327),\n",
+       "  AmscoSlice(index=218, start=327, end=328),\n",
+       "  AmscoSlice(index=219, start=328, end=330),\n",
+       "  AmscoSlice(index=220, start=330, end=331),\n",
+       "  AmscoSlice(index=221, start=331, end=333)],\n",
+       " [AmscoSlice(index=222, start=333, end=335),\n",
+       "  AmscoSlice(index=223, start=335, end=336),\n",
+       "  AmscoSlice(index=224, start=336, end=338),\n",
+       "  AmscoSlice(index=225, start=338, end=339),\n",
+       "  AmscoSlice(index=226, start=339, end=341),\n",
+       "  AmscoSlice(index=227, start=341, end=342)],\n",
+       " [AmscoSlice(index=228, start=342, end=343),\n",
+       "  AmscoSlice(index=229, start=343, end=345),\n",
+       "  AmscoSlice(index=230, start=345, end=346),\n",
+       "  AmscoSlice(index=231, start=346, end=348),\n",
+       "  AmscoSlice(index=232, start=348, end=349),\n",
+       "  AmscoSlice(index=233, start=349, end=351)],\n",
+       " [AmscoSlice(index=234, start=351, end=353),\n",
+       "  AmscoSlice(index=235, start=353, end=354),\n",
+       "  AmscoSlice(index=236, start=354, end=356),\n",
+       "  AmscoSlice(index=237, start=356, end=357),\n",
+       "  AmscoSlice(index=238, start=357, end=359),\n",
+       "  AmscoSlice(index=239, start=359, end=360)],\n",
+       " [AmscoSlice(index=240, start=360, end=361),\n",
+       "  AmscoSlice(index=241, start=361, end=363),\n",
+       "  AmscoSlice(index=242, start=363, end=364),\n",
+       "  AmscoSlice(index=243, start=364, end=366),\n",
+       "  AmscoSlice(index=244, start=366, end=367),\n",
+       "  AmscoSlice(index=245, start=367, end=369)],\n",
+       " [AmscoSlice(index=246, start=369, end=371),\n",
+       "  AmscoSlice(index=247, start=371, end=372),\n",
+       "  AmscoSlice(index=248, start=372, end=374),\n",
+       "  AmscoSlice(index=249, start=374, end=375),\n",
+       "  AmscoSlice(index=250, start=375, end=377),\n",
+       "  AmscoSlice(index=251, start=377, end=378)],\n",
+       " [AmscoSlice(index=252, start=378, end=379),\n",
+       "  AmscoSlice(index=253, start=379, end=381),\n",
+       "  AmscoSlice(index=254, start=381, end=382),\n",
+       "  AmscoSlice(index=255, start=382, end=384),\n",
+       "  AmscoSlice(index=256, start=384, end=385),\n",
+       "  AmscoSlice(index=257, start=385, end=387)],\n",
+       " [AmscoSlice(index=258, start=387, end=389),\n",
+       "  AmscoSlice(index=259, start=389, end=390),\n",
+       "  AmscoSlice(index=260, start=390, end=392),\n",
+       "  AmscoSlice(index=261, start=392, end=393),\n",
+       "  AmscoSlice(index=262, start=393, end=395),\n",
+       "  AmscoSlice(index=263, start=395, end=396)],\n",
+       " [AmscoSlice(index=264, start=396, end=397),\n",
+       "  AmscoSlice(index=265, start=397, end=399),\n",
+       "  AmscoSlice(index=266, start=399, end=400),\n",
+       "  AmscoSlice(index=267, start=400, end=402),\n",
+       "  AmscoSlice(index=268, start=402, end=403),\n",
+       "  AmscoSlice(index=269, start=403, end=405)],\n",
+       " [AmscoSlice(index=270, start=405, end=407),\n",
+       "  AmscoSlice(index=271, start=407, end=408),\n",
+       "  AmscoSlice(index=272, start=408, end=410),\n",
+       "  AmscoSlice(index=273, start=410, end=411),\n",
+       "  AmscoSlice(index=274, start=411, end=413),\n",
+       "  AmscoSlice(index=275, start=413, end=414)],\n",
+       " [AmscoSlice(index=276, start=414, end=415),\n",
+       "  AmscoSlice(index=277, start=415, end=417),\n",
+       "  AmscoSlice(index=278, start=417, end=418),\n",
+       "  AmscoSlice(index=279, start=418, end=420),\n",
+       "  AmscoSlice(index=280, start=420, end=421),\n",
+       "  AmscoSlice(index=281, start=421, end=423)],\n",
+       " [AmscoSlice(index=282, start=423, end=425),\n",
+       "  AmscoSlice(index=283, start=425, end=426),\n",
+       "  AmscoSlice(index=284, start=426, end=428),\n",
+       "  AmscoSlice(index=285, start=428, end=429),\n",
+       "  AmscoSlice(index=286, start=429, end=431),\n",
+       "  AmscoSlice(index=287, start=431, end=432)],\n",
+       " [AmscoSlice(index=288, start=432, end=433),\n",
+       "  AmscoSlice(index=289, start=433, end=435),\n",
+       "  AmscoSlice(index=290, start=435, end=436),\n",
+       "  AmscoSlice(index=291, start=436, end=438),\n",
+       "  AmscoSlice(index=292, start=438, end=439),\n",
+       "  AmscoSlice(index=293, start=439, end=441)],\n",
+       " [AmscoSlice(index=294, start=441, end=443),\n",
+       "  AmscoSlice(index=295, start=443, end=444),\n",
+       "  AmscoSlice(index=296, start=444, end=446),\n",
+       "  AmscoSlice(index=297, start=446, end=447),\n",
+       "  AmscoSlice(index=298, start=447, end=449),\n",
+       "  AmscoSlice(index=299, start=449, end=450)],\n",
+       " [AmscoSlice(index=300, start=450, end=451),\n",
+       "  AmscoSlice(index=301, start=451, end=453),\n",
+       "  AmscoSlice(index=302, start=453, end=454),\n",
+       "  AmscoSlice(index=303, start=454, end=456),\n",
+       "  AmscoSlice(index=304, start=456, end=457),\n",
+       "  AmscoSlice(index=305, start=457, end=459)],\n",
+       " [AmscoSlice(index=306, start=459, end=461),\n",
+       "  AmscoSlice(index=307, start=461, end=462),\n",
+       "  AmscoSlice(index=308, start=462, end=464),\n",
+       "  AmscoSlice(index=309, start=464, end=465),\n",
+       "  AmscoSlice(index=310, start=465, end=467),\n",
+       "  AmscoSlice(index=311, start=467, end=468)],\n",
+       " [AmscoSlice(index=312, start=468, end=469),\n",
+       "  AmscoSlice(index=313, start=469, end=471),\n",
+       "  AmscoSlice(index=314, start=471, end=472),\n",
+       "  AmscoSlice(index=315, start=472, end=474),\n",
+       "  AmscoSlice(index=316, start=474, end=475),\n",
+       "  AmscoSlice(index=317, start=475, end=477)],\n",
+       " [AmscoSlice(index=318, start=477, end=479),\n",
+       "  AmscoSlice(index=319, start=479, end=480),\n",
+       "  AmscoSlice(index=320, start=480, end=482),\n",
+       "  AmscoSlice(index=321, start=482, end=483),\n",
+       "  AmscoSlice(index=322, start=483, end=485),\n",
+       "  AmscoSlice(index=323, start=485, end=486)],\n",
+       " [AmscoSlice(index=324, start=486, end=487),\n",
+       "  AmscoSlice(index=325, start=487, end=489),\n",
+       "  AmscoSlice(index=326, start=489, end=490),\n",
+       "  AmscoSlice(index=327, start=490, end=492),\n",
+       "  AmscoSlice(index=328, start=492, end=493),\n",
+       "  AmscoSlice(index=329, start=493, end=495)],\n",
+       " [AmscoSlice(index=330, start=495, end=497),\n",
+       "  AmscoSlice(index=331, start=497, end=498),\n",
+       "  AmscoSlice(index=332, start=498, end=500),\n",
+       "  AmscoSlice(index=333, start=500, end=501),\n",
+       "  AmscoSlice(index=334, start=501, end=503),\n",
+       "  AmscoSlice(index=335, start=503, end=504)],\n",
+       " [AmscoSlice(index=336, start=504, end=505),\n",
+       "  AmscoSlice(index=337, start=505, end=507),\n",
+       "  AmscoSlice(index=338, start=507, end=508),\n",
+       "  AmscoSlice(index=339, start=508, end=510),\n",
+       "  AmscoSlice(index=340, start=510, end=511),\n",
+       "  AmscoSlice(index=341, start=511, end=513)],\n",
+       " [AmscoSlice(index=342, start=513, end=515),\n",
+       "  AmscoSlice(index=343, start=515, end=516),\n",
+       "  AmscoSlice(index=344, start=516, end=518),\n",
+       "  AmscoSlice(index=345, start=518, end=519),\n",
+       "  AmscoSlice(index=346, start=519, end=521),\n",
+       "  AmscoSlice(index=347, start=521, end=522)],\n",
+       " [AmscoSlice(index=348, start=522, end=523),\n",
+       "  AmscoSlice(index=349, start=523, end=525),\n",
+       "  AmscoSlice(index=350, start=525, end=526),\n",
+       "  AmscoSlice(index=351, start=526, end=528),\n",
+       "  AmscoSlice(index=352, start=528, end=529),\n",
+       "  AmscoSlice(index=353, start=529, end=531)],\n",
+       " [AmscoSlice(index=354, start=531, end=533),\n",
+       "  AmscoSlice(index=355, start=533, end=534),\n",
+       "  AmscoSlice(index=356, start=534, end=536),\n",
+       "  AmscoSlice(index=357, start=536, end=537),\n",
+       "  AmscoSlice(index=358, start=537, end=539),\n",
+       "  AmscoSlice(index=359, start=539, end=540)],\n",
+       " [AmscoSlice(index=360, start=540, end=541),\n",
+       "  AmscoSlice(index=361, start=541, end=543),\n",
+       "  AmscoSlice(index=362, start=543, end=544),\n",
+       "  AmscoSlice(index=363, start=544, end=546),\n",
+       "  AmscoSlice(index=364, start=546, end=547),\n",
+       "  AmscoSlice(index=365, start=547, end=549)],\n",
+       " [AmscoSlice(index=366, start=549, end=551),\n",
+       "  AmscoSlice(index=367, start=551, end=552),\n",
+       "  AmscoSlice(index=368, start=552, end=554),\n",
+       "  AmscoSlice(index=369, start=554, end=555),\n",
+       "  AmscoSlice(index=370, start=555, end=557),\n",
+       "  AmscoSlice(index=371, start=557, end=558)],\n",
+       " [AmscoSlice(index=372, start=558, end=559),\n",
+       "  AmscoSlice(index=373, start=559, end=561),\n",
+       "  AmscoSlice(index=374, start=561, end=562),\n",
+       "  AmscoSlice(index=375, start=562, end=564),\n",
+       "  AmscoSlice(index=376, start=564, end=565),\n",
+       "  AmscoSlice(index=377, start=565, end=567)],\n",
+       " [AmscoSlice(index=378, start=567, end=569),\n",
+       "  AmscoSlice(index=379, start=569, end=570),\n",
+       "  AmscoSlice(index=380, start=570, end=572),\n",
+       "  AmscoSlice(index=381, start=572, end=573),\n",
+       "  AmscoSlice(index=382, start=573, end=575),\n",
+       "  AmscoSlice(index=383, start=575, end=576)],\n",
+       " [AmscoSlice(index=384, start=576, end=577),\n",
+       "  AmscoSlice(index=385, start=577, end=579),\n",
+       "  AmscoSlice(index=386, start=579, end=580),\n",
+       "  AmscoSlice(index=387, start=580, end=582),\n",
+       "  AmscoSlice(index=388, start=582, end=583),\n",
+       "  AmscoSlice(index=389, start=583, end=585)],\n",
+       " [AmscoSlice(index=390, start=585, end=587),\n",
+       "  AmscoSlice(index=391, start=587, end=588),\n",
+       "  AmscoSlice(index=392, start=588, end=590),\n",
+       "  AmscoSlice(index=393, start=590, end=591),\n",
+       "  AmscoSlice(index=394, start=591, end=593),\n",
+       "  AmscoSlice(index=395, start=593, end=594)],\n",
+       " [AmscoSlice(index=396, start=594, end=595),\n",
+       "  AmscoSlice(index=397, start=595, end=597),\n",
+       "  AmscoSlice(index=398, start=597, end=598),\n",
+       "  AmscoSlice(index=399, start=598, end=600),\n",
+       "  AmscoSlice(index=400, start=600, end=601),\n",
+       "  AmscoSlice(index=401, start=601, end=603)],\n",
+       " [AmscoSlice(index=402, start=603, end=605),\n",
+       "  AmscoSlice(index=403, start=605, end=606),\n",
+       "  AmscoSlice(index=404, start=606, end=608),\n",
+       "  AmscoSlice(index=405, start=608, end=609),\n",
+       "  AmscoSlice(index=406, start=609, end=611),\n",
+       "  AmscoSlice(index=407, start=611, end=612)]]"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "amsco_transposition_positions(c7b, 'abcdef', \n",
+    "      fillpattern=(1, 2),\n",
+    "      fillstyle=AmscoFillStyle.reverse_each_row)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['stager',\n",
+       " 'staler',\n",
+       " 'stalin',\n",
+       " 'stamen',\n",
+       " 'sucker',\n",
+       " 'tucker',\n",
+       " 'twangs',\n",
+       " 'twerps',\n",
+       " 'twirls',\n",
+       " 'staffer',\n",
+       " 'stagers',\n",
+       " 'stagger',\n",
+       " 'stalins',\n",
+       " 'stamens',\n",
+       " 'stamina',\n",
+       " 'stammer',\n",
+       " 'statler',\n",
+       " 'suckers',\n",
+       " 'sudsier',\n",
+       " 'swagger',\n",
+       " 'tubbier',\n",
+       " 'tycoons',\n",
+       " 'loadable',\n",
+       " 'noblemen',\n",
+       " 'rubidium',\n",
+       " 'staffers',\n",
+       " 'staggers',\n",
+       " 'staminas',\n",
+       " 'stammers',\n",
+       " 'standard',\n",
+       " 'steelier',\n",
+       " 'submerse',\n",
+       " 'swaggers',\n",
+       " 'tubbiest',\n",
+       " 'tuitions',\n",
+       " 'twenties',\n",
+       " 'stalemate',\n",
+       " 'staleness',\n",
+       " 'stalinist',\n",
+       " 'stammerer',\n",
+       " 'standards',\n",
+       " 'submerses',\n",
+       " 'swaggerer',\n",
+       " 'stalemates',\n",
+       " 'stalenesss',\n",
+       " 'stammerers',\n",
+       " 'stepsister',\n",
+       " 'succulence',\n",
+       " 'statistical',\n",
+       " 'stepsisters',\n",
+       " 'succulences',\n",
+       " 'statistician',\n",
+       " 'statisticians']"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "transpositions[key_b[0]]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "security protocol solitaire comrades under a decree from moscow we are confined to using a new high security stream cipher stolen from the americans the solitaire cipher all files classified top secret and above are to be archived using this method this new field cipher has been tested and proven to match the security of the fi alka machine without the overhead of the technology you will need only a deck of cards to implement the cipher the key to be used will be provided and distributed on a one time pad and you must destroy the key as you use it the key consists of a random shuffle of a full deck of cards together with two distinguishable jokers agents should be freely able to carry this equipment without arousing suspicion\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(' '.join(segment(sanitise(\n",
+    "                amsco_transposition_decipher(sanitise(c7b), \n",
+    "                                             keyword=transpositions[key_b[0]][0], \n",
+    "                                             fillpattern=key_b[1],\n",
+    "                                             fillstyle=key_b[2])\n",
+    "            ))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/2015/2015-challenge8.ipynb b/2015/2015-challenge8.ipynb
new file mode 100644 (file)
index 0000000..9ab6fdc
--- /dev/null
@@ -0,0 +1,114 @@
+{
+ "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.vigenere import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "\n",
+    "c8a = sanitise(open('8a.ciphertext').read())\n",
+    "c8b = sanitise(open('8b.ciphertext').read())"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('charlie', -2104.8140749325567)"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score = vigenere_frequency_break(c8a)\n",
+    "key_a, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "harry i am so sorry we went into the russian hq last night without you but the station chief wanted\n",
+      "it to be his team that got the glory i am really grateful to you for coming back and putting us on\n",
+      "the right track though the stolen file from soviet headquarters was as you expected encrypted with\n",
+      "the solitaire cipher fortunately the cipher clerk who managed the encryption was incredibly careless\n",
+      "i found a sheet of burnt paper in the bin which gave me a list of thirty eight cards and i am hoping\n",
+      "that this is a large part of the key it will still be hard to break but maybe not impossible\n",
+      "especially as the erased part was still intact there maybe another clue in that the page appears to\n",
+      "have been torn from an economics textbook i found on the desk anyway i figure the chemists at\n",
+      "langley may help us to reconstruct the whole key given time though i wouldnt expect them to manage\n",
+      "more than one card a day given how careful they will have to be not to destroy the document it will\n",
+      "take usa while to crack this but maybe time is on our side with christmas things seem to be quiet\n",
+      "and i am hoping that within the next three weeks we may know precisely what the soviets were trying\n",
+      "to do here whatever the outcome i think it is clear that the future of europe is not likely to be\n",
+      "settled for a while i hear rumours everyday about shortages in the soviet bloc and border controls\n",
+      "are going up in places you wouldnt expect to prevent largescale migration there are problems in\n",
+      "greece and turkey and divisions between the british and french and the brits are having real trouble\n",
+      "paying off their war debts whether or not we crack the reichs doktor mystery i think there is going\n",
+      "to be plenty for you to do i know we had to work hard to persuade you to flyover but we really do\n",
+      "need you here even the chief recognizes that so if i can i want to persuade you to stay francois and\n",
+      "i are being posted to paris kind of a thankyou for our work on this project but icant go unless i\n",
+      "know the berlin station has someone i trust hope youll agree to take the job charlie\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(vigenere_decipher(c8a, key_a)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/2015/2a.ciphertext b/2015/2a.ciphertext
new file mode 100644 (file)
index 0000000..46aac34
--- /dev/null
@@ -0,0 +1,3 @@
+RWPGAXT, CD CTTS ID PEDADVXHT, AXUT LPH VTIIXCV SJAA QTWXCS P STHZ PCS X LPH VAPS ID WPKT PC TMRJHT ID UAN QPRZ ID TJGDET. X PB XCIGXVJTS PQDJI IWT GTXRWHSDZIDG - X WPSC’I RDBT PRGDHH IWXH QTUDGT, LWTC SXS NDJ UXGHI RDBT WTPG DU XI? 
+X IWXCZ X BPN PAGTPSN QT BPZXCV HDBT EGDVGTHH. DC PGGXKPA X UDJCS P EDHIRPGS LPXIXCV UDG BT DC IWT BPI PI IWT TBQPHHN LXIW CD BTHHPVT DC XI . PI ATPHI IWPI’H LWPI XI ADDZTS AXZT PI UXGHI. X SXS CDIXRT IWPI IWT ATIITGH DC IWT UGDCI RDJAS QT WXVWAXVWITS ID EXRZ DJI IWT EWGPHT IWT GTXRWHSDZIDG HD JCATHH IWPI XH PC TMIGPDGSXCPGN RDXCRXSTCRT X UXVJGTS XI BJHI QT GTAPITS ID DJG XCKTHIXVPIXDC. IWT HIGPCVTHI IWXCV LPH IWPI IWT EDHIRPGS WPS P HIPBE QJI CD EDHIBPGZ DC XI, HD XI RPC’I WPKT QTTC EDHITS. HXCRT XI LPHC’I HXVCTS X PHHJBT IWTN LPCITS ID HIPN PCDCNBDJH PCS X RDJASC’I HTT LWN IWTN LDJAS WPKT IPZTC IWT GXHZ DU WPCS STAXKTGXCV XI, QJI XC IWT TCS X LDGZTS XI DJI. IWTGT LPH P WXSSTC BTHHPVT. X’AA ATPKT XI ID NDJ ID UXVJGT DJI LWTGT XI LPH WXSSTC. PCNLPN X’KT PIIPRWTS IWT BTHHPVT X UDJCS. X ZCDL IWPI GTAPIXDCH LXIW IWGTT DU IWT UDJG EDLTGH PGT GTAPIXKTAN HIPQAT, QJI X IWXCZ LT CTTS ID ZTTE IWXH ID DJGHTAKTH UDG CDL. PAA IWT QTHI, 
+WPGGN
diff --git a/2015/2b.ciphertext b/2015/2b.ciphertext
new file mode 100644 (file)
index 0000000..b80a509
--- /dev/null
@@ -0,0 +1 @@
+DATJP MZVGG TRVIO OJBZO DIOCZ HDYYG ZJAOC DNTJP RDGGC VQZOJ KVTDF IJRTJ PRDGG WZCPI ODIBH ZVIYD XVIAJ MBDQZ OCZVM MJBVI XZWPO DRDGG IJOAJ MBDQZ TJPMD BIJMV IXZWZ AJMZT JPXVI GZVMI HJMZV WJPOO CZMVO GDIZN AMJHH ZTJPR DGGCV QZOJV NFTJP MXJGG ZVBPZ NDIAM ZIXCV IYWMD ODNCD IOZGG DBZIX ZRCVO OCZTV GMZVY TFIJR KJRZM APGAJ MXZNV MZRJM FDIBO JFZZK OCZMV OGDIZ NMPII DIBVI YRZWJ OCIZZ YOJFI JRRCJ JPMZI ZHDZN VMZWZ AJMZR ZXVIH ZZOTJ PNCJP GYPIY ZMNOV IYOCV ORDOC JPOHZ TJPMD IQZNO DBVOD JINRD GGBVD IGDOO GZIZB JODVO DJINR DOCHZ HVTBV DIZQZ MTOCD IB 
diff --git a/2015/3a.ciphertext b/2015/3a.ciphertext
new file mode 100644 (file)
index 0000000..56faecc
--- /dev/null
@@ -0,0 +1 @@
+CHGGB, MCT APEEOT XW MCT JMHRATQ AXJMNHGQ CHQ RT WXXOTQ WXG H VCFOT, KPM F MCFUL F WFZPGTQ FM XPM. VHJ MCT RTJJHZT XU MCT KHNL XW MCT JMHRA? F HR ZPTJJFUZ BXP JMTHRTQ FM XWW HUQ WXPUQ FM MCTGT. FM VHJ H AGTMMB FUZTUFXPJ AOXB. RB RHJMTGJ KHNL FU VHJCFUZMXU HGT FUNGTHJFUZOB VXGGFTQ HKXPM XPG GTOHMFXUJCFA VFMC MCT GTJM XW MCT WXPG AXVTGJ. WXOOXVFUZ MCT KGTHLQXVU FU MGPJM VFMC MCT JXSFTMJ MCTB HGT NXPUMFUZ XU MCT PL HUQ WGHUNT HJ HOOFTJ. FW MCTB HGT ZXFUZ KTCFUQ XPG KHNLJ VFMC MCFJ GTFNCJQXLMXG, MCHM QXTJ UXM KXQT VTOO WXG WPMPGT QFAOXRHNB. QX BXP CHST NXUMHNMJ MCTGT BXP NHU TYAOXFM MX WFUQ XPM VCHM MCTB HGT FUMTUQFUZ? VT GTHOOB NHUUXM HWWXGQ MX WHOO XPM GFZCM UXV. MCT HMMHNCTQ RTJJHZT FJ HUXMCTG FUMTGNTAM, MCFJ MFRT WGXR MCT KGFMFJC TRKHJJB VFGTOTJJ. VCFOT MCFUZJ HGT QFNTB F QXU’M WTTO F NHU HJL MCTR HKXPM FM, RHBKT BXP NXPOQ NGHNL FM WXG PJ. QXTJ FM RTUMFXU MCT GHMOFUTJ? KTJM, NCHGOFT
diff --git a/2015/3b.ciphertext b/2015/3b.ciphertext
new file mode 100644 (file)
index 0000000..de9a457
--- /dev/null
@@ -0,0 +1 @@
+FBFXD YOBSH TDHSX DKLXD HSVFZ YQFSO ZYRZC ULVVF XXCDC UFSLC OZYFX XDHSV FXFFT XCDPD QBYLT FDKSF ZVUXA DJCDS SHXXZ LYZYC FSVFI CXXHP PFXCU LXQFF YXFFY ZYMZV ZYZCB DKHXF TQLXX BYDCV OFLSU DRCDT LJFAZ SFVCV DYCLV CLOXD YDCVO FLSRU BDHSH XKSZF YAXLS FJFFI ZYPCU ZXCDC UFTXF OMFXA FCLZO FAZYK DLQDH CSLCZ OZYFX ULSAC DDQCL ZYQHC UZPUM LOHFV DHOAO FLACD LSSFX CDKTL EDSCL SPFCX DKYHS FTQFS PZYMF XCZPL CZDYX MZCLO RFSFL VUSFZ VUXAD JCDSL CFLSO ZFXCD IIDSC HYZCB AZXVS FFCFY NHZSZ FXZYK SFYVU LYAHX XFVCD SXDYO BSFNH FXCKH YAXKD SKHSC UFSZY MFXCZ PLCZD Y 
diff --git a/2015/4a.ciphertext b/2015/4a.ciphertext
new file mode 100644 (file)
index 0000000..6db3a2e
--- /dev/null
@@ -0,0 +1 @@
+TSRFXUI, HSI RHHRTSIL ZBHI MRG XINH UZ BZI BN YP LIRL LFBCG XRGH ZUESH RZL RCCIRFG HB AI NFBY BJF YPGHIFUBJG GBJFTI. UH TBZHRUZG HMB FIRXXP GUEZUNUTRZH CUITIG BN UZHIXXUEIZTI. HSI NUFGH UG HSRH HSI FUITSGLBWHBF YUESH ZBH FINIF HB RZ UZLUKULJRX RNHIF RXX. UH GIIYG HB AI HSI TBLIZRYI NBF HSI BFERZUQRHUBZ FJZZUZE HSI FRHXUZIG. RTTBFLUZE HB YP BHSIF GBJFTIG HSUG UG R TBXXITHUBZ BN FBJHIG, REIZHG RZL GRNI SBJGIG JGIL HB HFRZGCBFH ZRQU GPYCRHSUGIFG RZL MRF TFUYUZRXG BJH BN EIFYRZP RZL BZ HB GBJHS RYIFUTR. MI SRKI WZBMZ HSRH GJTS RZ BFERZUGRHUBZ IOUGHG GUZTI HSI IZL BN HSI MRF, AJH HSUG UG HSI NUFGH HUYI U SRKI GIIZ UH ZRYIL. HSI BHSIF CUITI BN UZNBFYRHUBZ UG YJTS YBFI GJAHXI. U RY AIEUZZUZE HB MBZLIF UN BJF GBJFTI UG TXBGIF HB SBYI HSRZ MI SRL FIRXUGIL. RZL U RY ZBH FINIFFUZE HB NFRZTBUG! GII UN PBJ TRZ GCBH HSI HMB HSUZEG U ZBHUTIL. AP HSI MRP, MSB HFRZGTFUAIL HSI FRLUB UZHIFTICH PBJ GIZH YI XRGH MIIW? SRFFP
diff --git a/2015/4b.ciphertext b/2015/4b.ciphertext
new file mode 100644 (file)
index 0000000..be1314d
--- /dev/null
@@ -0,0 +1 @@
+HSCOE CYASX FPRCP ZJEFW WTCGR JHHSC PFECY ZHPZJ EOETC YNGHS CPBWF YHZTY OTWHE FHCHS CEFHT WTYCG FYNHZ HEPHZ HJEYH SCSTI SKFWJ CHFEI CHGOZ EHSCX GCWKC GHSCP SFKCF BFEHT AJWFE TYHCE CGHTY YFQTG ATCYH TGHGO EZXHS CNTCF WASCX TGHCY BEZUC AHTOP ZJLFY HHZRE CFVHS CECTA SGNZV HZEYC HLZEV RCOZE CHSCP AFYNZ GZHFV CAFEC YZHHZ GSFEC FYPTY HCWWT ICYAC LTHSH SCXPZ JSFKC RCCYL FEYCN THSTY VTHTG HTXCH ZRCIT YYCIZ HTFHT ZYGTS FKCFY JXRCE TYXTY NFYNT HSTYV ZYACP ZJVYZ LLSFH TFXZO OCETY IPZJL TWWOT YNTHK CEPEC FGZYF RWCFG FGTIY ZOIZZ NOFTH STZOO CEPZJ HSCOZ WWZLT YITYO ZEXFH TZYZY CZOHS CWZAF WEFHT WTYCA ZZENT YFHZE GLTWW RCWCF KTYIH SCJGG CAHZE HZXZE EZLYT ISHTY FRWFA VWTXZ JGTYC JYNCE HSCRF AVGCF HZOST GAFEP ZJLTW WOTYN STNNC YFUJY TZEGG ZOOTA CELSZ TGHEP TYIHZ CGAFB CFYNT YHSCH EJYVP ZJLTW WOTYN FYJXR CEZOB FBCEG ECWFH TYIHZ GHZWC YFEHL ZEVGH SFHSC SZBCG HZHEF NCHZH SCOEC YASOZ ESTGO ECCNZ XPZJX TISHL FYHHZ AZYGT NCEAF ECOJW WPLSC HSCEP ZJAFY HEJGH PZJEO ETCYN ASFEW TCLTH SHSTG TYOZE XFHTZ YFOHC EFWWS CESJG RFYNO EFYAZ TGTGO ECYAS
diff --git a/2015/5a.ciphertext b/2015/5a.ciphertext
new file mode 100644 (file)
index 0000000..1d7ad3f
--- /dev/null
@@ -0,0 +1,9 @@
+LCAAP, D RLFRTFN XHG KLX GACWBRADOFN GLF ACNDX GACWBVDBBDXW UDTF PXH CBTFN. DG KCB C SHWDXA RDYLFA RUFAT DW AXXV 5. D KXHUN LCJF XIIFAFN GX BFG HY C VFFGDWE KDGL LFA, OHG BLF LCB NDBCYYFCAFN CWN LCBW’G OFFW BFFW BDWRF UCBG IADNCP. GLF VCADWFB BCK LFA UFCJF CG LFA HBHCU GDVF, CWN BLF KCB OXXTFN XHG IXA BXVF UFCJF XW VXWNCP CWN GHFBNCP BX WX XWF WXGDRFN BLF KCB VDBBDWE HWGDU GXNCP. KF BFWG CW XIIDRFA XHG GX LFA HBHCU LCHWGB CWN D KDUU EFG OCRT GX PXH DI KF IDWN CWPGLDWE. KLCG VCNF PXH CBT? NDN PXH LCJF C AFCBXW GX OFUDFJF BLF KCB DWJXUJFN DW BXVFGLDWE? 
+
+D GXXT CWXGLFA UXXT CG GLF VFBBCEFB. KFAF PXH AFIFAADWE GX GLF GPYXB? GLF KXAN ACGUDWFB TFFYB OFDWE BYFUG CB ACGDUDWFB. DB GLCG DVYXAGCWG? KLCG NDN PXH VFCW COXHG XHA BXHARF OFDWE RUXBF GX LXVF? 
+
+CUBX NDN BXVF NDEEDWE COXHG GLF AFDRLBNXTGXA. BFFVB PXH KFAF ADELG CWN DG AFIFAB GX CW HWNFAEAXHWN WCQD XAECWDBCGDXW NFNDRCGFN GX AFOHDUNDWE GLF AFDRL. VCPOF GLFP GLDWT XI DG CB LFCUDWE? C OHWRL XI ADRL WCQD BPVYCGLDBFAB GXXT XJFA GLF ACGUDWFB IAXV C EAXHY XI BB XIIDRFAB KLX BFG GLFV HY CG GLF GCDU XI GLF KCA CWN LCJF OFFW CRGDJF DW BLDYYDWE BRDFWGDBGB, FWEDWFFAB CWN BXUNDFAB GX GXKWB CRAXBB BXHGL CVFADRC. DI XHA BXHARF LCB DWBDNF DWIXAVCGDXW GLFW VCPOF KF RXHUN DWGFARFYG GLF UDWFB CWN YDRT HY BXVF XI GLF LDEL JCUHF GCAEFGB GLF IAFWRL CAF CIGFA. KLCG KCB “NDF CURLFVDBGFW YAXSFRG”? 
+
+GLF FWRUXBFN VFBBCEF KCB LCWNFN GX GLF VCADWFB, OHG GLFP NDNW’G EFG C WCVF. DWDGDCU CWCUPBDB BLXKB DG VHBG OF C JDEFWFAF RDYLFA KDGL YFADXN GKX BX DG BLXHUN OF AFCBXWCOUP BGACDELGIXAKCAN GX RACRT. 
+
+CUU GLF OFBG, RLCAUDF 
diff --git a/2015/5b.ciphertext b/2015/5b.ciphertext
new file mode 100644 (file)
index 0000000..9fc6ddb
--- /dev/null
@@ -0,0 +1 @@
+WLHJL VVXLX HQLRR YUPLX WPHEX GWMRR ZMOPE IWLHP RGDXL SQSIE VEIIK SXWHM QXKIX OVIFX RVRJE IUPLR LXLWD QLRRV VXRTR ZHVRR WLHVD XOMQI VFXXB SXRHZ HVNRR ABSXQ LKKXJ IWPXG NCDRG JLRGW RQHSQ ILRWI UIVXL RJLLH LRJXK IUIDX WLHZH VBPHE VXBSX ALPOM QGRRY IQMHR FIWLH VHMFL VHROW SUMIC RYWEN ISSVW HWVMR RRJLX KSZQX GKARY OHWLD XEIZS UXKXR CRYGS LLHEU EEMGS IJLZH LXRGV HHWLR YVEQH IVDRF WIVRQ RYUJU IQGKJ UMHRG WSIUL DTVXK IEVLX LWKAR YOHSE BQRVH SUQDC EIWLH CFEQR RXDJI SUHWS LARRG IULRA WLHCI IHPDF RYWXK EWTHV KESWB SXWKS XPGEV OWLHQ LJBSX ADRWX RSXXE MGCRY UWRGD POIGJ UMHRG WWLHR OIDZH XKIPS QIBMQ YQQDV NIGXU IDWXV BFLPO WLROS FOHVD XWLHJ DVHRG SIXKI SPDXI SUQLR IVLIG VLGKW WVDWV ILALP OPHEY IWLHH HXDMO WLROS FOHVB SXALP OJLRG XKINI BMQHR RRXWV BXRHR YEPHG USVWP ILXZM OPQSW ARVNE QHRYU PLXWP HKDQH ALPOI QHEII SUILX KEVIY IQTUS SIUPB FHKXR
diff --git a/2015/6a.ciphertext b/2015/6a.ciphertext
new file mode 100644 (file)
index 0000000..631351d
--- /dev/null
@@ -0,0 +1 @@
+ICRDV SFSHM RGHCF HPZYS XDRHS VSXFG HCRHN RKFSH RMRPS HRZZF RDFLA YHCSX HCFHP ZFLWF GGRNF GMFZS IUFLJ ZRXLS XHCFH DRXGI DSZHY EHCFD RLSYW FGGRN FZDFH HPJXV SUFVP IYSXI SLFXI FGYSE SNJDF PYJDT JXSYD ISZCF DIVFD UMRGS XKYVK FLWSN CHAFM YDHCI CFIUS XNCFD ARIUN DYJXL RXLAR XURII YJXHG HCRHS GRVVS WFRXH MCFXS GRSLH CFGYJ DIFMR GIVYG FHYCY WFAJH HCSXU SXNRA YJHSH SRWXY HGJDF SHWRU FGGFX GFHYH CSXUG CFMRG HCFGY JDIFH CFWFG GRNFG GHSVV UFFZI YWSXN RXLSR WNJFG GSXNH CRHGC FCRGN YXFGY HCFDF WJGHA FGYWF YHCFD GYJDI FEYDY JDSXH FVVSN FXIFG YWFHC SXNSG AYHCF DSXNW FRAYJ HHCFH YXFYE HCFWF GGRNF GMCPL YFGYJ DRXHR NYXSG HUFFZ HRJXH SXNJG RAYJH YJDRV VSFGS HSGXY HVSUF HCFHC SXNGM FRDFA FSXNR GUFLH YASLE YDRDF HCSXN GMFRD FVSUF VPHYC SLFED YWYXF RXYHC FDREH FDRVV RXPMR PSEYV VYMFL YXFYE YJDED FXICI YVVFR NJFGH YEDSF LDSIC GHDRG GFRXL MRHIC FLCFD HDPHY ZSIUJ ZHCFU FPEDY WVYIU FDGFF WGHYC RKFAF FXRIY XSIYJ VLXHI VFRDV PGFFM CRHMR GNYSX NYXAJ HGCFL SLXHG FFWHY AFRAV FHYYZ FXVYI UFDRX LVFEH YAKSY JGVPJ ZGFHR EHFDG CFCRL NYXFS HYYUR VYYUR HVYIU FDSHC RGRER VGFAR IUGYS RWNJF GGSXN HCFWY XFPMR GHRUF XAJHX YHCSX NZDYK SLFLS XFOIC RXNFI YJVLP YJLSN RDYJX LMSHC PYJDI YXHRI HGSXH CFADS HSGCR XLDJG GSRXF WARGG SFGRX LGFFS EHCFP RDFNF HHSXN HCFGR WFGYD HYEIY WWJXS IRHSY XGWRP AFPYJ IYJVL MRDXH CFWAP HCFMR PLSFR VICFW SGHFX ZDYTF IHMRG HCFIY LFXRW FEYDH CFXRQ SRHYW AYWAF EEYDH SCRLR DJXSX MSHCH CFWLJ DSXNH CFMRD MCFXM FMFDF HDPSX NHYUF FZHCF SDCRX LGYEE HCFCF RKPMR HFDGJ ZZVPD FWFWA FDHCF AYWAS XNSXK FWYDU HCRHM RGJGY DDRHC FDYJD XYDLS IRVVS FGRXP MRPSH SGGHS VVHYZ GFIDF HGYHC FERIH YJDZD YHRNY XSGHU XYMGR AYJHS HSGGS NXSES IRXHS GJGZF IHHCF UFPHY HCSGM CYVFW PGHFD PVSFG SXHCF SDSLF XHSHP SEMFU XFMMC YHCFP MFDFM YDUSX NEYDM FWSNC HAFRA VFHYE SNJDF YJHMC RHHCF PRDFJ ZHYYX FVRGH HCSXN RIHSX NYXRC JXICS HYYUR VYYUR HGYWF YEHCF EDFXI CLFRL LDYZG REHFD HCFED SFLDS ICGHD RGGFS XISLF XHRXL EYJXL HCFRH HRICF LIYWW JXSIR HSYXS CRKFX HCRLH SWFHY IDRIU SHAJH SHCSX USHWR PAFRK SNFXF DFRNR SXAJH SCRKF XHCRL RICRX IFHYH DPARA ARNFG HDSIU YXSHP FHNSK FSHHY PYJDA VRIUI CRWAF DRXLG FFMCR HHCFP IRXWR UFYES HRVVH CFAFG HCRDD P
diff --git a/2015/6b.ciphertext b/2015/6b.ciphertext
new file mode 100644 (file)
index 0000000..448a4b3
--- /dev/null
@@ -0,0 +1 @@
+DYIMX MESTE ZDPNF VVAMJ RNPSG CIGRV VFSIA DICUY OGYFY FMQQI FYFSM LQFXF ZBUOC SOVME CWMDD BNXUE DCIAQ VHFZA GORPK ZCEWF RQJIA NKLQG IYERF XPQAD VPXTO RXTIU AZBFZ HQONB BPSGE PRITE ZYWGL VXDFA GOURA YMBPP SGCIY VZIEN IALVX DFAGO UXTPG OOCMQ GMGRR XFSML MRROS MNDPS GMCGD YIKOW AYKYZ OMECK EZOBU KKCAF KNXFR XJKUO RXUYI TKDIM YLGRZ WUDVB DRKMX MVPPS GEZLD FTXLG NQRQQ ZNPRV WEWQX OPSGC IYVZI EHMJS CPRTV QYLVE PTIOJ MZLAG KCIYL BRIFY TLDRL VIZHI EXVHE ZTRDL WEEIE DRKMT VVMRR XPBLY LLMGM GRVEP OZRCJ SRLVB DYIDD ISOYS GDMND RWYLT YNZWO ZCADF RAFZB BZKUY IYZIM OPIAN ZAUWT VXTPG OMGRV MPPVG SKCAQ IOBZX UDPQY LFXPI TOEXI ZZXSE KUYGB EIIYM IFCPW TLTYG VWMJN BEILG YLEOU XTZCF KEHRC IAMJX AMMCK ZHPTZ RMKPK EWNXR GOZCA DFJYJ KUYFW UYOVP PSGHI ADKSW YWJWF VQLJB EKXTP BEORG TPZLY WCAFZ FYTEX WMQPI MQYLF DYIZW MGEJQ QPBVX KLQAI EUSCF SMOBZ XUDPR WSEED GBXWV UOILK KIXPD RX
diff --git a/2015/7a.ciphertext b/2015/7a.ciphertext
new file mode 100644 (file)
index 0000000..3df8fa8
--- /dev/null
@@ -0,0 +1 @@
+RTBFX UIUHT UZWUW ZAMMT BHUGS AUZSA ZEJHU ZIILH ARTIR WBNIM HTUZS GEINA FIUFI CAFHM IYBPT BKIBZ ACCAF HJZUH PTIFI URTIR WILHT IRUCT IFRXI FWGEB RWSFA JZLBZ LUHHJ FZGAJ HGTIU GMTUH IFJGG UBZTI FNBYU XPXIN HYAGR AMUZE JHGTI TBGFI XBHUK IGUZH TISJX BSBHC IFYGT IRXIB FXPTB GZAXA KINAF HTIGA KUIHS AKIFZ YIZHG AUBYG HUXXZ AHGJF IMTAG TIMBG MAFWU ZSNAF EJHUH TUZWH TUGUG WIPUZ HIXXU SIZRI UZHTI YIBZH UYIUT BKIEI IZMBH RTUZS HTIEF UHGHT IPGII YHATB KIEII ZUZRA ZHBRH MUHTA JFNFU IZLGU ZHTIF IURTG LAWHA FBZLH TIPUZ HJFZT BKIEI IZMBH RTUZS HTINF IZRTU HGIIY GXUWI MIBFI BXXMA FWUZS BSBUZ GHAZI BZAHT IFMTU RTUFI BXXPL ULZHI OCIRH BZLSU KIZMT BHMIF IBLUZ HTINF IZRTL ARJYI ZHXBG HMIIW ULAZH HTUZW HTBHU GBRAU ZRULI ZRIYP AMZSJ IGGUG HTBHH TIFJG GUBZG WZAMM TBHUG SAUZS AZBZL HTBHA JFEIG HTACI ANJZR AKIFU ZSUHU GHAEF IBWUZ HAHTI UFTDB ZLHFP HANUZ LGAYI HTUZS HTIFI JZNAF HJZBH IXPBR RAFLU ZSHAY PGAJF RIPJF UHTIP TBKIH BWIZH AJGUZ SBZIM RUCTI FGAXU HBUFI NAFBF RTUKI GHAFB SIANH ACGIR FIHNU XIGGA IKIZU NMIYB ZBSIH AGHIB XHTIF IXIKB ZHNUX IUHMU XXHBW IBXAH ANRAY CJHUZ SHAEF IBWHT IRUCT IFUBH HBRTB EFUIN YIGGB SINFA YPJFU IZRFP CHILJ GUZSB ZBYGR ARUCT IFWIP MAFLX IZSHT UGGUO UZMTU RTTIL IGRFU EIGHT IRUCT IFUHU GKIFP RXIKI FGUYC XIHAU YCXIY IZHEJ HBLIK UXHAR FBRWB ZLYPA ZITAC IUGHT BHMIR BZBXG ANUZL HTIRU CTIFW IPMTU XIUZH TITDA FBHXI BGHCB FHANU HUCXB ZHAIZ HIFUZ HMAMI IWGAZ LIRIY EIFGU OHIIZ HTHTI FJGGU BZGBF ITAGH UZSBX BFSIC FACBS BZLBI KIZHB GCBFH ANHTI UZHIF ZBHUA ZBXIE BJBJG GHIXX JZSMU HTXIB LUZSC AXUHE JFAYI YEIFG UZBHH IZLBZ RIYAG HANHT IGIRJ FUHPH IBYMU XXEIA RRJCU ILMUH THTBH BZLTD GIRJF UHPMU XXEIF IXBHU KIXPX USTHM UHTXJ RWUMU XXSIH UZBZL AJHMU HTHTI NUXIG MIZII LHTBH ZUSTH BZLHT IZMIR BZSIH HAHTI EAHHA YANHT IMTAX IFIUR TGLAW HAFGH FBHBS IYBXX HTIEI GHTBF FP
diff --git a/2015/7b.ciphertext b/2015/7b.ciphertext
new file mode 100644 (file)
index 0000000..fa2cf28
--- /dev/null
@@ -0,0 +1 @@
+UOCAD EDMMA EDAEC RRSOI COIPI IFEBO BDUSI SDSBE ENTTY ANETA DCOUD KOOTT RBELE DRAOA USYYO HISNL EDDSR ISHRS HEEOS ETROS TLSEU NRSCC OUWRI MOLHN STERS EDEEA RINTE WPENN OMSFT AITOF TOILL CAPEC ESEPN DUETN DEEUS ESOMF AKOGT INLGE LYARU ITSIC RIOIR SECOR ETNEU EATMT ALIHL EICRV EASME NCIED ATHEO LKWHE OHNWO NFIMH THUBE AIBND ATTHU EKTDO OECTW ITABA OULCA QWIUP IYPOC ODEEO ONSHI TCIEE ATAIA CLTTA RCHGH OFHET DPAEC HMAHV EHLOL YARLE IKEDR ODTEI DYSKE EYCFS HFOFE HTGEJ NDBBR YPHON IOSRO LMREF RWFII GHYPH NMEHR ELASO NDEIV TDTIR HEROT URECH ORHEG YNDED MEPYT WVIID OMOUT YAION AUFUC ATWOU OKTEF LTHMU TGNEC TITAR AOWEN NGSST EFRRE SCLFS PSATO EHIHE LASTV CHIFI IUTET EYEEC STNHE OILDS TNEPM ROSTT SRAFL LRHED ISESS RETIE NASU
diff --git a/2015/8a.ciphertext b/2015/8a.ciphertext
new file mode 100644 (file)
index 0000000..de67fa8
--- /dev/null
@@ -0,0 +1 @@
+JHRIJQEOZOJZZVADENPVXKUTFEPITBSJTIRJXLRDBRKNHKHQXJVUKJWYDBTKSMWVHTZZVGJPEWHIRVLDZEBSDLHZDBICTTYLBKQATYPOPQYYZLUVGHLCJOVCAEWFTXQFOLQWVEVMZYOFCJKRYLTWATZYOYUVNKSMVKNHKEZEERTYZCKJAHVDBSNLNWTTIHYODDWZKLTYPIHSBAIEMVUDAJLACQBEOAMGVLDVYKVAWTVOEMVOTYPASNPTRTZIEPPYPZJQYTLYIXGSYKSMGKWHVCKPGYKNSWQCUAXPLXJLEENZCRAIFYEEUPNTCMHKILPNIVGSEJDQJQBNULALGLTFQJYTUTGLXITPNKSMFKUWYTKLIHVVXMENPSKZNXJPRKJMMIOTTLZHUHNUTIQJVPZYOXJHTKSQWKZACLZKGWAIEWJVOEBPGMVDICWAXKSLSPPETKTFMZICRBLEUEAIEEZBMOWOJDQFNLEJAMGKHLCJIWVOEVCIWGKPRCBACZSKTTPKUTRNBXJLRVXICDLAEZBLGYCCFMMPAHREBLGWAXPITRLAIDBSJHVVMMIPAOIYNVQTAEPKSPVMZNAXGETSZWOKMOLYLSPAHVOMWMHNPHICKMIXFZIVOETSMQKZTJLBPCUGCPGQCFHVWXYUAOIPKSPZTIFKXVOENSWPGREPRQZGUTZXMXJVUXSQAQBLUYBIZWETEBLGTTFXIRCNEDZZIVOAEZVIEHRULLEANIMPVLQDCRCMJWSTYPGAKSLYLDIVVBVYWXVVDVDBVQFTYPLSEBMVYBMVDICWBEMLUJLELKSEKZKVCJKKSQWDBTDLGFGAIDPQWQUOLCAMFLWZEPGJYIJEUEUAHZYOWULEDEWFGXUZPBEPKIRXPSRPNXEPEVDIKSQRVOEEPFXVORVPEIGRSNPUEARNFHXVGJIJPTCYOAKEPIUVVZPBWYLRVEZCKUGKZLSJLRVHPEVLVVCBLGVUKNWQGPTYTVOKAIJNTICYTYLBXJLFLECVGVFVFZSRLIJYWXNPKVWGXQIEJPBXNLDWZZEYOICPQLGHRIFUSWYSVGMVAKAPLJSWASYZZXCNEJTVXJLSFGQIVILFNIRFIOIOMVEVNKCWPUHRVRWMPNUGTVTNHCVDGSWDOLWLRVLXGPKXVVPIPDIPALRCOIUJACPUMIYAKTWRVOEIPIVGWRFMTIOZIERZIGJERYLXWYKVJIRFKIMTAMQUSSPBAGLNKSMFTPTZDPEPKFIPVGJHNUEPIDYIKDIVGOAMTVKTLACEZSWILVAICKUGFQNXJLIIHIVFLBKDELGAHVCWVPVTNPKVCJKKSMVGPCYDLSMAOIXGWVLRPTBLKUKKSMVGPSXZQRIAOSPXPGUTPQWVAVUKZLSKRNFHEIJHDKZESTRHRCLXQWEIDCEFLYFFBSHSYFGMVDBTNPZICSLPOWRGLDPZCLGYEVGMRVOETSQIHYETZORKGEJEPEVZOZQQGCUINLVXVVPVCAYCKEPZCXQZTRJNVCUCFTAEPKIRCMFGPNXAWWVLDKZXETPSBTVHQMAKSIRMFOLQWVQBRNZZOQUTYTATTVJVNBFWAITLVXIVUEWMWUPKEZEXJLBVCTMPZTREQSPOAJDWQGVNVTBVWZTYZXIAVUCWIKTLEKZBEMLTYPRSDJHRCTMG
diff --git a/2015/8b.ciphertext b/2015/8b.ciphertext
new file mode 100644 (file)
index 0000000..2fc6da5
--- /dev/null
@@ -0,0 +1 @@
+IUTWMVVHVRORNXZZAGPPJSLVPFDLVZMEVGJIVYDZPNAPKQXCIZLGRZWNNCSVKPQTMLKPQNWPGOAYVAPQIPQWRMIXPBTCCEGWHLOZQRFYZGHEJCFETFRULYBLUDNHNYGBEKBKSNXYMRCTHNLXHKHKDFCBBWGVJQBLIESQAJWVLZQTLLASRESDVJMRTBJDOVOAJPQQIVYZHFAFQBHGMVOSDEXBYHKSPYSQLDFRZFYJHEDWPZMVBDCRIYALMMVQWJHVIPDUCKFVZBXMDQVBMXOKODOGYEBWLACFMUVQNSQRKMMNWZBEOOUEXIYDJWUJICKRFQLCESIKHCJQRUFPRRGYHSTZNWOSPAZULTCZPRSOYVETXLLAQMJMVUSOPLCEWYLJUADSJGTLOHOXRHSPZGLADFFAHORATZOBMRVVFDWANXPGUNQGLIHGTRMWBJMFTALCCPZGVLCSINPBUWOVPYXUQUZKTGLTVRZLIRRFNWUULJIVFMEVFIPUNCMDUZAGRHDACDPFKTHTKDKOGUSPYENXTPQUROUZTWCMIGPCKLYWZGUWJRLVKNKQKGPDQNABIRLPVKHOMWXWCQTLGWHXBJFYGIVIWWJXWAVUCOFKJUMZKXKKOEGOETLRAKQVMGKOABGIXQLQMBJYBJUOIZRWHKZCDSMNHMWTRSDBSRULECERARYGFDPERECYGULSJCJWVMLNRZXKQRTTSZWJUVSUXLGKMQPHJWAUBUEJXKYAXCEBLGJHTNKTNZSGYLOFUZUTLNYBHBKGKSCDWIYUXXFYJPNTAFKBGCNLJVGTKDCNBHUSAZRBWSXKICXDISPIRYEOIVXZAWAZIFPGAUYDQSWYCSIQDENTCTAONTOBCIVFYPVPDEMUHDPNTSUOSWVMLXECSHCMHESCGWSUSTAYHKUMOXUFEANTUHNDZHZFLRSHCZBASXPPMCNWMSJTANASBRPHDWJUCTTGMHNTTPIGTVJWWNFUWEOZMCIQMDZDJGLKSSYOXIBGIHPZOMNYBORFNCBTNUHQDOPUOFCCLDFUHIPMKCZKCZVZNMFLWOKIZFKINWQNROAZYLCTMUZYUGOUIMEQSQQAAIQVYQRSPZPUXUNBAORFDDASVMADOGRNPBPKNXGXQOKSEHEAJNZNMQIUMPLHWUFWLEOBKPIASZALJPZQUIKJSGKPGEGMPFBUNHOFKXTSCJMTYBUJEBYNNEVQHKNTIUJBJEEUSQOINRDAZUQMEWEELBLBSGUGXDXLWTUEODCKZYXJUODPPGBSPLAKHPKUZYVWGXMVXEAENQYBPKSDJMTZIBEYMTOFWCVOYZLJSKXGBKAHDTZAMZSFPGPYFFWRBHLNXOAXOITZVFBEXAKVYPAYTIRZMRKIYZRKIQNSDOINPTWMACVOJCXWCOXCEAJBQULUYWQLRERSUIIQTBASGUMAORADTIWOIDHEWLYZBADGFMHHWXNQCZKFTBVJRSYMKGTMLRGNHPUZYOVAOGTVHKHHEQBKTHJYBCUONPEUPDPJMLEOZILYNABGMPEEVJHKADCUEHMNEFWJURTJKTBKZSMTKYPCRVGFPHEIDVFSVNFUMSYAXJAVGMDSZRMHMQVSUEKUWFZFRYOROKWORNQUNJXBHNZAYXWWBEISHIQBOJAAYEKWMGJLGHFDRKBEJTQUQKVRHNJGFHARSOXBRZHKTJFJFNRXQZQRMFKNXRWLVCZBZSFQAOCLPZSGIOTMXTQHBHVYVRYIUSKFXFPKNSQITSRMYGRYXWRFQMBBMJTYOCDTTW
diff --git a/2015/Solitaire.py b/2015/Solitaire.py
new file mode 100644 (file)
index 0000000..dfa1c5b
--- /dev/null
@@ -0,0 +1,266 @@
+#!/usr/local/bin/python\r
+\r
+# Solitaire.py\r
+# Copyright (C) 1999  Mordy Ovits <movits@lockstar.com>\r
+#   This program is free software; you can redistribute it and/or \r
+# modify it under the terms of the GNU General Public License as \r
+# published by the Free Software Foundation; either version 2 of the \r
+# License, or (at your option) any later version.\r
+#   This program is distributed in the hope that it will be useful,\r
+# but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+# GNU General Public License for more details.\r
+#   You should have received a copy of the GNU General Public License\r
+# along with this program (see License.txt); if not, write to the Free \r
+# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  \r
+# 02111-1307  USA\r
+#   NOTE: the Solitaire encryption algorithm is strong cryptography.\r
+# That means the security it affords is based on the secrecy of the \r
+# key rather than secrecy of the algorithm itself.  That also means \r
+# that this program and programs derived from it may be treated as \r
+# a munition for the purpose of export regulation in the United States \r
+# and other countries.  You are encouraged to seek competent legal \r
+# counsel before distributing copies of this program.\r
+#\r
+#   Solitaire.py is an implementation of the Solitaire encryption \r
+# algorithm, as designed by Bruce Schneier and described at: \r
+#     http://www.counterpane.com/solitaire.html\r
+# as well as in Neil Stephenson's novel Cryptonomicon.\r
+#   Solitaire is a cryptographically strong stream cipher that can\r
+# be implemented using a deck of playing cards.  This implementation is\r
+# designed to be extremely clean, and a good aid to someone looking to see\r
+# how Solitaire works \r
+\r
+\r
+class Deck:\r
+       # Sets up the Deck in Bridge format\r
+       def __init__(self):\r
+               self.Cards = []\r
+               for i in range(1,55):\r
+                       self.Cards.append(i)\r
+\r
+       def MoveDownOne(self, index):\r
+               if (index == 53):\r
+                       temp = self.Cards[index]\r
+                       self.Cards[index] = self.Cards[0]\r
+                       self.Cards[0] = temp\r
+               else:\r
+                       temp = self.Cards[index]\r
+                       self.Cards[index] = self.Cards[index + 1]\r
+                       self.Cards[index + 1] = temp\r
+\r
+       def MoveDownTwo(self, index):\r
+               if (index == 53):\r
+                       self.Cards.insert(2, self.Cards[index])\r
+                       del self.Cards[index + 1]\r
+               elif (index == 52):\r
+                       self.Cards.insert(1, self.Cards[index])\r
+                       del self.Cards[index + 1]\r
+               else:\r
+                       self.Cards.insert((index + 3), self.Cards[index])\r
+                       del self.Cards[index]\r
+\r
+       def GetValueByIndex(self, index):\r
+               return self.Cards[index]\r
+\r
+       def GetIndexByValue(self, value):\r
+               for i in range(0,54):\r
+                       if (self.Cards[i] == value):\r
+                               return i\r
+               return -1\r
+\r
+       def TripleCut(self, low, high):\r
+               self.Cards = self.Cards[high + 1:] + self.Cards[low:high + 1] + self.Cards[:low]\r
+\r
+       def CountCutByIndex(self, index):\r
+               CutBy = index\r
+               self.Cards = self.Cards[CutBy:-1] + self.Cards[:CutBy] + [self.Cards[53]]\r
+\r
+\r
+\r
+class SolitaireCipher:\r
+       def __init__(self):\r
+               self.Deck = Deck()\r
+       \r
+       def GetNextOutput(self):\r
+               self.Deck.MoveDownOne(self.Deck.GetIndexByValue(53))\r
+\r
+               self.Deck.MoveDownTwo(self.Deck.GetIndexByValue(54))\r
+\r
+               if (self.Deck.GetIndexByValue(53) > self.Deck.GetIndexByValue(54)):\r
+                       self.Deck.TripleCut(self.Deck.GetIndexByValue(54), self.Deck.GetIndexByValue(53))\r
+               else:\r
+                       self.Deck.TripleCut(self.Deck.GetIndexByValue(53), self.Deck.GetIndexByValue(54))\r
+\r
+               CutBy = self.Deck.Cards[53]\r
+               if (CutBy == 54):\r
+                       CutBy = 53\r
+               self.Deck.CountCutByIndex(CutBy)\r
+               \r
+               TopCard = self.Deck.Cards[0]\r
+               if (TopCard == 54):\r
+                       TopCard = 53\r
+               return (self.Deck.Cards[TopCard])\r
+\r
+       def KeyDeck(self, s):\r
+               from string import upper, letters\r
+               k = ""\r
+               for i in range(0, len(s)):\r
+                       if s[i] in letters:\r
+                               k = k + s[i]\r
+               k = upper(k)\r
+               for i in range(0, len(s)):\r
+                       self.GetNextOutput()\r
+                       # New Step Five\r
+                       self.Deck.CountCutByIndex(ord(k[i]) - 64)\r
+                       \r
+       def Encrypt(self, s):\r
+               from string import upper, letters\r
+               c = ""\r
+               p = ""\r
+               for i in range(0, len(s)):\r
+                       if s[i] in letters:\r
+                               p = p + s[i]\r
+               p = upper(p)\r
+               if not ((len(p) % 5) == 0):\r
+                       p = p + ('X' * (5 - (len(p) % 5)))\r
+               for j in range(0, len(p)):\r
+                       while(1):\r
+                               output = self.GetNextOutput()\r
+                               if ((output == 53) or (output == 54)):\r
+                                       continue\r
+                               else:\r
+                                       break\r
+                       if (output > 26):\r
+                               output = output - 26\r
+                       k = (ord(p[j]) - 65) + output\r
+                       if (k > 25):\r
+                               k = k - 26\r
+                       k = k + 65\r
+                       c = c + chr(k) \r
+               return c\r
+       \r
+       def Decrypt(self, s):\r
+               from string import upper, letters\r
+               c = ""\r
+               p = ""\r
+               for i in range(0, len(s)):\r
+                       if s[i] in letters:\r
+                               c = c + s[i]\r
+               c = upper(c)\r
+               \r
+               for j in range(0, len(c)):\r
+                       while(1):\r
+                               output = self.GetNextOutput()\r
+                               if ((output == 53) or (output == 54)):\r
+                                       continue\r
+                               else:\r
+                                       break\r
+                                       \r
+                       if (output > 26):\r
+                               output = output - 26\r
+                       k = ord(c[j]) - output\r
+                       if (k < 65):\r
+                               k = k + 26\r
+                       p = p + chr(k) \r
+               \r
+               return p\r
+\r
+def PrintInFives(s):\r
+       ns = ""\r
+       for i in range(0,len(s)):\r
+               ns = ns + s[i]\r
+               if (len(ns) == 5):\r
+                       print ns,\r
+                       ns = ""\r
+       print ns\r
+\r
+def test():\r
+       print "Running Test Vectors"\r
+       print "--------------------"\r
+       # (plaintext, key, ciphertext)\r
+       vectors = [\r
+                               ("AAAAAAAAAAAAAAA", "", "EXKYIZSGEHUNTIQ"),\r
+                               ("AAAAAAAAAAAAAAA", "f", "XYIUQBMHKKJBEGY"),\r
+                               ("AAAAAAAAAAAAAAA", "foo", "ITHZUJIWGRFARMW"),\r
+                               ("AAAAAAAAAAAAAAA", "a", "XODALGSCULIQNSC"),\r
+                               ("AAAAAAAAAAAAAAA", "aa", "OHGWMXXCAIMCIQP"),\r
+                               ("AAAAAAAAAAAAAAA", "aaa", "DCSQYHBQZNGDRUT"),\r
+                               ("AAAAAAAAAAAAAAA", "b", "XQEEMOITLZVDSQS"),\r
+                               ("AAAAAAAAAAAAAAA", "bc", "QNGRKQIHCLGWSCE"),\r
+                               ("AAAAAAAAAAAAAAA", "bcd", "FMUBYBMAXHNQXCJ"),\r
+                               ("AAAAAAAAAAAAAAAAAAAAAAAAA", "cryptonomicon", "SUGSRSXSWQRMXOHIPBFPXARYQ"),\r
+                               ("SOLITAIRE","cryptonomicon","KIRAKSFJAN")\r
+                               ]\r
+       for i in vectors:\r
+               s = SolitaireCipher()\r
+               s.KeyDeck(i[1])\r
+               ciphertext = s.Encrypt(i[0])\r
+               if (ciphertext == i[2]):\r
+                       print "passed!"\r
+               else:\r
+                       print "FAILED!"\r
+               print "plaintext           = " + i[0]\r
+               print "key                 = " + i[1]\r
+               print "expected ciphertext =",\r
+               PrintInFives(i[2])\r
+               print "got ciphertext      =",\r
+               PrintInFives(ciphertext)\r
+               print\r
+       print "Test bijectivity (i.e. make sure that D(E(m)) == m"\r
+       print "--------------------------------------------------"\r
+       from whrandom import choice, randint\r
+       from string import uppercase\r
+       for i in range(0,5):\r
+               p = ""\r
+               for i in range(0,randint(10,25)):\r
+                       p = p + choice(uppercase)\r
+               s = SolitaireCipher()\r
+               s.KeyDeck("SECRETKEY")\r
+               c = s.Encrypt(p)\r
+               s = SolitaireCipher()\r
+               s.KeyDeck("SECRETKEY")\r
+               r = s.Decrypt(c)\r
+               if (r[:len(p)] == p):\r
+                       print "passed!"\r
+               else:\r
+                       print "FAILED!"\r
+               print "Random plaintext =",\r
+               PrintInFives(p)\r
+               print "ciphertext       =",\r
+               PrintInFives(c)\r
+               print "decrypt          =",\r
+               PrintInFives(r[:len(p)])\r
+               \r
+               print\r
+               \r
+       \r
+\r
+\r
+\r
+if (__name__ == "__main__"):\r
+       from sys import argv\r
+       from string import upper\r
+       usage = "Usage:\nsolitaire.py [-test] | [-e,-d] key filename\n"\r
+       \r
+       \r
+       if (len(argv) < 2):\r
+               print usage\r
+       elif ("-TEST" in map(upper,argv)):\r
+               test()\r
+       elif (upper(argv[1]) == "-E"):\r
+               FileToEncrypt = open(argv[3])\r
+               Plaintext = FileToEncrypt.read()\r
+               s = SolitaireCipher()\r
+               s.KeyDeck(argv[2])\r
+               Ciphertext = s.Encrypt(Plaintext)\r
+               PrintInFives(Ciphertext)\r
+       elif (upper(argv[1]) == "-D"):\r
+               FileToDecrypt = open(argv[3])\r
+               Ciphertext = FileToDecrypt.read()\r
+               s = SolitaireCipher()\r
+               s.KeyDeck(argv[2])\r
+               Plaintext = s.Decrypt(Ciphertext)\r
+               PrintInFives(Plaintext)\r
+       else:\r
+               print usage\r
diff --git a/2015/cards2.png b/2015/cards2.png
new file mode 100644 (file)
index 0000000..1176142
Binary files /dev/null and b/2015/cards2.png differ
diff --git a/2015/sol.py b/2015/sol.py
new file mode 100644 (file)
index 0000000..35da266
--- /dev/null
@@ -0,0 +1,174 @@
+#!/bin/env python\r
+\r
+"""\r
+Python implementation of Bruce Schneier's Solitaire Encryption\r
+Algorithm (http://www.counterpane.com/solitaire.html).\r
+\r
+John Dell'Aquila <jbd@alum.mit.edu>\r
+"""\r
+\r
+import string, sys\r
+\r
+def toNumber(c):\r
+    """\r
+    Convert letter to number: Aa->1, Bb->2, ..., Zz->26.\r
+    Non-letters are treated as X's.\r
+    """\r
+    if c in string.letters:\r
+        return ord(string.upper(c)) - 64\r
+    return 24  # 'X'\r
+\r
+def toChar(n):\r
+    """\r
+    Convert number to letter: 1->A,  2->B, ..., 26->Z,\r
+    27->A, 28->B, ... ad infitum\r
+    """\r
+    return chr((n-1)%26+65)\r
+\r
+\r
+class Solitaire:\r
+    """ Solitaire Encryption Algorithm\r
+    http://www.counterpane.com/solitaire.html\r
+    """\r
+\r
+    def _setKey(self, passphrase):\r
+        """\r
+        Order deck according to passphrase.\r
+        """\r
+        self.deck = range(1,55)\r
+        # card numbering:\r
+        #  1, 2,...,13 are A,2,...,K of clubs\r
+        # 14,15,...,26 are A,2,...,K of diamonds\r
+        # 27,28,...,39 are A,2,...,K of hearts\r
+        # 40,41,...,52 are A,2,...,K of spades\r
+        # 53 & 54 are the A & B jokers\r
+        for c in passphrase:\r
+            self._round()\r
+            self._countCut(toNumber(c))\r
+\r
+    def _down1(self, card):\r
+        """\r
+        Move designated card down 1 position, treating\r
+        deck as circular.\r
+        """\r
+        d = self.deck\r
+        n = d.index(card)\r
+        if n < 53: # not last card - swap with successor\r
+            d[n], d[n+1] = d[n+1], d[n]\r
+        else: # last card - move below first card\r
+            d[1:] = d[-1:] + d[1:-1]\r
+        \r
+    def _tripleCut(self):\r
+        """\r
+        Swap cards above first joker with cards below\r
+        second joker.\r
+        """\r
+        d = self.deck\r
+        a, b = d.index(53), d.index(54)\r
+        if a > b:\r
+            a, b = b, a\r
+        d[:] = d[b+1:] + d[a:b+1] + d[:a]\r
+        \r
+    def _countCut(self, n):\r
+        """\r
+        Cut after the n-th card, leaving the bottom\r
+        card in place.\r
+        """\r
+        d = self.deck\r
+        n = min(n, 53) # either joker is 53\r
+        d[:-1] = d[n:-1] + d[:n]\r
+\r
+    def _round(self):\r
+        """\r
+        Perform one round of keystream generation.\r
+        """\r
+        self._down1(53) # move A joker down 1\r
+        self._down1(54) # move B joker down 2\r
+        self._down1(54)\r
+        self._tripleCut()\r
+        self._countCut(self.deck[-1])\r
+\r
+    def _output(self):\r
+        """\r
+        Return next output card.\r
+        """\r
+        d = self.deck\r
+        while 1:\r
+            self._round()\r
+            topCard = min(d[0], 53)  # either joker is 53\r
+            if d[topCard] < 53:  # don't return a joker\r
+                return d[topCard]\r
+\r
+    def encrypt(self, txt, key):\r
+        """\r
+        Return 'txt' encrypted using 'key'.\r
+        """\r
+        self._setKey(key)\r
+        # pad with X's to multiple of 5\r
+        txt = txt + 'X' * ((5-len(txt))%5)\r
+        cipher = [None] * len(txt)\r
+        for n in range(len(txt)):\r
+            cipher[n] = toChar(toNumber(txt[n]) + self._output())\r
+        # add spaces to make 5 letter blocks\r
+        for n in range(len(cipher)-5, 4, -5):\r
+            cipher[n:n] = [' ']\r
+        return string.join(cipher, '')\r
+\r
+    def decrypt(self, cipher, key):\r
+        """\r
+        Return 'cipher' decrypted using 'key'.\r
+        """\r
+        self._setKey(key)\r
+        # remove white space between code blocks\r
+        cipher = string.join(string.split(cipher), '')\r
+        txt = [None] * len(cipher)\r
+        for n in range(len(cipher)):\r
+            txt[n] = toChar(toNumber(cipher[n]) - self._output())\r
+        return string.join(txt, '')\r
+                \r
+testCases = ( # test vectors from Schneier paper\r
+    ('AAAAAAAAAAAAAAA', '', 'EXKYI ZSGEH UNTIQ'),\r
+    ('AAAAAAAAAAAAAAA', 'f', 'XYIUQ BMHKK JBEGY'),\r
+    ('AAAAAAAAAAAAAAA', 'fo', 'TUJYM BERLG XNDIW'), \r
+    ('AAAAAAAAAAAAAAA', 'foo', 'ITHZU JIWGR FARMW'),\r
+    ('AAAAAAAAAAAAAAA', 'a', 'XODAL GSCUL IQNSC'), \r
+    ('AAAAAAAAAAAAAAA', 'aa', 'OHGWM XXCAI MCIQP'), \r
+    ('AAAAAAAAAAAAAAA', 'aaa', 'DCSQY HBQZN GDRUT'),\r
+    ('AAAAAAAAAAAAAAA', 'b', 'XQEEM OITLZ VDSQS'), \r
+    ('AAAAAAAAAAAAAAA', 'bc', 'QNGRK QIHCL GWSCE'), \r
+    ('AAAAAAAAAAAAAAA', 'bcd', 'FMUBY BMAXH NQXCJ'), \r
+    ('AAAAAAAAAAAAAAAAAAAAAAAAA', 'cryptonomicon', \r
+     'SUGSR SXSWQ RMXOH IPBFP XARYQ'),\r
+    ('SOLITAIRE','cryptonomicon','KIRAK SFJAN')\r
+)\r
+\r
+def usage():\r
+    print """Usage:\r
+    sol.py {-e | -d} _key_ < _file_\r
+    sol.py -test\r
+    \r
+    N.B. WinNT requires "python sol.py ..."\r
+    for input redirection to work (NT bug).\r
+    """\r
+    sys.exit(2)\r
+\r
+if __name__ == '__main__':\r
+    args = sys.argv\r
+    if len(args) < 2:\r
+        usage()\r
+    elif args[1] == '-test':\r
+        s = Solitaire()\r
+        for txt, key, cipher in testCases:\r
+            coded = s.encrypt(txt, key)\r
+            assert cipher == coded\r
+            decoded = s.decrypt(coded, key)\r
+            assert decoded[:len(txt)] == string.upper(txt)\r
+        print 'All tests passed.'\r
+    elif len(args) < 3:\r
+        usage()\r
+    elif args[1] == '-e':\r
+        print Solitaire().encrypt(sys.stdin.read(), args[2])\r
+    elif args[1] == '-d':\r
+        print Solitaire().decrypt(sys.stdin.read(), args[2])\r
+    else:\r
+        usage()\r
diff --git a/2016/1a.ciphertext b/2016/1a.ciphertext
new file mode 100644 (file)
index 0000000..2a70205
--- /dev/null
@@ -0,0 +1,8 @@
+PIZZG,
+Q PIDM AKIVVML BPM MVKZGXBML VWBM BPM XWTQKM NWCVL WV RIUMTQI'A LMAS IVL IBBIKPML QB NWZ GWC BW TWWS IB. BPM XWTQKM LMKZGXBML QB NWZ BPMUAMTDMA (QB QA DMZG ABZIQOPBNWZEIZL WVKM GWC ZMITQAM BPIB QB PIA JMMV EZQBBMV JIKSEIZLA - QB RCAB CAMA I KIMAIZ APQNB KQXPMZ). BPM WNNQKMZ QV KPIZOM WN BPM QVDMABQOIBQWV UILM QB KTMIZ BW UM BPIB PM BPQVSA BPQA XZWDMA RIUMTQI'A LMIBP QA "RCAB" I XMZAWVIT BZIOMLG. KIZMTMAA CAM WN BPM EWZL "RCAB" MDMV QN PM QA ZQOPB, JCB Q LWV'B BPQVS PM QA. Q PIDM AXWSMV BW PMZ KWTTMIOCMA, IVL RIUMTQI LWMAV'B ABZQSM UM IA I RCUXMZ. APM EIA XZMBBG LZQDMV IVL PMZ EWZS EIA OWQVO MFBZMUMTG EMTT. IXXIZMVBTG APM EIA CVPIXXG IJWCB PMZ JWGNZQMVL TMIDQVO, JCB I YCQKS AKIV WN PMZ AMIZKP PQABWZG ACOOMABA APM EIA XZMBBG IKBQDM QV BZGQVO BW BZIKS PQU LWEV. BPM XWTQKM BPQVS BPIB APWEA PWE LMAXMZIBM APM EIA. Q BPQVS QB APWEA BPIB APM EIAV'B BPM AWZB BW OQDM CX MIAQTG.
+WV WVM BPQVO Q LW IOZMM EQBP BPM XWTQKM, QB LWMAV'B AMMU DMZG TQSMTG BPIB I XPGAQKQAB EWZSQVO WV OZIDQBG EIDMA QA KICOPB CX QV IVGBPQVO BWW ACAXQKQWCA. PMZ IZMI QA EMTT NCVLML IVL AQVKM BPM LQAKWDMZG WN OZIDQBG EIDMA I NME UWVBPA IOW QB QA QV BPM AXWBTQOPB. PMZ PMIL WN LMXIZBUMVB AIGA RIUMTQI EIA LMABQVML NWZ I OWWL KIZMMZ, IVL Q KIV'B AMM IVGBPQVO QV PMZ EWZS BPIB EWCTL JM WN QVBMZMAB BW LIZSVMB WZ OWDMZVUMVB IKBWZA.
+BW JM PWVMAB Q IU CVACZM QN Q IU KPIAQVO APILWEA PMZM, JCB BPMV APILWE KPIAQVO QA WVM WN GWCZ AXMKQITQBQMA AW Q EWCTL JM ZMITTG OZIBMNCT QN GWC KWCTL BISM I TWWS IVL TMB UM SVWE QN GWC BPQVS Q IU EIABQVO GWCZ BQUM.
+
+BPIVSA,
+
+KPIZTQM
diff --git a/2016/1b.ciphertext b/2016/1b.ciphertext
new file mode 100644 (file)
index 0000000..62ae8f1
--- /dev/null
@@ -0,0 +1 @@
+E TOY'P ZEPGLST OY PZED LSET YZTE. AZYLP GLSEYZOTZD HZ YPCP, SPYZW LELSEZOYLN TH ZSPPDE. YLN TE TIT QZEO, PEC L EDP'G LSES RTX, PHC PSEP RZ EEF MJE WT FRSE ZMPC LPHOY. L RYT'Y PAALS DLH ELSH ZEOY TW, MS EZMP CPHP HPXYL SE PCZX XTS PXLWMEYLN TPY ZW LSE THWL POZERT, MZZ EDTDTSEO YL XTSOY TQEY LNTOYLP YZ RDL SP. S EFM'O PPC RLP H RYT SE JCPG PCPEQ, LOTL, DPH. RY T SEJ'C PGPC PE QLELSE. PV TWE QP WPS. P GPTW PM EYL NT.
diff --git a/2016/2016-challenge1.ipynb b/2016/2016-challenge1.ipynb
new file mode 100644 (file)
index 0000000..5bb0581
--- /dev/null
@@ -0,0 +1,227 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.caesar import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "\n",
+    "c1a = open('1a.ciphertext').read()\n",
+    "c1b = open('1b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(8, -1547.487440811204)"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score = caesar_break(c1a)\n",
+    "key_a, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "HARRY,\n",
+      "I HAVE SCANNED THE ENCRYPTED NOTE THE POLICE FOUND ON JAMELIA'S DESK AND ATTACHED IT FOR YOU TO LOOK AT. THE POLICE DECRYPTED IT FOR THEMSELVES (IT IS VERY STRAIGHTFORWARD ONCE YOU REALISE THAT IT HAS BEEN WRITTEN BACKWARDS - IT JUST USES A CAESAR SHIFT CIPHER). THE OFFICER IN CHARGE OF THE INVESTIGATION MADE IT CLEAR TO ME THAT HE THINKS THIS PROVES JAMELIA'S DEATH IS \"JUST\" A PERSONAL TRAGEDY. CARELESS USE OF THE WORD \"JUST\" EVEN IF HE IS RIGHT, BUT I DON'T THINK HE IS. I HAVE SPOKEN TO HER COLLEAGUES, AND JAMELIA DOESN'T STRIKE ME AS A JUMPER. SHE WAS PRETTY DRIVEN AND HER WORK WAS GOING EXTREMELY WELL. APPARENTLY SHE WAS UNHAPPY ABOUT HER BOYFRIEND LEAVING, BUT A QUICK SCAN OF HER SEARCH HISTORY SUGGESTS SHE WAS PRETTY ACTIVE IN TRYING TO TRACK HIM DOWN. THE POLICE THINK THAT SHOWS HOW DESPERATE SHE WAS. I THINK IT SHOWS THAT SHE WASN'T THE SORT TO GIVE UP EASILY.\n",
+      "ON ONE THING I DO AGREE WITH THE POLICE, IT DOESN'T SEEM VERY LIKELY THAT A PHYSICIST WORKING ON GRAVITY WAVES IS CAUGHT UP IN ANYTHING TOO SUSPICIOUS. HER AREA IS WELL FUNDED AND SINCE THE DISCOVERY OF GRAVITY WAVES A FEW MONTHS AGO IT IS IN THE SPOTLIGHT. HER HEAD OF DEPARTMENT SAYS JAMELIA WAS DESTINED FOR A GOOD CAREER, AND I CAN'T SEE ANYTHING IN HER WORK THAT WOULD BE OF INTEREST TO DARKNET OR GOVERNMENT ACTORS.\n",
+      "TO BE HONEST I AM UNSURE IF I AM CHASING SHADOWS HERE, BUT THEN SHADOW CHASING IS ONE OF YOUR SPECIALITIES SO I WOULD BE REALLY GRATEFUL IF YOU COULD TAKE A LOOK AND LET ME KNOW IF YOU THINK I AM WASTING YOUR TIME.\n",
+      "\n",
+      "THANKS,\n",
+      "\n",
+      "CHARLIE\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(caesar_decipher(c1a, key_a))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(11, -384.68678644711156)"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score = caesar_break(c1b)\n",
+    "key_b, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "\"E TOY'P ZEPGLST OY PZED LSET YZTE. AZYLP GLSEYZOTZD HZ YPCP, SPYZW LELSEZOYLN TH ZSPPDE. YLN TE TIT QZEO, PEC L EDP'G LSES RTX, PHC PSEP RZ EEF MJE WT FRSE ZMPC LPHOY. L RYT'Y PAALS DLH ELSH ZEOY TW, MS EZMP CPHP HPXYL SE PCZX XTS PXLWMEYLN TPY ZW LSE THWL POZERT, MZZ EDTDTSEO YL XTSOY TQEY LNTOYLP YZ RDL SP. S EFM'O PPC RLP H RYT SE JCPG PCPEQ, LOTL, DPH. RY T SEJ'C PGPC PE QLELSE. PV TWE QP WPS. P GPTW PM EYL NT.\\n\""
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c1b"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "icant believe he left like that after everything we said after everything we agreed but he has gone and icant find him and this is too big to deal with alone icant blame him more than me we were both blind to what was happening and we are both guilty but together we might have started to fix it icant see how i can do that alone here now so i dont have an option it has to end i have to end it\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(wcat(segment(cat(reversed(sanitise(caesar_decipher(c1b, key_b)))))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[1, 5, 7, 15, 18, 23, 28, 33, 34, 40]"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "nonletters = [i for i in range(len(c1b)) if c1b[i] not in string.ascii_letters]\n",
+    "nonletters[:10]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'icantbelieveheleftlikethataftereverythingwesaidaftereverythingweagreedbuthehasgoneandicantfindhimandthisistoobigtodealwithaloneicantblamehimmorethanmewewerebothblindtowhatwashappeningandwearebothguiltybuttogetherwemighthavestartedtofixiticantseehowicandothataloneherenowsoidonthaveanoptionithastoendihavetoendit'"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "p1bs = cat(reversed(sanitise(caesar_decipher(c1b, key_b))))\n",
+    "p1bs"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "\"i can't believe he left like that. after everything we said, after everything we agreed. but he has gone, and i can't find him, and this is too big to deal with alone. i can't blame him more than me, we were both blind to what was happening and we are both guilty, but together we might have started to fix it. i can't see how i can do that alone, here, now. so i don't have an option. it has to end. i have to end it.\\n\""
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "p1b = p1bs\n",
+    "for i in nonletters:\n",
+    "    p1b = p1b[:i] + c1b[i] + p1b[i:]\n",
+    "p1b"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/2016/2016-challenge2.ipynb b/2016/2016-challenge2.ipynb
new file mode 100644 (file)
index 0000000..6298f3f
--- /dev/null
@@ -0,0 +1,246 @@
+{
+ "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.caesar import *\n",
+    "from cipher.affine import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "\n",
+    "c2a = open('2a.ciphertext').read()\n",
+    "c2b = open('2b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(6, -1833.0297785667572)"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score = caesar_break(c2a)\n",
+    "key_a, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "CHARLIE\n",
+      "THE NOTE YOU SENT OVER WAS TRICKIER THAN I EXPECTED. JAMELIA DIDN'T JUST REVERSE THE WHOLE MESSAGE BEFORE ENCRYPTING IT, SHE PUT ALL THE PUNCTUATION AND SPACING BACK IN THE ORIGINAL PLACES TO THROW THE CASUAL READER OFF THE SCENT. IT WASN'T VERY SOPHISTICATED, BUT IT WAS DEVIOUS, AND TELLS US SOMETHING ABOUT THE WAY SHE THINKS. ONE THING I AM CERTAIN ABOUT, THIS DOESN'T READ LIKE A SUICIDE NOTE. WHO WRITES ONE OF THOSE IN CODE?\n",
+      "\n",
+      "OUR FIELD AGENT ASKED AROUND AT THE UNIVERSITY AND WAS TOLD THAT JAMELIA'S BOYFRIEND WORKED IN THE SAME LAB AS HER FOR A WHILE. HIS NAME IS MARTIN TRAYNOR AND THEY BOTH DID AN INTERNSHIP IN THEIR SECOND YEAR AT A SPINOUT COMPANY CALLED DYNAMIX. THAT IS A SMALL STARTUP WHICH WORKS ON THE FRINGES OF THE ARMS INDUSTRY, BUT NO-ONE SEEMS TO KNOW MUCH ABOUT IT.\n",
+      "\n",
+      "I AM NOT SURE WHY DYNAMIX WOULD HAVE HIRED JAMELIA; YOU SAID THAT SHE WAS WORKING ON GRAVITY WAVES, WHICH ARE A SEISMOLOGICAL PHENOMENON. I READ AN INTERESTING PAPER CALLED \"GRAVITY WAVES IN EARTHQUAKES\" WHICH SUGGESTED THAT THEY MIGHT BE RESPONSIBLE FOR THE DESTRUCTION OF HIGH RISE BLOCKS DURING SOME TREMORS. BUT UNLESS DYNAMIX ARE PLANNING TO TRY TO WEAPONISE EARTHQUAKES I AM NOT SURE WHY THIS WOULD BE OF INTEREST TO THEM. WE NEED TO KNOW MORE ABOUT HER WORK AND WHAT THEY HIRED HER TO DO.\n",
+      "\n",
+      "THERE ARE A LOT OF QUESTIONS EVEN IN THE FIRST NOTE:\n",
+      "\n",
+      "WHY DID MARTIN LEAVE?\n",
+      "WHERE IS HE?\n",
+      "WHY COULDN'T SHE GET HOLD OF HIM?\n",
+      "WHAT WAS TOO BIG FOR JAMELIA TO HANDLE ALONE?\n",
+      "WHAT MADE JAMELIA FEEL GUILTY?\n",
+      "HOW WAS SHE PLANNING TO FIX IT?\n",
+      "\n",
+      "I AM HOPING THAT THE ATTACHED DOCUMENT WILL ANSWER SOME OF THESE QUESTIONS BUT IT WILL PROBABLY JUST RAISE OTHERS. I FOUND IT PASTED UNDER THE COVER OF THE NOTEBOOK THAT THE PREVIOUS MESSAGE WAS TAKEN FROM. I CAN SEE WHY THE POLICE MISSED IT, THOUGH IT WASN'T A VERY PROFESSIONAL JOB.\n",
+      "\n",
+      "HARRY\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(caesar_decipher(c2a, key_a))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(17, -1552.2481210949848)"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score = caesar_break(c2b)\n",
+    "key_b, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "NHFXCZDYX KDS TLSCZY,\n",
+      "\n",
+      "RUB LSF VZCLAFOOF ZYCFSFXCFA ZY ABYLTZW?\n",
+      "UDR AZA ABYLTZW PFC TB VDAF-QLXF?\n",
+      "RULC LSF ABYLTZW IOLYYZYP CD AD RZCU ZC?\n",
+      "RUB ZX UF XCZOO ZYMDOMFA RZCU CUFT?\n",
+      "RUD LSF CUF IAX XBYAZVLCF?\n",
+      "\n",
+      "Z CUZYJ Z JYDR CUF LYXRFSX, LYA Z LT ISFCCB XHSF UF THXC AD CDD. CUF CUSFF TDYCUX RF XIFYC RDSJZYP LC ABYLTZW RFSF XDTF DK CUF TDXC FWVZCZYP Z ULMF FMFS FWIFSZFYVFA, QHC XHSFOB, JYDRZYP RULC RF JYDR YDR, FMFY TLSCZY THXC ULMF XDTF SFXFSMLCZDYX LQDHC RDSJZYP RZCU CUFXF IFDIOF.\n",
+      "\n",
+      "Z LT YDC XHSF RUD CD CLOJ CD LQDHC CUZX. Z LT VFSCLZY CULC XDTF TFTQFSX DK CUF QDLSA LC ABYLTZW LSF VDTIOFCFOB ZY CUF ALSJ LQDHC ZC, YD VDYXIZSLVB RZCU CULC TLYB TFTQFSX VDHOA ULMF XHSMZMFA TDSF CULY L RFFJ, QHC Z ULMF YD ZAFL RUZVU DK CUFT Z VLY CSHXC. Z CUDHPUC Z VDHOA CSHXC TLSCZY, QHC CULC RLX QFKDSF CUF IAX ULVJ.\n",
+      "\n",
+      "Z VLY’C CLOJ CD CUF IDOZVF; XIFVZLO QSLYVU LSF VFSCLZY CD KOLP ZC PZMFY CUF YLTFX DK XDTF DK CUF IFDIOF DY CUF QDLSA. RZCU CUFZS VDYYFVCZDYX RUD JYDRX RULC TZPUC ULIIFY. CUF IAX XBYAZVLCF LSF CDD QZP KDS TF CD ULYAOF LODYF. CUFB JYDR LOTDXC FMFSBCUZYP LQDHC TF, LYA Z JYDR YFWC CD YDCUZYP LQDHC CUFT. ZK Z XCLB UFSF CD KZPUC, CUFY ZC ZX DYOB L TLCCFS DK CZTF HYCZO CUFB SFLOZXF Z LT DY CD CUFT. ZK Z ULMFY’C AZXLIIFLSFA QFKDSF CUFY, CUFY Z ULMF L KFFOZYP CUFB RZOO TLJF TF AZXLIIFLS.\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(c2b)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "WQOGLIMHG TMB CUBLIH,\n",
+      "\n",
+      "ADK UBO EILUJOXXO IHLOBOGLOJ IH JKHUCIF?\n",
+      "DMA JIJ JKHUCIF YOL CK EMJO-ZUGO?\n",
+      "ADUL UBO JKHUCIF RXUHHIHY LM JM AILD IL?\n",
+      "ADK IG DO GLIXX IHVMXVOJ AILD LDOC?\n",
+      "ADM UBO LDO RJG GKHJIEULO?\n",
+      "\n",
+      "I LDIHS I SHMA LDO UHGAOBG, UHJ I UC RBOLLK GQBO DO CQGL JM LMM. LDO LDBOO CMHLDG AO GROHL AMBSIHY UL JKHUCIF AOBO GMCO MT LDO CMGL OFEILIHY I DUVO OVOB OFROBIOHEOJ, ZQL GQBOXK, SHMAIHY ADUL AO SHMA HMA, OVOH CUBLIH CQGL DUVO GMCO BOGOBVULIMHG UZMQL AMBSIHY AILD LDOGO ROMRXO.\n",
+      "\n",
+      "I UC HML GQBO ADM LM LUXS LM UZMQL LDIG. I UC EOBLUIH LDUL GMCO COCZOBG MT LDO ZMUBJ UL JKHUCIF UBO EMCRXOLOXK IH LDO JUBS UZMQL IL, HM EMHGRIBUEK AILD LDUL CUHK COCZOBG EMQXJ DUVO GQBVIVOJ CMBO LDUH U AOOS, ZQL I DUVO HM IJOU ADIED MT LDOC I EUH LBQGL. I LDMQYDL I EMQXJ LBQGL CUBLIH, ZQL LDUL AUG ZOTMBO LDO RJG DUES.\n",
+      "\n",
+      "I EUH'L LUXS LM LDO RMXIEO; GROEIUX ZBUHED UBO EOBLUIH LM TXUY IL YIVOH LDO HUCOG MT GMCO MT LDO ROMRXO MH LDO ZMUBJ. AILD LDOIB EMHHOELIMHG ADM SHMAG ADUL CIYDL DURROH. LDO RJG GKHJIEULO UBO LMM ZIY TMB CO LM DUHJXO UXMHO. LDOK SHMA UXCMGL OVOBKLDIHY UZMQL CO, UHJ I SHMA HOFL LM HMLDIHY UZMQL LDOC. IT I GLUK DOBO LM TIYDL, LDOH IL IG MHXK U CULLOB MT LICO QHLIX LDOK BOUXIGO I UC MH LM LDOC. IT I DUVOH'L JIGURROUBOJ ZOTMBO LDOH, LDOH I DUVO U TOOXIHY LDOK AIXX CUSO CO JIGURROUB.\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(caesar_decipher(c2b, key_b))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "((5, 7, True), -1275.2927860232996)"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score = affine_break(c2b)\n",
+    "key_b, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "QUESTIONS FOR MARTIN,\n",
+      "\n",
+      "WHY ARE CITADELLE INTERESTED IN DYNAMIX?\n",
+      "HOW DID DYNAMIX GET MY CODE-BASE?\n",
+      "WHAT ARE DYNAMIX PLANNING TO DO WITH IT?\n",
+      "WHY IS HE STILL INVOLVED WITH THEM?\n",
+      "WHO ARE THE PDS SYNDICATE?\n",
+      "\n",
+      "I THINK I KNOW THE ANSWERS, AND I AM PRETTY SURE HE MUST DO TOO. THE THREE MONTHS WE SPENT WORKING AT DYNAMIX WERE SOME OF THE MOST EXCITING I HAVE EVER EXPERIENCED, BUT SURELY, KNOWING WHAT WE KNOW NOW, EVEN MARTIN MUST HAVE SOME RESERVATIONS ABOUT WORKING WITH THESE PEOPLE.\n",
+      "\n",
+      "I AM NOT SURE WHO TO TALK TO ABOUT THIS. I AM CERTAIN THAT SOME MEMBERS OF THE BOARD AT DYNAMIX ARE COMPLETELY IN THE DARK ABOUT IT, NO CONSPIRACY WITH THAT MANY MEMBERS COULD HAVE SURVIVED MORE THAN A WEEK, BUT I HAVE NO IDEA WHICH OF THEM I CAN TRUST. I THOUGHT I COULD TRUST MARTIN, BUT THAT WAS BEFORE THE PDS HACK.\n",
+      "\n",
+      "I CAN’T TALK TO THE POLICE; SPECIAL BRANCH ARE CERTAIN TO FLAG IT GIVEN THE NAMES OF SOME OF THE PEOPLE ON THE BOARD. WITH THEIR CONNECTIONS WHO KNOWS WHAT MIGHT HAPPEN. THE PDS SYNDICATE ARE TOO BIG FOR ME TO HANDLE ALONE. THEY KNOW ALMOST EVERYTHING ABOUT ME, AND I KNOW NEXT TO NOTHING ABOUT THEM. IF I STAY HERE TO FIGHT, THEN IT IS ONLY A MATTER OF TIME UNTIL THEY REALISE I AM ON TO THEM. IF I HAVEN’T DISAPPEARED BEFORE THEN, THEN I HAVE A FEELING THEY WILL MAKE ME DISAPPEAR.\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(affine_decipher(c2b, key_b[0], key_b[1], key_b[2]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/2016/2016-challenge3.ipynb b/2016/2016-challenge3.ipynb
new file mode 100644 (file)
index 0000000..6ef30ce
--- /dev/null
@@ -0,0 +1,141 @@
+{
+ "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.keyword_cipher import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "\n",
+    "c3a = open('3a.ciphertext').read()\n",
+    "c3b = open('3b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('weston', <KeywordWrapAlphabet.from_largest: 3>), -1706.5657011593255)"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score = keyword_break_mp(c3a)\n",
+    "key_a, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "harry,\n",
+      "\n",
+      "if jamelia was working on a scheme to weaponise earthquakes, then we need to know how far she had got. i have sent trinity in to work undercover in jamelia’s lab and tasked her to try to infiltrate dynamix from there. trinity isn’t too happy there, jamelia’s office isn’t much bigger than a broom closet, but we need to try to find the code base referred to in the hidden diary entry.\n",
+      "\n",
+      "in the meantime, i have been working on the list of questions you and jamelia were asking. first: why did martin leave? according to his flatmate he flew to geneva for talks with a company called citadelle. our local agents are making enquiries, but it seems that they are that rarest of things, an established arms manufacturer with money worries. second: where is martin now? no-one knows. citadelle deny any knowledge of him, and there is no record of him leaving the country. he has disappeared.\n",
+      "\n",
+      "the most intriguing thing from jamelia’s last message is the reference to the pds syndicate. i have heard rumours of this myself in whitehall. it is all very hush-hush and it is not even clear if it is an official initiative.\n",
+      "\n",
+      "the big news for now is a breakthrough on the so called suicide note. given how small jamelia’s office was, trinity wondered why she had kept a broken printer in there next to the working one. trinity opened it up and found a few modifications which pointed the laser straight at the paper instead of the drum. she got in touch with the lab and got them to take another look at the letter. they found the attached message burned into the paper fibres. it is impossible to see with the naked eye, but the charring shows up under high powered fluoroscopy. over to you for the decryption.\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(keyword_decipher(c3a, key_a[0], key_a[1]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('neural', <KeywordWrapAlphabet.from_largest: 3>), -1476.8535205989874)"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score = keyword_break_mp(c3b)\n",
+    "key_b, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "notes on dynamix citadelle the pds syndicate dynamix area small company that relies on postgraduate interns for most of its good ideas the project we worked on for dynamix was signal recognition in a noisy environment citadelle is a major arms manufacturer that got left behind in the digital age and seems to be looking to buy it swayback into the market by taking over smaller more nimble competitors after we left dynamix we were both approached by someone claiming to work for citadelle saying they were impressed by the work we did there and that they would be interested in developing the code we wrote it old them where to go i thought martin was going to do the same but then he told me he wanted to talk with them he said that our code might be of interest to powerful people and i though the was trying to get me to join him and work with them now i think he was trying to warn me after martin disappeared i was approached by someone claiming to work for a government agency known as the pds syndicate they wouldnt tell me what they did or why they were interested but they wanted to know where martin had gone i have almost finished testing the latest version of the net it is better than any of the previous versions by several orders of magnitude and i havent tuned it yeti think it has real potential and i think that dynamix citadelle and the pds syndicate think that too i am afraid i think i need to hide i dont know where to run\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(wcat(segment(sanitise(keyword_decipher(c3b, key_b[0], key_b[1])))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/2016/2016-challenge4.ipynb b/2016/2016-challenge4.ipynb
new file mode 100644 (file)
index 0000000..26cdb08
--- /dev/null
@@ -0,0 +1,373 @@
+{
+ "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.keyword_cipher import *\n",
+    "from cipher.column_transposition import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "\n",
+    "c4a = open('4a.ciphertext').read()\n",
+    "c4b = open('4b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'MWJJT WDEVM WJBXF XWCDG VBGKF JLGLM FHEKK TDEXV WLFAN LXLMX DZXMW PFAFR NDLGN DJWPF BQMTL MFTCX RMLAF XDLFJ FKLFE XDYWC FBXWW DECWJ LXDWK KMFLG BENKX DLMFM XEEFD CFKKW RFXKF DLBWK LQFFZ YWCFB XWMWE AFFDQ GJZXD RGDKX RDWBJ FVGRD XLXGD WLETD WCXSW LOXJK LXQWK HNUUB FEATL MXKWK XVGNB EDLKF FMGQX LJFBW LFELG QFWHG DXKFE RJWPX LTQWP FKANL LMFDX LGGZW BGGZW LMFJA GGZKM FBOWD EXLAF RWDLG CWZFK FDKFX LQWKO NBBGO AGGZK GDRFD FJWBJ FBWLX PXLTA BWVZM GBFKW DEDFN LJGDK LWJKY WCFBX WQWKD GLQGJ ZXDRG DRJWP XLTQW PFKAN LGDRJ WPXLW LXGDW BQWPF KXVWD KFFMG QLMFO XFBEW RFDLK QGNBE MWPFR GLVGD ONKFE XDLMF NKLMF TKGCF LXCFK NKFAG LMDWC FKOGJ LMFKW CFLMX DRANL LMFTJ FWBBT WJFEX OOFJF DLRJW PXLTQ WPFKW JFWKF XKCGB GRXVW BHMFD GCFDG DWKTG NWBJF WETOX RNJFE GNLRJ WPXLW LXGDW BQWPF KWJFF DLXJF BTEXO OFJFD LFXDK LFXDH JFEXV LFELM FCWMN DEJFE TFWJK WRGWD ELMFT QFJFE FLFVL FEATL MFBXR GLFWC BWKLT FWJLM FKXRD WBKWJ FRXPF DGOOA TLMXD RKBXZ FAXDW JTABW VZMGB FKTKL FCKWD EWJFX DVJFE XABTO WXDLL MFTFW KXBTR FLKQW CHFEA TBGVW BDGXK FXLQW KWDWC WUXDR OFWLE FLFVL XDRLM FCWDE YWCFB XWQWK HWJLG OLMWL LGWEE LGGNJ VGDON KXGDK MFQWK XDLMF LFWCJ FKHGD KXABF OGJEF KXRDX DRLMF KFWJV MWBRG JXLMC KWDEL MFDGX KFOXB LFJKN KFELG KHGLL MFKXR DWBGO WRWBW VLXVF PFDLW RWXDK LLMFD GXKFG OKFXK CGBGR XVWBW VLXPX LTKGK MFEXE ZDGQK GCFLM XDRWA GNLRJ WPXLT QWPFK LGGXK LXBBE GDLZD GQFSW VLBTM GQETD WCXSQ FJFNK XDRMF JFSHF JLXKF GJQMW LLMFH EKKTD EXVWL FWJFG JEGXO TGNVW DRFLW DTXDL FBGDL MWLXL CXRML MFBHR NXEFC TFDIN XJXFK LMFDG XKFKX WCMFW JXDRK NRRFK LLMWL HEKWJ FKFJX GNKBG LKGOV WKMBG LKGOX DOBNF DVFKG XKNRR FKLQF XDVJF WKFLM FKFVN JXLTO GJONL NJFCF KKWRF KQMFD TGNJF HBTLJ TNKXD RWEGN ABFFD VJTHL XGDJF PFJKX DRLMX DRKAF OGJFW HHBTX DRWZF TQGJE VXHMF JLGLM FCFKK WRFXQ XBBAF GNLGO VGDLW VLOGJ LMFJF KLGOL MFQFF ZXWCL WZXDR WVJWK MVGNJ KFXDD FNLJG DKLWJ ETDWC XVKXD LMFMG HFLMW LXVWD OXLXD AFLLF JQXLM LMFBG VWBKX MWPFW LFKLW LETDW CXSGD LMNJK EWTOG JWDXD LFJDK MXHXD LMFXJ HJGRJ WCCXD RKFVL XGDXO XVWDR FLWVV FKKLG LMFXJ DFLQG JZLMF DCWTA FQFVW DKLWJ LLGND JWPFB LMXKX DLMFC FWDLX CFXOG NDELM FWLLW VMFEC FCGKB XHOGB EFENH NDEFJ GDFBF RGOYW CFBXW KEFKZ WLOXJ KLXLM GNRML XLQWK YNKLW OXSOG JWQGA ABTEF KZANL XLLNJ DFEGN LLGAF WOWDL WKLXV HBWVF LGMXE FWKFV JFLXL JFCXD EFECF GOLMF HNJBG XDFEB FLLFJ QMXVM RXPFD LMFZF TQGJE XKHJG AWABT DGVGX DVXEF DVFXL BGGZK BXZFY WCFBX WWDEC WJLXD KMWJF EWBGP FGOGB EEFLF VLXPF KLGJX FKLJX DXLT\\n'"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c4a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('waveform', <KeywordWrapAlphabet.from_largest: 3>), -2536.7576625007914)"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score = keyword_break_mp(c4a)\n",
+    "key_a, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "harry and charlie i am no closer to the pds syndicate but i think i have begun to unravel why they might be interested in jamelia and martin as she told us in the hidden message i sent last week jamelia had been working on signal recognition at dynamix at first i was puzzled by this as i couldnt see how it related to weapon is ed gravity waves but then i took a look at her bookshelf and it began to make sense it was full of books on general relativity blackholes and neutron stars jamelia was not working on gravity waves but on gravitational waves i can see how the field agents would have got confused in the us they sometimes use both names for the same thing but they really are different gravity waves area seismological phenomenon as you already figured out gravitational waves are entirely different einstein predicted them a hundred years ago and they were detected by the ligo team last year the signals are given off by things like binary blackhole systems and are incredibly faint they easily get swamped by local noise it was an amazing feat detecting them and jamelia was part of that to add to our confusion she was in the team responsible for designing the search algorithms and the noise filters used to spot the signal of a galactic event against the noise of seismological activity so she did know something about gravity waves too i still dont know exactly how dynamix were using her expertise or what the pds syndicate are or do if you can get any intel on that it might help guide my enquiries the noise siam hearing suggest that pds are serious lots of cash lots of influence so i suggest we increase the security for future messages when you reply try using a double encryption reversing things before applying a keyword cipher to the message i will be out of contact for the rest of the week i am taking a crash course in neutron star dynamics in the hope that i can fit in better with the locals i have a test at dynamix on thursday for an internship in their programming section if i can get access to their network then maybe we can start to unravel this in the meantime i found the attached memo slip folded up under one leg of jamelia s desk at first i thought it was just a fix for a wobbly desk but it turned out to be a fantastic place to hide a secret it reminded me of the purloined letter which given the keyword is probably no coincidence it looks like jamelia and martin shared a love of old detective stories trinity\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(wcat(segment(sanitise(keyword_decipher(c4a, key_a[0], key_a[1])))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'tetheabmpnpskirytetfalulnhtdiiewnkhaeavrcleahecanoiufblgndiatssyeahmttlucodutacapyllrneevtemsooehftacattkehstksieytraohvtteshgierhtntiegilleaenctrethittghinamedgaflirotfaoictnofberiteislotoatitehwkinerncaeylalhtpelhegeansecicdloubawesmwdpeiafthllaseessrtofrouireltilanggtiorhsamhtreobeylalstrmabhtuteahntthwisaaetwrooegdiratghthtetstedpaatdorspvdeidiamsazlginyatdeiadlenkadmemtsiuaechstrieotesehtaeptsneritndokhwnooehwtylucodevhagosotmihucnmrfoanotiatuboplpeoetearhtseyognrieyrvetgnhiplpeoenodolieinnreevtguhohehtwnteisonoutaidphnhtmaeitmachpalyscsitithatlucoddaletmoosenithghtwisihucmidmeamitepitacslltilceovolosmoubgytretheraiseubalzppzalgnyiwwthaeralenuoedterheanytdaaxminacdinletbiheevocuwlkmayitvaohesithoroppttiunytemeiiwngtmohsefeonricomtleadlihetsetafrnonoillwityleloroumeetlarkoloiofngrdrwateeosioynguiaagnnosomitarn'"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c4br = cat(reversed(sanitise(c4b)))\n",
+    "c4br"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "transpositions[transpositions_of('edgarallenpoe')] += ['edgarallenpoe']"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(((3, 2, 0, 1, 4), False, False), -1959.882702003483)"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "column_transposition_break_mp(c4br)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['debar',\n",
+       " 'decaf',\n",
+       " 'decal',\n",
+       " 'decay',\n",
+       " 'ficas',\n",
+       " 'fleas',\n",
+       " 'freds',\n",
+       " 'gleam',\n",
+       " 'glean',\n",
+       " 'gofer',\n",
+       " 'great',\n",
+       " 'ikeas',\n",
+       " 'incas',\n",
+       " 'infer',\n",
+       " 'juicy',\n",
+       " 'krebs',\n",
+       " 'lobar',\n",
+       " 'loges',\n",
+       " 'lokis',\n",
+       " 'molar',\n",
+       " 'molds',\n",
+       " 'moldy',\n",
+       " 'moles',\n",
+       " 'nolas',\n",
+       " 'opecs',\n",
+       " 'pricy',\n",
+       " 'pries',\n",
+       " 'prigs',\n",
+       " 'prods',\n",
+       " 'profs',\n",
+       " 'proms',\n",
+       " 'pshaw',\n",
+       " 'punky',\n",
+       " 'rugby',\n",
+       " 'stony',\n",
+       " 'straw',\n",
+       " 'stray',\n",
+       " 'strew',\n",
+       " 'sulky',\n",
+       " 'surly',\n",
+       " 'debase',\n",
+       " 'debate',\n",
+       " 'deccan',\n",
+       " 'deccas',\n",
+       " 'encase',\n",
+       " 'endear',\n",
+       " 'fleecy',\n",
+       " 'freddy',\n",
+       " 'giddap',\n",
+       " 'goodby',\n",
+       " 'grease',\n",
+       " 'grebes',\n",
+       " 'greeds',\n",
+       " 'greedy',\n",
+       " 'guffaw',\n",
+       " 'higher',\n",
+       " 'hoffas',\n",
+       " 'incant',\n",
+       " 'indias',\n",
+       " 'indict',\n",
+       " 'infant',\n",
+       " 'inhere',\n",
+       " 'jogger',\n",
+       " 'kojaks',\n",
+       " 'locals',\n",
+       " 'logger',\n",
+       " 'looker',\n",
+       " 'nolans',\n",
+       " 'nonfat',\n",
+       " 'ormolu',\n",
+       " 'ornery',\n",
+       " 'oshawa',\n",
+       " 'osmium',\n",
+       " 'ossify',\n",
+       " 'prepay',\n",
+       " 'promos',\n",
+       " 'prompt',\n",
+       " 'pronto',\n",
+       " 'proofs',\n",
+       " 'pshaws',\n",
+       " 'pulley',\n",
+       " 'straws',\n",
+       " 'strays',\n",
+       " 'strews',\n",
+       " 'sulkys',\n",
+       " 'supply',\n",
+       " 'surrey',\n",
+       " 'swishy',\n",
+       " 'tunney',\n",
+       " 'tweedy',\n",
+       " 'twiggy',\n",
+       " 'debased',\n",
+       " 'debases',\n",
+       " 'debated',\n",
+       " 'decades',\n",
+       " 'decayed',\n",
+       " 'decease',\n",
+       " 'encases',\n",
+       " 'fleeces',\n",
+       " 'goddard',\n",
+       " 'greases',\n",
+       " 'greater',\n",
+       " 'greeces',\n",
+       " 'indians',\n",
+       " 'inhibit',\n",
+       " 'kookier',\n",
+       " 'locally',\n",
+       " 'mombasa',\n",
+       " 'mommies',\n",
+       " 'mummify',\n",
+       " 'noonday',\n",
+       " 'precept',\n",
+       " 'precess',\n",
+       " 'proctor',\n",
+       " 'pronoun',\n",
+       " 'propers',\n",
+       " 'strauss',\n",
+       " 'supplys',\n",
+       " 'surreys',\n",
+       " 'debarred',\n",
+       " 'deceased',\n",
+       " 'deceases',\n",
+       " 'endeared',\n",
+       " 'freebees',\n",
+       " 'indianas',\n",
+       " 'mombasas',\n",
+       " 'opponent',\n",
+       " 'prepares',\n",
+       " 'decadence',\n",
+       " 'deceaseds',\n",
+       " 'indianans']"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "transpositions[(3, 2, 0, 1, 4)]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(3, 1, 0, 2, 4)"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "transpositions_of('edgar')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(0, 3, 4, 2, 1)"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "transpositions_of('dupin')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'the temp bank is pretty full and i think we have a real chance of building a system that could actually prevent some of the attacks the key is to harvest the right intelligence at the right time and flag it for action before it is too late i think we can really help the agencies could be swamped with false alerts so our filtering algorithm has to be really smart but then that is what we are good at right the test data pds provided is amazingly detailed and makes it much easier to see the patterns i dont know how they could have got so much information about people are they storing everything people do online in ever thought when i set out on a phd in mathematical physics that it could lead to something with such immediate impact i still love cosmology but there is a real buzz applying what we learned out here at dynamix and icant believe how lucky i am to have this opportunity meeting with someone from citadelle this afternoon i will tell you more later looking forward to seeing you again soon martin'"
+      ]
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "wcat(segment(column_transposition_decipher(c4br, 'debar', False, False)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/2016/2016-challenge5.ipynb b/2016/2016-challenge5.ipynb
new file mode 100644 (file)
index 0000000..e63ab86
--- /dev/null
@@ -0,0 +1,315 @@
+{
+ "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.keyword_cipher import *\n",
+    "from cipher.column_transposition import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "\n",
+    "c5a = open('5a.ciphertext').read()\n",
+    "c5b = open('5b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'SCFFP TJTGS CFRJZ XCVLG LYGLZ IJSLW CJLGJ XLGGC ELIFZ XXCFJ TYNSC JTGJS LJLXB HCYVT GTJCY LJNZF VZIBC FJJTX LGBTL GUCXL WTCTX BWTLR JSCJT JNCGS LFAZR TYEGV TWWGJ SCJRP YCXTO NLFLT YJLFL GJLRT YGZTH LECYJ ZNZYR LFTIU CXLWT CNCGN ZFVTY EZYCF LAFKT JXLYJ JZZWK GTYEG ZATCW XLRTC HKJJS CJGZK YRGCH TJZWR GASZZ WAZKW RGSLC YRXCF JTYSC MLHLL YRLML WZBTY ECGAF LLYTY ECWEZ FTJSX IZFCE LYJGJ FPTYE JZBTA VZKJJ SLXZG JFLWT CHWLZ YLGHP RCJCX TYTYE SZNNZ KWRJS CJSCM LITJJ LRNTJ SSLFF LCWLO BLFJT GLTYG TEYCW YZTGL CYCWP GTGGK FLWPJ SLRCJ CTGYJ JSCJY ZTGPT RTRSC MLGZX LWKAV NTJSH CAVEF ZKYRZ YJSLB RGGPY RTACJ LJSLP NLFLT YTJTC WWPGL JKBJZ RLCWN TJSCI KJKFL TYNST ASDKC YJKXJ FCYGX TGGTZ YXCVL GTJTX BZGGT HWLJZ AFCAV ATBSL FGKGT YERTE TJCWX LJSZR GBRGG JCYRG IZFBZ GJRTE TJCWG KFMLT WWCYA LCYRJ SLPNL FLCYC FXGWL YEJSA CHTYL JZIIT ALTYT JTCJT MLVLB JAZXB WLJLW PGLBC FCJLI FZXJS LZJSL FTYJL WWTEL YALCE LYATL GTJST YVJSL BWCYN CGJZJ CWRLY TCHTW TJPZY CWWGT RLGCY RTJNC GGJFK AJKFL RJZBF LMLYJ TYJLF CELYA PFTMC WFPJS LGPYR TACJL SCRBF TXLXT YTGJL FTCWG TEYZI IHKJC IJLFJ SCJJS LFLTG YZBCB LFJFC TWCYR JSLFL SCGHL LYYZY LNGZI CYPBF ZEFLG GTYGT RLFGJ STYVJ SLGPY RTACJ LNCGA WZGLR RZNYT YUCYK CFPCI JLFFK XZKFG ZIKYC KJSZF TGLRG KFMLT WWCYA LHKJE TMLYJ SCJHK WVAZW WLAJT ZYTYJ SLKVT GCKJS ZFTGL RTJTG SCFRJ ZTXCE TYLNS CJJSL PNLFL KBJZT VYZNJ SCJGL MLFCW ZIJSL BLZBW LNSZW CKYAS LRBRG WLIJJ SLATM TWGLF MTALT YILHF KCFPC YRJNZ YZNSC MLHZC FRBZG TJTZY GCJAT JCRLW WLJZJ SLHLG JZIXP VYZNW LRELY ZYLZI JSLGL YTZFG SCRRT FLAJA ZYJCA JNTJS UCXLW TCZFX CFJTY HKJTG KBBZG LTJTG BZGGT HWLJS CJATJ CRLWW LNCGU KGJJS LMLST AWLIZ FBRGJ ZVLLB CYLPL ZYJSL JNZZI JSLXT GJTWW RZYJV YZNNS PJSLP NLFLF LECFR LRCGG BLATC WJSZK ESXCP HLJFT YTJPS CGGZX LJSTY EIZFK GGSLG LYJJS LIZWW ZNTYE XLGGC ELSTR RLYTY CYTXC ELITW LTYTY GJCEF CXCGZ FJZIN TGSPZ KNLFL SLFLJ STYEG ZTCXE KLGGT YEJSC JGSLI LLWGJ SLYLL RJZHL ICTFW PRTGA FLJLG SLSCG CWGZT YAFLC GLRJS LGLAK FTJPW LMLWZ ISLFA ZXXGH KJKYI ZFJKY CJLWP RKLJZ CXTOK BNTJS SZKGL VLLBT YENLN LFLYJ CHWLJ ZGLJK BCGLA KFLAS CYYLW IZFVL PLOAS CYELH LIZFL JFTYT JPWLI JJZUZ TYJSL RPYCX TOJLC XIZFJ KYCJL WPGSL TGEZZ RCJTX BFZMT GTYEC YRGSL SCGJC VLYCW LCRIF ZXXCF JTYCY RKGLR CAZWK XYJFC YGBZG TJTZY ATBSL FJSCJ CWGZL OBWCT YGJSL GJLEC YZEFC BSPJF TYTJP VYZNG JSCJJ SLZBB ZGTJT ZYNTW WITYR TJFLC GZYCH WPGJF CTESJ IZFNC FRJZA FCAVT IJSLP GBZJT JCNZF RZINC FYTYE JFTYT JPGAT BSLFT GJZKE SLFJZ AFCAV JSCYX CFJTY GCYRT SCRJZ SKYJC WTJJW LHTJI ZFJSL AFTHH KJXCP HLPZK NTWWI TYRTJ XZFLL CGTWP VYZNT YECWW JSTGC JWLCG JGSLR TRYJF LGZFJ JZXCF JTYGF LMLFG TYEJF TAVGZ XCPHL NLGSZ KWRAZ YGTRL FZKFG LWMLG WKAVP TRZYJ NCYJJ ZBKGS ZKFWK AVJZZ ICFCY RTRZY JNCYJ JZLOB ZGLJF TYTJP JZXZF LFTGV JSCYY LALGG CFPNS LYPZK FLBWP TGKEE LGJNL IZWWZ NJFTY TJPGC RMTAL CYRKG LCMTE LYLFL ATBSL FCVLP NZFRZ IWLYE JSJSF LLGSZ KWRHL CRLDK CJLHL GJASC FWTL\\n'"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c5a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('charlie', <KeywordWrapAlphabet.from_largest: 3>), -2991.076271929155)"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score = keyword_break_mp(c5a)\n",
+    "key_a, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "harry it is hard to make sense of the latest message from martin what is the temp bank is it a network of part time spies jamelia implied that it washer coding skills that dynamix were interested in so i began to wonder if jamelia was working on a recruitment tool using social media but that sounds abit oldschool could she and martin have been developing a screening algorithm for agents trying to pick out the most reliable ones by datamining how would that have fitted with her real expertise in signal noise analysis surely the data isnt that noisy i did have some luck with background on the pds syndicate they were initially setup to deal with a future in which quantum transmission makes it impossible to crack ciphers using digital methods pds stands for post digital surveillance and they were an arms length cabinet office initiative kept completely separate from the other intelligence agencies i think the plan was total deniability on all sides and it was structured to prevent interagency rivalry the syndicate had prime ministerial signoff but after that there is no paper trail and there has been no news of any progress insiders think the syndicate was closed down in january after rumours of unauthorised surveillance but given that bulk collection in the uk is authorised it is hard to imagine what they were up to i know that several of the people who launched pds left the civil service in february and two now have board positions at citadelle to the best of my knowledge none of the seniors had direct contact with jamelia or martin but i suppose it is possible that citadelle was just the vehicle for pds to keep an eye on the two of them i still dont know why they were regarded as special though maybe trinity has something for us she sent the following message hidden in an image file in in stag rama sort of wish you were here things oi am guessing that she feels the need to be fairly discrete she has also increased the security level of her comms but unfortunately due to a mixup with housekeeping we we rentable to setup a secure channel for key exchange before trinity left to join the dynamix team fortunately she is good at improvising and she has taken a lead from martin and used a column transposition cipher that also explains the steganography trinity knows that the opposition will find it reasonably straightforward to crack if they spot it a word of warning trinity s cipher is tougher to crack than martins and i had to hunt a littlebit for the crib but maybe you will find it more easily knowing all this atleast she didnt resort to martins reversing trick so maybe we should consider ourselves lucky i dont want to push our luck to of a randi dont want to expose trinity to more risk than necessary when you reply i suggest we follow trinity s advice and use avi genere cipher a keyword of length three should be adequate best charlie\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(wcat(segment(sanitise(keyword_decipher(c5a, key_a[0], key_a[1])))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "transpositions[transpositions_of('edgarallenpoe')] += ['edgarallenpoe']"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(((1, 2, 4, 3, 0), False, True), -3669.618471067677)"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "column_transposition_break_mp(c5b)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'harry and charlie not much time and i need to spend the time i have carefully i have access to the dynamix network and used it to hack into citadelle they have a large database that a number of people here are working on mostly maintenance and data entry but jamelia steam seem to have been working on mining the data nothing too surprising really and at first i couldnt see what the fuss was about but again i got lucky jamelia s account on the machine they gave me had been wiped but they missed a configfile that showed me that she had used an online storage service for some of her files and one of them was huge the client software kept metadata about the file and it looks like a clone of the database i have seen here but the filesize is way off and the storage scheme seems to have been formatted with pointers to hidden parts of the file that dwarf the database i have seen in the citadelle servers i dont know about the database itself but i also found what looks like an encrypted db scheme file if you can send me jamelia sold laptop or phone i think there is a chance we could recover some of the documents that she had deleted by syncing it to the server if her keychain has been copied over that might also give me access to the citadelle database which i have codenamed titan i think we might be getting close to the truth but i am also sure that i am not trusted here and that will make it hard to get much more intelligence without raising alarm others seem to have fairly free access to the building but my pass only gets me to one floor and three rooms everyone is friendly but no one is talking and i dont want to push too hard and make them more suspicious i would suggest we switchback to substitution ciphers in the future this is getting serious maybe avi genere or hill cipher next time trinity'"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "wcat(segment(column_transposition_decipher(sanitise(c5b), (1, 2, 4, 3, 0), fillcolumnwise=False, emptycolumnwise=True)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['faced',\n",
+       " 'laced',\n",
+       " 'mable',\n",
+       " 'maced',\n",
+       " 'madge',\n",
+       " 'paced',\n",
+       " 'rabid',\n",
+       " 'raced',\n",
+       " 'radon',\n",
+       " 'ramon',\n",
+       " 'sable',\n",
+       " 'sabre',\n",
+       " 'sadie',\n",
+       " 'salon',\n",
+       " 'scion',\n",
+       " 'shirk',\n",
+       " 'simon',\n",
+       " 'table',\n",
+       " 'talon',\n",
+       " 'tempo',\n",
+       " 'think',\n",
+       " 'timon',\n",
+       " 'vacuo',\n",
+       " 'vents',\n",
+       " 'venus',\n",
+       " 'virus',\n",
+       " 'wacke',\n",
+       " 'wafts',\n",
+       " 'wagon',\n",
+       " 'waits',\n",
+       " 'walts',\n",
+       " 'wants',\n",
+       " 'warts',\n",
+       " 'wefts',\n",
+       " 'welts',\n",
+       " 'whirl',\n",
+       " 'whisk',\n",
+       " 'whits',\n",
+       " 'wilts',\n",
+       " 'yakut',\n",
+       " 'yalus',\n",
+       " 'zanys',\n",
+       " 'gabbed',\n",
+       " 'jabbed',\n",
+       " 'labile',\n",
+       " 'laddie',\n",
+       " 'nabbed',\n",
+       " 'nadine',\n",
+       " 'neglig',\n",
+       " 'paddle',\n",
+       " 'paglia',\n",
+       " 'rabble',\n",
+       " 'racier',\n",
+       " 'racoon',\n",
+       " 'ramona',\n",
+       " 'reform',\n",
+       " 'sables',\n",
+       " 'sabres',\n",
+       " 'sacral',\n",
+       " 'saddle',\n",
+       " 'sadies',\n",
+       " 'safari',\n",
+       " 'salons',\n",
+       " 'saloon',\n",
+       " 'samoan',\n",
+       " 'sampan',\n",
+       " 'samson',\n",
+       " 'scenic',\n",
+       " 'school',\n",
+       " 'scions',\n",
+       " 'scipio',\n",
+       " 'shirks',\n",
+       " 'simons',\n",
+       " 'tabbed',\n",
+       " 'tablet',\n",
+       " 'tacoma',\n",
+       " 'tenser',\n",
+       " 'thisll',\n",
+       " 'vacate',\n",
+       " 'vacuum',\n",
+       " 'vellum',\n",
+       " 'veneto',\n",
+       " 'venues',\n",
+       " 'venuss',\n",
+       " 'villon',\n",
+       " 'vinson',\n",
+       " 'viruss',\n",
+       " 'wabash',\n",
+       " 'waddle',\n",
+       " 'wanton',\n",
+       " 'welter',\n",
+       " 'whisks',\n",
+       " 'yaltas',\n",
+       " 'labeled',\n",
+       " 'nabbing',\n",
+       " 'pacific',\n",
+       " 'paddled',\n",
+       " 'pillion',\n",
+       " 'raccoon',\n",
+       " 'ragnark',\n",
+       " 'saddled',\n",
+       " 'saddles',\n",
+       " 'sadness',\n",
+       " 'safaris',\n",
+       " 'saloons',\n",
+       " 'samoans',\n",
+       " 'sampans',\n",
+       " 'schools',\n",
+       " 'scipios',\n",
+       " 'session',\n",
+       " 'simmons',\n",
+       " 'tabitha',\n",
+       " 'ubuntus',\n",
+       " 'vanuatu',\n",
+       " 'velvets',\n",
+       " 'venuses',\n",
+       " 'vinsons',\n",
+       " 'wabashs',\n",
+       " 'waddled',\n",
+       " 'walloon',\n",
+       " 'whitish',\n",
+       " 'zairian',\n",
+       " 'zillion',\n",
+       " 'labelled',\n",
+       " 'nanchang',\n",
+       " 'negligee',\n",
+       " 'paganini',\n",
+       " 'peephole',\n",
+       " 'reformer',\n",
+       " 'sadnesss',\n",
+       " 'sessions',\n",
+       " 'simmonss',\n",
+       " 'simonson',\n",
+       " 'velveteen']"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "transpositions[(1, 2, 4, 3, 0)]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/2016/2016-challenge6.ipynb b/2016/2016-challenge6.ipynb
new file mode 100644 (file)
index 0000000..c18936b
--- /dev/null
@@ -0,0 +1,190 @@
+{
+ "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.vigenere import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "\n",
+    "c6a = open('6a.ciphertext').read()\n",
+    "c6b = open('6b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'\\nPZAED IRAHN NESGU AVMNJ TVFHR OAFUA ZHEQG UGSTN ZAPCE EUOYD EPLII WIAGS YGWUA CUZEZ MSGZA IWTUG UTZTJ SSFSF RTUGL UEFEQ GUGLO OWAZS JBJEE JOELO NNOVV SHKPV UIBFF EGMGZ EBLHR JHNUK RJSUW HNVTB KPRFD NDOGG FGAMR GNYAN RSNQL HRFSN OEEWW NLCUA NTGNR GFGZE YSPGG PFZEJ SSHKI AYHNV BRWNP GMCJO ZASRV AAVAA SUGGM NLEQK CNFFY SGTWD GZEFL RRSMS GRNFA YQSVK WRZAI WATWN GKOAL HROAL LOVFT RJVVW WUAMN FDVSM UGPVF GGZIF OIYDG VNEHK EAGUT ZTBMN ESVRD TUASZ QSGWR LANGZ EZWAA LIZWI PSLYW DVFAS WWSSV BMRFO IGZTU WEGBE AWSGW NJZOS GLYGW RVMNJ TVFTB SLBUA YTAAC HRASP SREQI AYOHL AYDCN KHGJA AKAPL IBFSV FAAWF SGRGL OFLAL GFSYR VVWUA CUASN DIGLL RARBF IPYII WNGZE JSYJW FBMNQ ZIZZE VKTES VRDLV FGHFD RJTUW NNEEW SMRKA AVIJG NQWRR VISLH NLWNK AUANG LHNLH RKTVD LUSSS WEYAN TKFBJ JNEEY AAUWI FMSVF GNXAX WPNKS CGRGO HVUHJ SSTGO QWNBM GULOS GOYLH RTAAC AAVIN ELBGK VFGSG RJSRQ LORPA ZANVF GVLAF AAZFO GKUEW HBOHR OOHDD USVRG BGSIA WDBFE BXTUA SDMAY ATLGU GKIQW TUWTE SDROE USVRL IRVHV KNBJW RYINF TESNF SCGAO AKTBS NNUCB MNGAN FOIGR EEDAA VWUAC UAGHW SFASA GSHJP EASRO EUSDG ZEHKU NDDVX FVUUY LIRKG RLTVF GNUCR KSSJO ZLHRK WVKSN MTUGR VLIRK BHLTU ANTKA EWAYG TRSSV WRGZE EWTUS NGZEL MSRVT BTENF DJATU UOBHE ESTVG NSJOZ LHRXI FAGNA NRVAP UEFKT BSSGJ OAYBB PHRDD VFMNJ TVFSA WWASM RLHRW NPDOF WDYWT GWRSJ OZLHN LBBPP EGMVK EFLOF ZEQDI TZTBF HVKRB DEVFA YDTUA SOMTH FFBJT HFAGW LLATV KATSI AWNPJ YCLEQ SNQLH VKTVE EGZEP APUWR VKAOA TFLRB FGRJT USNGZ EBFEF OEUSV RTERF DRSLV FGJAT UACBM LQOAV LFBJT UWIAL EENIR OWVLH ZSRGA NOMTV ZAIWA SWEYA NTLHN LTUWI ALEEN IROWV DLTGB RLTRJ ISAKA GWZGR RANNV VNFCR KOVOI YDSCW NQSLV LTYWT VEENF AYQSV FGVLI ALHRZ OCWOS YEGLI AYAOJ ENCOA WTUAN TLHNL PHRZY WSZWT UWMNF ATWRN LTUWS JASFT AACMR FTVGN RVTUS TGZEY SSGLI ZWHRK AJEAE LIAAN CWRFG NUWWN KTESV RDLVF GJATU SYBMN TOOZS NNFDG ZEQWS PJICL IBFSB MNQWD NDOGD IXWJN EEYAA VVIQF TCACX MPBFT UASNL FVJSG TEPSU FWINK SHEEQ LHNLT UASJS SCJIB JTBZE EVENL HOMTJ ZEAAC UWCXW DGZEQ STRKI GVIQF TGAEH HTUWY FWEZL OUSVR TERFA GLHRT AACTB YEGZE ELHEW EQSYF SFGWR WSMRD INKDR STUEO EWLNL EEZAE JY\\n'"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c6a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('nsa', -2139.1561825446256)"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score = vigenere_frequency_break(sanitise(c6a))\n",
+    "key_a, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "charlie i have found martin he was camped out at a hacker collective in oslo which he must have thought was safe but turned out to be a major error to avoid suspicion from the other hackers he had to spend alot of time online and the nsa were watching one of the laptops he was using had been compromised and an automated scan flagged the stream for analysis we have agents on the way to interview him and i am hoping this will give us enough to unravel this mystery in the meantime i called in a few favours with the et jen esten who followed martin to a local bank he is carrying out all cash transactions in an effort to stay off grid which is a little ironic given the way we found him he is travelling under the name james and i wondered if that was a hint that he still has feelings for jamelia he is using a fake passport which was goodenough to fool the bank and i am looking forward to examining it asia m not sure how he would have obtained one of this quality outside the trade we have tied his norwegian transactions to an account in switzerland which i guess is no surprise we had the usual difficulties getting access from the swiss authorities but things area lot easier there than they used to be and with cooperation from the f is i gained access to a strongbox held in martins new name the enclosed letter from that box promises to shed light on his role in all this but unfortunately it is again encrypted and this time the cipher is abit stronger than the ones we have been dealing with i could wait for the interview with martin but i have a feeling that the interview will go better if i know more in advance so i will spend a little time analysing it in the hope of getting a break one thing that puzzles me the manager at the swiss bank mentioned that the last time he saw martin in person he was travelling with a young woman and the description sounded alot like jamelia i didnt pickup on this at first because i assumed that this was prior to her death but when i checked the dates it didnt tie up they seem to have been at the bank together three days after jamelia s death more later harry\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(wcat(segment(vigenere_decipher(sanitise(c6a), key_a))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(' ', 315),\n",
+       " ('I', 117),\n",
+       " ('E', 113),\n",
+       " ('R', 102),\n",
+       " ('V', 101),\n",
+       " ('M', 90),\n",
+       " ('T', 77),\n",
+       " ('B', 76),\n",
+       " ('G', 74),\n",
+       " ('K', 74),\n",
+       " ('Z', 61),\n",
+       " ('L', 59),\n",
+       " ('X', 57),\n",
+       " ('F', 54),\n",
+       " ('W', 53),\n",
+       " ('C', 51),\n",
+       " ('A', 51),\n",
+       " ('P', 46),\n",
+       " ('J', 46),\n",
+       " ('S', 43),\n",
+       " ('Y', 41),\n",
+       " ('H', 41),\n",
+       " ('N', 37),\n",
+       " ('U', 32),\n",
+       " ('O', 29),\n",
+       " ('Q', 28),\n",
+       " ('D', 23),\n",
+       " ('\\n', 1)]"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "collections.Counter(c6b).most_common()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('trainer', -1995.616991556106)"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score = vigenere_frequency_break(sanitise(c6b))\n",
+    "key_b, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "jamelia what do you think about this do you think dynamix would fund it proposal long baseline signal noise analysis in largescale heterogeneous networks m traynor and jd almar abstract in our work on signal noise analysis for ligo we have developed new tools for digital analysis of extremely low amplitude signals in an excessively noisy environment the classical features of this analysis are the exploitation of very long baseline signal collection and the synthesis of signals from a large sensor network to filter the noise the principle novel feature is the development of a large database of templates of target signals that allow them to be filtered from the noise and interpreted in realtime we believe this approach can be adapted to a wide variety of signal harvesting problems both within and outside the physical sciences as an example of a commercial application of the technology we have carried out analysis of a toy model which suggests that this approach maybe sensitive enough to track individual footfall across a shopping centre or airport concourse and to carryout gait analysis using seismometers embedded in the building fabric this would provide a new and less obtrusive alternative to the camera systems currently in use it has not escaped our attention that the template bank approach should scale to allow tracking of multiple targets and to search for patterns that may signal antisocial or potentially even terrorist behaviour patterns more speculatively the long baseline techniques which are key to triangulating the source of gravitational waves could be modified to provide a template based network analysis tool for finding long range correlations in network traffic this analysis could signal activity spikes among transnational criminal or terrorist groups triggering surveillance and targeting early intervention to prevent crime\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(wcat(segment(vigenere_decipher(sanitise(c6b), key_b))))"
+   ]
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/2016/2016-challenge7.ipynb b/2016/2016-challenge7.ipynb
new file mode 100644 (file)
index 0000000..15cf412
--- /dev/null
@@ -0,0 +1,242 @@
+{
+ "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.vigenere import *\n",
+    "from cipher.bifid import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "\n",
+    "c7a = open('7a.ciphertext').read()\n",
+    "c7b = open('7b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'ELUOP PAIJO NPAVX VHLDQ ZCDUY LZVJK WTDVL VGZZE LLWKU AYMLF KUSSK PLOJZ EXHPK LZYGH VLHZD MSMXX PEXFV UHPPP ARAXP YQHXF INPJF EEHZT BHQJI QYQAE ZNQZT SEJIP XWZXS BEPDL MDYMP EYEEF LOLUE JIYJI YXFCE DMYIL HTRVV VLMLP DHLQY SEGOA VHLEA YIVHF JTSYX YHZLY SFYWW MKELC NOVHB AGLYG KILUN TLUCK MOAMO XFYPH BLFFI TEKHV WNYTM OXXIP CCAGA JCLMS GSYGL PASFI OWTPX KYHOV HLLUP OZLLW ELQWA HWPTC BUSUL LXTHH OISOV HXKLP OVBXG HZOMD RAAYT AVPUM TEMUI ZNELP AIJUH LMISL SWPSP PQFSR QOAGH SEWII JUJPP AXSBE OVHSD MZCIL RJIYT OUMNC WSBVF WLLJM OXLUS EMCIA FPMMD WWCCL QKMKV FDAAM XIPYW YSWFW PLHXA WJMLL XUYEZ ZWKFC PMPAS TYCLL UEJYS EWUEW HZSBP AFITE IJMFO XXWJR AYCLG LLLYG PQSIT YHCIT PSXLT TLQSD DTMNE LIZQM OXFCY LUVAW BEEIO XVHLC WUCSL EYQAV SGDTB JIHMF DMOXL USEGA RAUEC MJVSY YSBPA WPPTT LFWQD YWPWM FNYWJ IUHLW TPINL FDVLZ WMCFW MCLHP HBYIV HFDQR RSVZW AVIZN OYIKI JIETV VQYHT PJLVS GCTND EDYSE UVVXX YLWAW DFLNT SEVYS NBHAQ FPDWS GYHTP JZMVH LVVHF WBEEI FKGFZ YPJIL LPECW QGWZE AZIUW LOMZM JISEC HRMHT POHKF YZEGJ EJCAD VVGXI DPOYE ZWRYQ KRWJW TIIRG XPDIL PWLDL EAGWJ DFALL LYWWM KELCN CMYYL WLQCU EEMXC ILLLL ZQARV GQSNQ OAELT QEHPS IEOMN RGFPM OUEJY SEIOX WFTMW TIZNO PEVLK YNLZA PDUNL TSEUY SEMRE EIEOM DSDFL YMLFV USPPS MLHFD VVMLM PFYLV GGJYI YIOMY LWAHW MFQMY XUYAD CZIZN EFJYI FCLEM YRGLP JEHPS YGLPV XWPTE KLPDI NRVPO UUSLN VVWVX PUHVG ZWLCZ YFODL EAMLU SEBBS VYEYQ VTWQC PGDED MTSTS EUIEO MKRSG POGSH WNLPX LVVHL OMAEL CRLGS LYCSP UHGWV ENMWW MMPSB ZMZNE FWIEV YVDIU IZQYZ QAEYC EDMCR ALPOV BHGCC PXLLL AYTZB HZWYL ZIIEU DPPAX SXPZM KMNHP ENVWS QYZQA TALND MKWJU XWIKK FCSNB HQFUX ZEHXS BEOMJ MLIYZ ASEWQ CPDLA GBHPQ CVWNY TBHHW VTCKZ IVYSD MPXAP TEKHI ZNSEQ DHWCW WIAIJ YSEAA MKCGD QOXSB EOMDS ZMDTA FPSHL CMOXJ OQOVH OFUMD QOXXI PRIAS GZJMJ VPWPP TZAIJ IEEVL WWLPH AARWA LSKUE JVZWA VRSHT XQOJG YRLBV SXXLS MDXSB EPDLM DYMZB KIEYP DMOKF CCZBP RGGYP MIHSB PHSUE TMDTE ZIZNX ZZMOF UMEVL VWZQT LFPWL TEVLR SNFZJ HKFCV WIAWS QENMW WMMPS BAEZN EYMYE HJLPU HGWVE TZLZW QZSOU MFITE ALYIL PSBYY XLPOV BINCE NMSPG WPSBF FFYVL BUIWV OLPUS ANNLZ LLLLF QWUSK XYFWM RWYMO IOWWM DPVRE WQZYB HLLXY LMZMU LPIMA EZYET PDEKU HEQKI ECLWK LLKCS ENVCL CWLOL PWBEE CVFSX PRVLP DUSNV LLOSE TZBGW MDVVH FWBEQ WAWWN YZQAE JNPYM WIUHL WMLVX UYZVV MLCOP XEIYH TSAPL HUQZB YEHML PDPXU YWWWJ IZNQZ NSEZY MYWKI LCDTD KEZYS EIOXV YXTIS GWBOY IRRSV LQWFF TIWPP ARAGT SNVIY UEZWM HSBPH BHLLX PWILZ WLPHZ LHJUS RVPLK OASBB SEIEO VHLYH TGQSI FIPXW ZVGZQ QWSPW QZZBL FGNOP ZHIHJ LPPAE ZNEFW KILHT ZXLAF YSHVL ZWYGC MZIJB DLKZM ZNAPS LLWLP SEUMS FAIMA SFXWF WDVGN ZYLSY GWPSA PLLHZ OMZWW LAYMO ALOME VBSUW LVVHF SYGLP VXLIY OVHWA MLMPZ EUUYZ GSIJC EYMRV GQZEL LQAUW NMOXK LTQBH WLHPX MNRSL CLTHM UHLYQ MWLWP AABWW BEZBK IFLFE MDOFU MDAPA KYSEP AMOJT SAUSA NLWMY WJIYJ IYXLO ZMIUA GHVJL HIJFL DIDXS BHWIL ZWLZE BVRWL LNOUM CUEEQ AYGVL VTHXG NOPZH TWLAE WUWSQ OYIKR ABPMB HLLFW LBMID XLSMO XSBEO MAELM ENMWW MMPSB KPABN LAHIJ YSEMT MLZZE VBSEU PWJHV WXTDV VGSNY PXZIZ NDPON YKMNT BZMJY ENIYE ZWPNQ VZLUS EBJEX YSEMA MHMPO TSELU VFMOX ZNTHA RRAFZ YLUYG ZDRVP KFIWP JZXUY ADCZI ZNQZP JVSYD LVVMK MPCXW SXIWZ WAEWL PHALW SVLEI KEFXE LPAKF CELBZ WAMJW IUEJI QPTWQ SMLYL HIVCG ZZWSL MEDMB UWLOP ABJWL PSVPX JUXPJ VXKYX LRKIL WPAAB WWQEL PAPSY GPZAS FXTOM DXMVC ZVFEJ NYTBY EEZZO VHXUY ADCZI ZNQZA JMJNP XWPFW BEYML ALYMY WPXSF PCZVG XIPPZ NIVBR TPHHW QZSAZ MKSWL VHWWC ETZVL LOLJB PWJYG TVBIZ NSEQD XMIOP SJIZW JCWAW KCSWM AEZWF PVUMW WYPQJ WJYEF XTSUH TPUTE JAZCX LXSOO LZNEE ICQBB SHICO ILFGN OPUPE DWOYI UMLLL XALQS DQZMT EFYSE VPWLH PXCJS VSETB UIVCJ EQSEM KSRQO KFCJC ZHGKU HEKLT KODPP AWAHX ZZMWH YCOVH EKHTX MJRSX YPBAE FCCZV FEJNY TBYEE BETED IAPCP BUMEI CQALX GH\\n'"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c7as = sanitise(c7a)\n",
+    "c7ar = cat(reversed(c7as))\n",
+    "c7a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('esullih', -3786.443520764479)"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score = vigenere_frequency_break(sanitise(c7a))\n",
+    "key_a, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('usehill', -3786.443520764477)"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score = vigenere_frequency_break(sanitise(c7ar))\n",
+    "key_a, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "notes from interview with martin traynor in attendance mins a and reps from n is the suspect was carrying high quality identity documents in the name of james martin and claimed to be a dropout from a graduate programme in computer science in neuchatel his story checked out with the university authorities analysis showed a high degree of correlation between the biometrics of the suspect and of martin traynor but we did not reveal that we suspected james to be martin he refused requests to provide a dna sample for analysis stating that dna databases were a tool of oppression a search of the suspects belongings found no links with the uk at all despite the fact that voice characteristics suggest he spent a considerable amount of time there as a child the suspect stated that he had left all that behind and was not prepared to talkabout it taking care not to reveal what was already known about traynor s relationship with the swiss bank we turned to the suspects financial arrangements at first he claimed to work entirely on a cash basis and not to have a bank account but when pressed on this he could not or would not explain where he kept his cash reserve even when we pointed out that he appeared to be too well off for someone living hand to mouth pushing harder we revealed that we had footage of him in the lobby of a bank and he claimed that he had visited on behalf of the collective as part of a phishing expedition on a freelance penetration test of the banks security when challenged about the legality of this he claimed it was a white hat exercise and that no weaknesses had been found sono further action had been taken by the collective under further questioning however it became apparent that the suspect was talking about an entirely different bank from the swiss bank we had been monitoring he seemed to believe that we had footage of him in an oslo branch agents were sent to retrieve lobby footage of this bank and further analysis showed that his visits there tallied with the activities he described at interview however we also noticed that a woman matching dal mars description was often video ed at the same branch during the period under investigation when asked about this the suspect became highly agitated and repeatedly demanded to call his lawyer we pointed out that it was unusual for a member of a hacking collective to have a lawyer on retainer but the suspect refused to answer anymore questions until he had been allowed to make the call a call trace showed the mobile that he rang belonged to a lawfirm which works for the arms manufacturer citadelle the suspect was released on bail pending charges of conspiracy to engage in unauthorised access to computer technology at the bank and is being closely watched all calls to and from the lawfirm are being monitored and the oslo bank is under twentyfourseven surveillance conclusions we believe with near certainty that the suspect is martin traynor and that the woman in the footage is jamelia dal mar we believe they are in communication with one another and are both being protected by citadelle or one of its subsidiaries we believe that they are both living in or near oslo and that they are both now highly likely to be aware that the net is closing in we do not understand how dal mar contrived to fake her death and we still do not have a clear picture of the interaction between the pds syndicate dynamix and citadelle nor do we fully understand why they have a strong interest in traynor and dal mar we believe that some or all of that information maybe contained in the encrypted files on traynor s laptop which has been passed to forensics for analysis and to secure the data\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(wcat(segment(vigenere_decipher(sanitise(c7ar), key_a))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'HTPEG WEEHW AOHCP NIRXE IEXZG OGDQK UEGBY KHWAO CDOTQ OTSLY OELDU MOSEQ OQYTP RNNIG ABADV QIAXV OODEE GWSSF QRGGS YEGWS SEQSX BTKBR FTGBY KBKEU QNETC KSOQB FOTSY QEOSU RBCTE KYORM TPLRA TTKMO BKEUO KCNDZ MROTR NCOYW QKPSH VTCVN FTQET CALWA VVFUK BSKFH RASAQ VFCRS GBTTT QWNEV YFRHE AQCHS QQTNN DPBTC PZEGR EAKKO HURRO CXNQG KNCQS TBSNQ BMTZO OSEBO RXKDE HEHRO YKEOB BFIKQ TTCIZ CCORU IHGYT IMBAH OAWOO ZSOQR OCDSS OQDGE YMKLO AQKXO BKPSF HSVLK WTEHN ATKTO UKNSI OCYDL TQGIT NUOCR KCEPO SRQCQ QCQSR HLWNO SKENN BTFLO LENAW BOCYT NETRN OWDEK SOQIP DWHEA WLOVV YFSCD OTLIN SOSYQ OPYNH TOCON RPTHN AWCOO DYTCO RETHL ULAEQ RPBNZ CSEHC ISDNR TNDTS PSQFC RBNPS YSRBE UELKE QTEYQ QLZLY KSOBD KNTGT WBURR BLQAK BSCVL IIUVT FQBPA KGSTC LSFSC KSKSO BAORE BQEVC BHQBL SVIQO ULKOT HQNFO IOSAH RATKT OXQUE HRYNB KPSKQ OFNWS EUOCX SOQYO VEFSC NREQS PUOED LFWKF ORUIN GTKGO ASDQS GEYMK QOPIO DEVSF NCERS QUPES OQYWB EKBQK PIADC OIUGN CTOII VOQBT ZCPEN BHZKA GOYCQ PCDET MIWFE BGEUE ORYCG SYEKM OQIPD AOCUI NGTHW AOQVT ETVCU BTOYS OQYBQ YBGLT NKVTF VQTFH STQES RQDEU MUKNS IOCYF ERRBL SRHQS THKPE TRPEW BEOSB QKQMP ZBRUE BLHTH HCSBD ACIGC YRENT HRAUQ NENKT ONOTW THUIK HIOOS GQEGO HXIRW TEINS QYFFQ NKTLT RSCNE TRGEY DANRL HFPTK TOFDQ TSOQR AGFTL HVNTS NYIIV OQETS BKFYO SEPQI VLTOY EHMIR WHEAW GOTBO QXRHR AKBRR GTXPR SEHFL RBIFL QOODE GAENO OUXWL ELSEH THMIR UDKQA DVTIH ROICC QTOYE HMIRI HWOIB CRQLP LWHEA WXOBO FYQEV RTRGX QLBQN TBYYR EBTRT TEENR MSDHQ OQXTC LOIFE QTHUA TOOUW BNTSI BDUKH SNQVR ARCTH VRSEC QSNSO QYSFH RGUTR OUREI OVUQP UTTLA VNVMT SLXDN HOAWB OEPGQ ECKEO THEAU OTUVL CLBPE QGCEE KQNTB GEUEO RYEBT QGELR SOQYV TTYHM IRVTT XHQOV FOKRK QFENK NOBLE LCQRR WGOEO LSOGE YNHUA TOVUF NHTZX DSTUL QFSCQ QGHYC NVSCU EURLK ASLOD TSBQR MRPET LMENH TASGS TFOTD HQTUN IWQIP OKOME GGFTT GOEXV TCMBM ARGEY NKFOS KTYEO BDUKB SEMCT RQVRI UITZB RYDCF SOSCQ RLIQO EAEBB SRQGP ECDAQ VBDUB GCYEQ ETSBK FYGEY NOUTE QTTNG SUQDK SYSGB ZUFKR LOBGT VWIWS OQOKD YSGBZ UCKRG EYIGO ENKKO MANE'"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c7bs = sanitise(c7b)\n",
+    "c7br = cat(reversed(c7bs))\n",
+    "c7b"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[('o', 138),\n",
+       " ('t', 126),\n",
+       " ('e', 124),\n",
+       " ('q', 109),\n",
+       " ('s', 103),\n",
+       " ('r', 90),\n",
+       " ('b', 77),\n",
+       " ('k', 75),\n",
+       " ('n', 73),\n",
+       " ('c', 70),\n",
+       " ('h', 63),\n",
+       " ('g', 58),\n",
+       " ('y', 57),\n",
+       " ('i', 54),\n",
+       " ('u', 54),\n",
+       " ('l', 52),\n",
+       " ('a', 51),\n",
+       " ('f', 46),\n",
+       " ('d', 43),\n",
+       " ('v', 42),\n",
+       " ('p', 37),\n",
+       " ('w', 37),\n",
+       " ('m', 25),\n",
+       " ('x', 20),\n",
+       " ('z', 15)]"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "collections.Counter(c7bs).most_common()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('ligo', <KeywordWrapAlphabet.from_a: 1>, 4), -2067.501010592418)"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "bifid_break_mp(c7bs, wordlist=['gravity', 'ligo'])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'martin we have made a dreadful mistake and i have been too slow to admit that to myself i have had a visit from the woman from the syndicate and i confronted her about the source of the templates she confirmed my worst fears and now i want to crawl away and die what have we done our software has led to so much suffering when it was designed to do the opposite i asked her how the cabinet office could possibly have authorised this and she laughed and explained that the syndicate no longer worked for the british government call it private enterprises he said we have always been good at that my horror must have been written all over myfaces he didnt seem surprised at my reaction but equally she didnt take it well and civility was abandoned i asked her how it could be legal let alone moral to do what they proposed and her answer was that it was necessary i said we wouldnt help them and she said it was necessary that we did i said i wouldnt be able to face my family and friends if we cooperated and she said i wouldnt have to worry about that for long one way or another the pds syndicate were going to make sure we both disappeared looking back i can see that from the start this whole thing has acted to draw us into its centre and now i am at the event horizon almost unable to escape its pull but i think we have one last chance i am sure she will be visiting you as well she thinks we have no choice but i think a choice is all we have whatever you do hold out for better terms she has to believe that you are on side and motivated by greed so that she wont worry about any qualms you might have convince her that you will convince me to cooperate tell her that you think you should work from the collective in oslo and that you want payment via the bank in switzerland i got the impression that money is not a problem with money in a swiss bank and the expertise and connectivity afforded by the collective i think we have a chance to escape and to try to stop them perhaps we will survive this perhaps we can bring them down'"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "wcat(segment(bifid_decipher(c7bs, 'ligo', KeywordWrapAlphabet.from_a, period=4)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/2016/2016-challenge8.ipynb b/2016/2016-challenge8.ipynb
new file mode 100644 (file)
index 0000000..d990f8c
--- /dev/null
@@ -0,0 +1,180 @@
+{
+ "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.hill import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "\n",
+    "c8a = open('8a.ciphertext').read()\n",
+    "c8b = open('8b.ciphertext').read()\n",
+    "\n",
+    "c8as = sanitise(c8a)\n",
+    "c8bs = sanitise(c8b)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(matrix([[ 7,  8],\n",
+       "         [11, 11]]), -5760.41300554484)"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score = hill_break(sanitise(c8a))\n",
+    "key_a, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[('a', 312),\n",
+       " ('l', 243),\n",
+       " ('x', 228),\n",
+       " ('r', 220),\n",
+       " ('c', 216),\n",
+       " ('j', 214),\n",
+       " ('d', 210),\n",
+       " ('i', 208),\n",
+       " ('b', 207),\n",
+       " ('o', 198),\n",
+       " ('h', 192),\n",
+       " ('u', 183),\n",
+       " ('z', 169),\n",
+       " ('s', 163),\n",
+       " ('m', 162),\n",
+       " ('g', 160),\n",
+       " ('w', 145),\n",
+       " ('q', 143),\n",
+       " ('n', 140),\n",
+       " ('f', 135),\n",
+       " ('k', 133),\n",
+       " ('p', 132),\n",
+       " ('v', 131),\n",
+       " ('y', 128),\n",
+       " ('e', 120),\n",
+       " ('t', 90)]"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "collections.Counter(c8as).most_common()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "charlieandtrinityithinkwehavecomeascloseaswecantoasolutiontothisveryoddcaseofadeadwomanwhoneverdiedaweaponthatneverexistedandagovernmentinitiativethathadnothingtodowiththegovernmentmartinandjameliawereputinaterriblepositionihadntrealisedjusthowbaduntilireadtheattacheddocumentthatirecoveredfrommartinsandjameliasharddriveittellsthewholestorythesyndicateprobablythoughttheywerebeingcleverwhentheyfakedjameliasdeaththerewasaclearthreatthatonceherdeathwasrecordedassuicidetheycoulddisposeofherintheirownwayandintheirowntimeifshefailedtocooperatewhattheyfailedtorealiseisthatonceshewasofficiallydeadnoonewouldbelookingoutforheranditmadeitaloteasierforhertodisappearwhenshewantedtohavingbeencutloosefromthegovernmentthesyndicatewererelyingonsourcesintheinternationalintelligencecommunitytocarryoutsurveillanceforthembutnoonewouldbewatchingforaghostandtoomanyquestionswouldhavebeenaskediftheyrequestedasearchonceshewasofficiallydeadithinkthatdynamixrealisedearlyonwhatthetemplateapproachcoulddoforlargescalenetworkanalysisandtheyrealisedthatjameliahadthetalentandmartintheambitiontomakeitworkasasmallcompanytheyhadnothingtolosebyinvestinginitbutwhencitadelleheardrumoursthattheywereworkingonsomethingbigtheyrealisedthatthiscouldbethebreakthroughtheyneededtheirmassiveinvestmentinconventionalbattlefieldweaponrythreatenedtobecomeobsoleteonthecyberbattlefieldandtheyweresearchingforsomethingnewtorevitalisethecompanyatfirstithinktheygenuinelymisunderstoodwhatdynamixwereworkingontheconfusionbetweengravitywavesandgravitationalwavesledeveryonetoassumethatdynamixwerehopingtoweaponizeseismicactivityperhapsviaaresonanceeffectbutthiswasneveraboutaweaponofmassdestructionasjameliasexposemakescleariamnotsureatwhatpointthepostdigitalsurveillancesyndicategotinvolvedtheywereinitiallysetuptoprepareforatimewhendigitalsurveillanceisnolongereffectiveaquantumtechnologiesenvironmentinwhichthecontentofcommunicationsisencryptedsosecurelythatnoalgorithmcancrackitwithoutbetrayingitspresencetheywerekeepingacloseeyeonallthesoftwaredevelopmentteamsatarmsmanufacturersandhadkeptjameliaandmartinunderobservationwhenworkingfordynamixtheywerecertainlyquicktorealisethepotentialofthesignalnoiseanalysistechniquesthepairhaddevelopedforgravitationalwavedetectionatsomepointthoughsomeonerealisedthefundamentalflawinusingatemplatebasedapproachwhichinabetterworldwouldhaveledtotheendoftheprojectunfortunatelysomeevilgeniusatthesyndicatesawasolutionandgiventheobviouslimitsongovernmentactioninthisspheretheydecidedtoleverageprivatesectorinvolvementgiventheirhungerforrelevancecitadellewereanobvioustargetandwerebroughtintothepictureunfortunatelyforthesyndicatesomeoneatcitadelleblabbedtoaseniorcivilservantandthewholeoperationwasterminatedthejunioroperativesweredispersedamongotherdepartmentsbutthemajorplayerswereretiredwenowknowthattheremainsofthesyndicatecontinuedtooperatewithcitadelleanddynamixfundingagovernmentdepartmentnolongeriwasthrownbymartinscalltothephonelinkedtocitadelleduringtheinterviewlastweekandforamomentthoughtthathewasworkingwiththembutofcoursehewasnotphoningcitadelleifwetrackthephonewewillfindjameliawithnorealresourcesoftheirownsheandmartinseemstohaveplayedtheblackhatsattheirowngametakingwhattheyneedastheypreparedtodoublecrossthemyoumightaskwhysheisnotmakingmoreofanefforttohidefromthesyndicateanditsalliesbutthatisthebeautyofthewaytheyhavethissetupmartinstimewiththecollectivehasbeenspentseedingcopiesofthefileontoeveryserverhecouldfindifanythinghappenedtothemnowitwouldbeimpossibleforthesyndicatedynamixorcitadelletosuppresstheinformationitwouldfloodthewebtheirapparentcarelessnessweakencryptionandpoorlyhiddendocumentsmartinsappearanceonbanksurveillancecamerasandhisvisibilityonthewebwereallpartofaschemetoensuretheauthoritiesgotsuspiciousasortofinsurancepolicyitforcedthesyndicatetoprotectthemhencethehighqualitytraveldocumentstogetrealprotectionjameliahadtomakesuretheirstorycouldntbesquashedsotheyhadtobuytimesheandmartinagreedtoworkwiththesyndicateandtoconspireinjameliasfakeddeathandithinktheyconvincedthesyndicatetoletmartinjointhehackercollectivebypresentingitasagoodcoverfordatacollectionarguingthattheyneededtosetthebaselineforthebehaviouraltemplatesbutnowthebigquestiondowegopublicifwedoitwilllancetheboilandwehavearealchanceofbringingdownthesyndicateanditscollaboratorsinseveralmajorarmsmanufacturerswemightalsobeabletotracethetemplatetargetsontheotherhandifwedothatwealsoriskkillingjameliaandmartinoncethestoryispublicthereisnoreasonforthepdssyndicatetokeepthemaliveandeveryreasontosilencewitnessesidontknowwhatyouthinkbutithinkweneedtodealwiththisofflinetheoldfashionedway\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(hill_decipher(key_a, c8as))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "charlie and trinity i think we have come as close as we can to a solution to this very odd case of a dead woman who never died a weapon that never existed and a government initiative that had nothing to do with the government martin and jamelia were putin a terrible position i hadnt realised just how bad until i read the attached document that i recovered from martins and jamelia s harddrive it tells the whole story the syndicate probably thought they were being clever when they faked jamelia s death there was a clear threat that once her death was recorded as suicide they could dispose of her in their own way and in their own time if she failed to cooperate what they failed to realise is that once she was officially dead no one would be looking out for her and it made it alot easier for her to disappear when she wanted to having been cut loose from the government the syndicate were relying on sources in the international intelligence community to carryout surveillance for them but no one would be watching for a ghost and too many questions would have been asked if they requested a search once she was officially dead i think that dynamix realised early on what the template approach could do for largescale network analysis and they realised that jamelia had the talent and martin the ambition to make it work as a small company they had nothing to lose by investing in it but when citadelle heard rumours that they were working on something big they realised that this could be the breakthrough they needed their massive investment in conventional battlefield weaponry threatened to become obsolete on the cyber battlefield and they were searching for something new to revitalise the company at first i think they genuinely misunderstood what dynamix were working on the confusion between gravity waves and gravitational waves led everyone to assume that dynamix were hoping to weapon ize seismic activity perhaps via a resonance effect but this was never about a weapon of mass destruction as jamelia s expose makes clear i am not sure at what point the post digital surveillance syndicate got involved they were initially setup to prepare for a time when digital surveillance is no longer effective a quantum technologies environment in which the content of communications is encrypted so securely that no algorithm can crack it without betraying its presence they were keeping a close eye on all the software development teams at arms manufacturers and had kept jamelia and martin under observation when working for dynamix they were certainly quick to realise the potential of the signal noise analysis techniques the pair had developed for gravitational wave detection at some point though someone realised the fundamental flaw in using a template based approach which in a better world would have led to the end of the project unfortunately some evil genius at the syndicate saw a solution and given the obvious limits on government action in this sphere they decided to leverage private sector involvement given their hunger for relevance citadelle were an obvious target and were brought into the picture unfortunately for the syndicate someone at citadelle blabbed to a senior civil servant and the whole operation was terminated the junior operatives were dispersed among other departments but the major players were retired we now know that the remains of the syndicate continued to operate with citadelle and dynamix funding a government department no longer i was thrown by martins call to the phone linked to citadelle during the interview last week and for a moment thought that he was working with them but of course he was not phoning citadelle if we track the phone we will find jamelia with no real resources of their own she and martin seems to have played the black hats at their own game taking what they need as they prepared to double cross them you might ask why she is not making more of an effort to hide from the syndicate and its allies but that is the beauty of the way they have this setup martins time with the collective has been spent seeding copies of the file on to every server he could find if anything happened to them now it would be impossible for the syndicate dynamix or citadelle to suppress the information it would flood the web their apparent carelessness weak encryption and poorly hidden documents martins appearance on bank surveillance cameras and his visibility on the web were all part of a scheme to ensure the authorities got suspicious a sort of insurance policy it forced the syndicate to protect them hence the high quality travel documents to get real protection jamelia had to make sure their story couldnt be squashed so they had to buy time she and martin agreed to work with the syndicate and to conspire in jamelia s faked death and i think they convinced the syndicate to let martin join the hacker collective by presenting it as a good cover for data collection arguing that they needed to set the baseline for the behavioural templates but now the big question do we go public if we do it will lance the boil and we have a real chance of bringing down the syndicate and its collaborators in several major arms manufacturers we might also be able to trace the template targets on the other hand if we do that we also risk killing jamelia and martin once the story is public there is no reason for the pds syndicate to keep them alive and every reason to silence witnesses i dont know what you think but i think we need to deal with this offline the oldfashioned way\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(wcat(segment(hill_decipher(key_a, c8as))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[('0', 15368), ('1', 11257), (' ', 6508), ('2', 5920), ('\\n', 1)]"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "collections.Counter(c8b).most_common()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/2016/2016-challenge8b.ipynb b/2016/2016-challenge8b.ipynb
new file mode 100644 (file)
index 0000000..5a4982e
--- /dev/null
@@ -0,0 +1,739 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import math\n",
+    "\n",
+    "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.column_transposition import *\n",
+    "from cipher.keyword_cipher import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "from support.language_models import *\n",
+    "from logger import *\n",
+    "\n",
+    "c8a = open('8a.ciphertext').read()\n",
+    "c8b = open('8b.ciphertext').read()\n",
+    "\n",
+    "c8as = sanitise(c8a)\n",
+    "c8bs = sanitise(c8b)\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "3226615"
+      ]
+     },
+     "execution_count": 27,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "wap = open('../support/war-and-peace.txt').read()\n",
+    "len(wap)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['10', '00', '00', '01', '00', '111', '000', '100', '010', '101']"
+      ]
+     },
+     "execution_count": 28,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c8bc = [ch for ch in cat(c for c in c8b if c in '012').split('2') if ch]\n",
+    "c8bc[:10]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[['10', '00', '00', '01', '00'],\n",
+       " ['111', '000', '100', '010', '101'],\n",
+       " ['100', '110', '011', '011', '000'],\n",
+       " ['0010111', '1010011', '1100011', '1100000', '0000001'],\n",
+       " ['0111', '0001', '0001', '0101', '1100'],\n",
+       " ['0101', '0001', '0011', '0110', '1100'],\n",
+       " ['1', '0', '0', '0', '0'],\n",
+       " ['011', '110', '101', '000', '001'],\n",
+       " ['00', '00', '01', '11', '10'],\n",
+       " ['0010', '0010', '0100', '0100', '0000']]"
+      ]
+     },
+     "execution_count": 29,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c8bchunks = chunks(c8bc, 5, fillvalue=[[]])\n",
+    "c8bchunks[:10]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[['10000', '00010'],\n",
+       " ['10101', '10010', '10001'],\n",
+       " ['11000', '01110', '00110'],\n",
+       " ['01110', '00110', '11000', '00000', '10000', '11100', '11101'],\n",
+       " ['00001', '10011', '10000', '11110'],\n",
+       " ['00001', '10011', '00110', '11100'],\n",
+       " ['10000'],\n",
+       " ['01100', '11000', '10101'],\n",
+       " ['00011', '00110'],\n",
+       " ['00000', '00110', '11000', '00000']]"
+      ]
+     },
+     "execution_count": 30,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c8bchars = [chunks(column_transposition_encipher(cat(char), 'abcde', fillcolumnwise=True, emptycolumnwise=False), 5)\n",
+    " for char in c8bchunks]\n",
+    "c8bchars[:10]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(25, 0)"
+      ]
+     },
+     "execution_count": 31,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c8pos = [[int(cat(reversed(c)), 2) for c in bword] for bword in c8bchars]\n",
+    "max(n for ns in c8pos for n in ns), min(n for ns in c8pos for n in ns)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'bi vjr dom omdabhx qzbp qzmh b gdv ym amda dxdbh ebffma qtbnm hjt yv qzm kjpq abxbqdf prosmbffdhnm p'"
+      ]
+     },
+     "execution_count": 32,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c8text = wcat(cat(unpos(int(cat(reversed(c)), 2)) for c in bword) for bword in c8bchars)\n",
+    "c8text[:100]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "5325"
+      ]
+     },
+     "execution_count": 33,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(sanitise(c8text))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "5325"
+      ]
+     },
+     "execution_count": 34,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "eng_target = sanitise(wap)[:5325]\n",
+    "len(eng_target)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "5325"
+      ]
+     },
+     "execution_count": 35,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "random_target = cat(random.choice(string.ascii_lowercase) for _ in range(5325))\n",
+    "len(random_target)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 36,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(-32687.168128732188, -20426.14140719279, -30689.376594117315)"
+      ]
+     },
+     "execution_count": 36,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "Ptrigrams(sanitise(c8text)), Ptrigrams(sanitise(eng_target)), Ptrigrams(sanitise(random_target))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 37,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "40669.896112351824"
+      ]
+     },
+     "execution_count": 37,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(21000 - 32700) / math.log(0.75)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 38,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "3476.059496782207"
+      ]
+     },
+     "execution_count": 38,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(21000 - 22000) / math.log(0.75)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 39,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2391.2432630309268"
+      ]
+     },
+     "execution_count": 39,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(21000 - 32700) / math.log(0.0075)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 40,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2.788846178301471e+22"
+      ]
+     },
+     "execution_count": 40,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "math.exp((21000 - 327) / 400)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 41,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0.951229424500714"
+      ]
+     },
+     "execution_count": 41,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "math.exp(((-32000) - (-30000)) / 40000)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 42,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1738.0297483911036"
+      ]
+     },
+     "execution_count": 42,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(-500) / math.log(0.75)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 43,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'etoainhsrdlumwycfgpbvkxjqz'"
+      ]
+     },
+     "execution_count": 43,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ltrs = [p[0] for p in english_counts.most_common()]\n",
+    "cat(ltrs)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 44,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'mqdbjhopzafrntgxvkiyseuclw'"
+      ]
+     },
+     "execution_count": 44,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ctls =  [p[0] for p in collections.Counter(sanitise(c8text)).most_common()]\n",
+    "cat(ctls)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 45,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "ap fiu ohe heodanc tras tren a yof be deod ocoan kalled twame niw bf tre gist dacatol suhveallonme sfndamote ap a oy stall olave tren fiu yof be yf inlf rige ap tref rove kalled ye tren tras letteh wall rove been dasthabuted an unenmhfgted pihy ti oll tre simaol yedao sates ond oll tre news ocenmaes an tre wihld treah noye wall be kniwn ti evehfine ond tre stihf ip wrot tref thaed ti di wall be reodlane news ap nit tren yf rige as trot fiu wall keeg tras quaet pih niw pih fiuh soke os well os pih yane yf noye as joyelao dolyoh ond a oy gohtlf hesginsable pih tras yess tras letteh as yf otteygt ti exgloan yf hile an wrot roggened an tre rige trot nitranc lake at wall eveh roggen ocoan tre sfndamote wos o civehnyent anataotave ti ghegohe pih o wihld an wramr enmhfgtain wall be si semuhe trot ni ine mon mhomk at trot wihld as olyist rehe ond tre quontuy temrnilicf hevilutain as lakelf ti cave bahtr ti at siin ap nitranc mronces ghavomf wall be obsilute ond si wall semhemf riw fiu peel obiut trot degends o lit in wri fiu ohe ond wri fiu trank ros yist ti coan a wos neuthol but wren yf phaend yohtan succested trot we miuld odogt siye ip tre temrnilicf we develiged pih tre laci ghijemt a wos exmated ot tre gissabalataes iuh glon wos ti buald berovaiuhol teyglote paltehs ti thomk chiug omtavataes in tre web ihacanollf we riged ti yidel tre sgheod ip adeos yohtan wos antehested an tre yohketanc oncle ond sow at os o wof ip sellanc ghidumts bf undehstondanc riw yeyes ghigocote a wos yihe antehested an undehstondanc riw gilatamol adeos sgheod trhiucr o gigulotain at wos o yallain yales phiy iuh heol oheos ip exgehtase ond a sriuld rove heolased tre doncehs yumr eohlaeh tre woh coyes degohtyent ot dfnoyax sow tre gitentaol pih tras tiil ti be used os o twentf pahst mentuhf vehsain ip sacant olliwanc antellacenme ocenmaes ond civehnyents ti thomk syoll chiug omtavataes bf yotmranc inlane berovaiuh ti kniwn teyglotes syoll chiugs anmludanc tehhihast mells tre gds sfndamote rod ocents ot just obiut evehf ohys yonupomtuheh an tre west anmludanc dfnoyax wren tref bemoye owohe ip iuh wihk tref ohhonced pih dfnoyax ti hemhuat us in treah antehn smreye at wos on oyozanc taye we rod evehf hesiuhme we miuld wont ond ot pahst tre pheediy ti di wrot we wonted centlf tref bhiucrt us hiund ti wihkanc in syoll chiug dfnoyam thomkanc ond pilliwanc siye ip tre hement thocedaes a wihked iut pih yfselp tre gitentaol ip iuh siptwohe ti detemt ond ghevent tehhihasy but we needed doto we molled at tre teyg bonk o dotobose ip berovaiuhol teyglotes wramr we wiuld use ti yotmr ocoanst lave inlane thoppam ti racrlacrt oheos ip antehest ni ine rod eveh wihked in tras siht ip gottehn bosed thomkanc bepihe si we rod ni doto in wramr ti bose tre teyglotes yidellanc miyyunamotain gottehns between yeybehs ip o tehhihast chiug watriut tre teyglotes at wos aygissable ti mohhf iut heol taye yinatihanc os tre doto hote wos poh tii racr pih lave onolfsas a hoased yf minmehns watr tre reod ip heseohmr ot dfnoyax ond trot wos wren a wos anthidumed ti siyeine phiy tre sfndamote tref ghiyased us doto bosed in yotreyotamol yidels develiged bf tre degohtyent ip depenme ond tre ghijemt mintanued at wos yihe summesspul tron we rod dohed ti rige o stheoy ip racr quolatf doto palled tre teyg bonk ond tre olcihatry becon ti sgit heol wihld exoygles trot mliself yotmred tre teyglotes ip miuhse o lit ip trot wos just mrotteh trehe as o wihld ip dappehenme between dasmussanc ond mohhfanc iut on ottomk ond ni semuhatf sehvame mon anvestacote evehf deluded pontosf inlane an ihdeh ti pand tre ine heol glit dfnoyax wehe exmated bf wrot we rod omraeved but os tre hesults hilled an tref deyonded yihe ommuhomf ond pih trot we needed yumr betteh doto tre sfndamote wehe roggf ti iblace ond trot as wren a heolased tre riw poh tref wehe ghegohed ti ci a thaed ti minvanme yfselp trot tre sfndamote rod ommess ti o lohce dotobose ip exastanc miyyunamotains trot tref wehe usanc ti exthomt berovaiuhol teyglotes but tre yihe a triucrt obiut at tre yihe unlakelf at seeyed iuh siptwohe wos seeanc heol wihld ottomk gottehns trot wehe susgamaiuslf sayaloh olyist mriheichogred ond a becon ti windeh ap tre gds sfndamote wehe nit just thomkanc tehhihast omtavatf but wehe enmiuhocanc at oyinc chiugs trot tref rod genethoted an ihdeh ti buald on enmfmligoedao ip berovaiuhol teyglotes trot miuld be used ti sgit putuhe ottomks bepihe tref roggened tre sfndamote rod on omralles reel at wos nit gissable ti miihdanote treah heseohmr ghichoyye watriut leovanc treah iwn dacatol piitghant yohtan ond a hepimused iuh eppihts in thomkanc trey diwn ond piund oll tre evadenme we needed but tref wehe tre exgehts nit us ond we yust rove thaccehed on olohy siyewrehe tref cove us ine mriame yf deotr wos niw anevatoble tre inlf questain wos wretreh ih nit at wiuld be poked inme a wos ippamaollf deod a wiuld rove ni ghitemtain but we wehe voluoble ti trey ond trot wos tre kef ti iuh suhvavol a neveh knew tre noye ip tre cahl tref used ti poke yf suamade but tref dad ossuhe ye trot sre rod daed ip notuhol mouses a rige trot yumr wos thue tre sfndamote wehe tre heol exgehts an esgainoce but yohtan ond a rod tre edce an midanc tref wotmred us mohepullf but we yonoced ti glont o vahus an tre dotobose encane ond at wall rove been thaccehed linc bepihe fiu heod tras at as desacned ti anpemt evehf migf ip iuh olcihatry ond ti enmhfgt mhumaol eleyents ip tre mide hendehanc at unusoble we leohned o lit phiy studfanc stuxnet ond tre teyg bonk wall suppeh tre soye pote os tre ahonaon menthapuces niw tre vahus as heleosed we minvanmed tre sfndamote ti pund o romkeh millemtave an nihwof ond ti olliw yohtan ti wihk trehe undehmiveh os poh os tref wehe minmehned re wall be rohvestanc boselane doto pih niase paltehanc an simaol yedao thoppam but re wall be dasthabutanc tras pale ond tre vahus ti os yonf sehvehs os re mon watriut olehtanc trey yohtan as ciid ot tras re ros olheodf romked o nuybeh ip bomk ug miygonf ond ogg sehvehs ond used trey os o dasthabutain yemronasy we rove olsi been leovanc o thoal pih tre antellacenme sehvames we rove ni heosin ti belaeve tre civehnyents ohe minnemted watr tras ond evehf heosin ti belaeve tref yof be iuh best rige ip stigganc trey ohe we sope ghiboblf nit ih tras ansuhonme gilamf wiuld rove heyoaned just trot we yacrt be in tre hun triucr unoble ti thacceh tre deod yon swatmr trot wos keeganc trese pales sope we di nit glon in cavanc ug ond we uhce fiu nit ti eatreh\n"
+     ]
+    }
+   ],
+   "source": [
+    "trans = {pr[0]: pr[1] for pr in zip(ctls, ltrs)}\n",
+    "tt = ''.maketrans(trans)\n",
+    "print(c8text.translate(tt))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 46,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "-21381.986189863124"
+      ]
+     },
+     "execution_count": 46,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "Ptrigrams(sanitise(c8text.translate(tt)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 47,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'dajoklynpigqemhstuvwxfzcbr'"
+      ]
+     },
+     "execution_count": 47,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c8alphabet0 = cat(trans[l] for l in sorted(trans))\n",
+    "c8alphabet0"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 48,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# logger.setLevel(logging.DEBUG)\n",
+    "logger.setLevel(logging.WARN)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 49,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('mqjdbhzpoafrgtvnixkyseuclw', -17922.293053151883)"
+      ]
+     },
+     "execution_count": 49,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cipher_alphabet, score = simulated_annealing_break(\n",
+    "    sanitise(c8text), workers=3,\n",
+    "    initial_temperature=200, max_iterations=20000, \n",
+    "    plain_alphabet=cat(ltrs), cipher_alphabet=cat(ctls),\n",
+    "    fitness=Ptrigrams)\n",
+    "cipher_alphabet, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 50,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'if you are reading this then i may be dead again killed twice now by the post digital surveillance syndicate if i am still alive then you may be my only hope if they have killed me then this letter will have been distributed in unencrypted form to all the social media sites and all the news agencies in the world their name will be known to everyone and the story of what they tried to do will be headline news if not then my hope is that you will keep this quiet for now for your sake as well as for mine my name is jamelia dalmar and i am partly responsible for this mess this letter is my attempt to explain my role in what happened in the hope that nothing like it will ever happen again the syndicate was a government initiative to prepare for a world in which encryption will be so secure that no one can crack it that world is almost here and the quantum technology revolution is likely to give birth to it soon if nothing changes privacy will be absolute and so will secrecy how you feel about that depends a lot on who you are and who you think has most to gain i was neutral but when my friend martin suggested that we could adapt some of the technology we developed for the ligo project i was excited at the possibilities our plan was to build behavioural template filters to track group activities on the web originally we hoped to model the spread of ideas martin was interested in the marketing angle and saw it as a way of selling products by understanding how memes propagate i was more interested in understanding how political ideas spread through a population it was a million miles from our real areas of expertise and i should have realised the dangers much earlier the war games department at dynamix saw the potential for this tool to be used as a twenty first century version of sigint allowing intelligence agencies and governments to track small group activities by matching online behaviour to known templates small groups including terrorist cells the pds syndicate had agents at just about every arms manufacturer in the west including dynamix when they became aware of our work they arranged for dynamix to recruit us on their intern scheme it was an amazing time we had every resource we could want and at first the freedom to do what we wanted gently they brought us round to working on small group dynamic tracking and following some of the recent tragedies i worked out for myself the potential of our software to detect and prevent terrorism but we needed data we called it the temp bank a database of behavioural templates which we would use to match against live online traffic to highlight areas of interest no one had ever worked on this sort of pattern based tracking before so we had no data on which to base the templates modelling communication patterns between members of a terrorist group without the templates it was impossible to carry out real time monitoring as the data rate was far too high for live analysis i raised my concerns with the head of research at dynamix and that was when i was introduced to someone from the syndicate they promised us data based on mathematical models developed by the department of defence and the project continued it was more successful than we had dared to hope a stream of high quality data filled the temp bank and the algorithm began to spot real world examples that closely matched the templates of course a lot of that was just chatter there is a world of difference between discussing and carrying out an attack and no security service can investigate every deluded fantasy online in order to find the one real plot dynamix were excited by what we had achieved but as the results rolled in they demanded more accuracy and for that we needed much better data the syndicate were happy to oblige and that is when i realised the how far they were prepared to go i tried to convince myself that the syndicate had access to a large database of existing communications that they were using to extract behavioural templates but the more i thought about it the more unlikely it seemed our software was seeing real world attack patterns that were suspiciously similar almost choreographed and i began to wonder if the pds syndicate were not just tracking terrorist activity but were encouraging it among groups that they had penetrated in order to build an encyclopaedia of behavioural templates that could be used to spot future attacks before they happened the syndicate had an achilles heel it was not possible to coordinate their research programme without leaving their own digital footprint martin and i refocused our efforts on tracking them down and found all the evidence we needed but they were the experts not us and we must have triggered an alarm somewhere they gave us one choice my death was now inevitable the only question was whether or not it would be faked once i was officially dead i would have no protection but we were valuable to them and that was the key to our survival i never knew the name of the girl they used to fake my suicide but they did assure me that she had died of natural causes i hope that much was true the syndicate were the real experts in espionage but martin and i had the edge in coding they watched us carefully but we managed to plant a virus in the database engine and it will have been triggered long before you read this it is designed to infect every copy of our algorithm and to encrypt crucial elements of the code rendering it unusable we learned a lot from studying stuxnet and the temp bank will suffer the same fate as the iranian centrifuges now the virus is released we convinced the syndicate to fund a hacker collective in norway and to allow martin to work there undercover as far as they were concerned he will be harvesting baseline data for noise filtering in social media traffic but he will be distributing this file and the virus to as many servers as he can without alerting them martin is good at this he has already hacked a number of back up company and app servers and used them as a distribution mechanism we have also been leaving a trail for the intelligence services we have no reason to believe the governments are connected with this and every reason to believe they may be our best hope of stopping them are we safe probably not or this insurance policy would have remained just that we might be on the run though unable to trigger the dead man switch that was keeping these files safe we do not plan on giving up and we urge you not to either'"
+      ]
+     },
+     "execution_count": 50,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cipher_translation = ''.maketrans(cipher_alphabet, cat(ltrs))\n",
+    "c8text.translate(cipher_translation)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 51,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "# cipher_alphabet, score = simulated_annealing_break_worker(\n",
+    "#     sanitise(c8text), \n",
+    "#     ltrs, ctls,\n",
+    "#     700, \n",
+    "#     200,\n",
+    "#     Ptrigrams)\n",
+    "# cipher_alphabet, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 52,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'a': 'd',\n",
+       " 'b': 'y',\n",
+       " 'c': 'n',\n",
+       " 'd': 'a',\n",
+       " 'e': 'm',\n",
+       " 'f': 'i',\n",
+       " 'g': 'x',\n",
+       " 'h': 'z',\n",
+       " 'i': 'b',\n",
+       " 'j': 'c',\n",
+       " 'k': 'e',\n",
+       " 'l': 'f',\n",
+       " 'm': 'g',\n",
+       " 'n': 'h',\n",
+       " 'o': 'j',\n",
+       " 'p': 'k',\n",
+       " 'q': 'l',\n",
+       " 'r': 'o',\n",
+       " 's': 'p',\n",
+       " 't': 'q',\n",
+       " 'u': 'r',\n",
+       " 'v': 's',\n",
+       " 'w': 't',\n",
+       " 'x': 'u',\n",
+       " 'y': 'v',\n",
+       " 'z': 'w'}"
+      ]
+     },
+     "execution_count": 52,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "{chr(v): chr(k) for k, v in cipher_translation.items()}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 53,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'if you are reading this then i may be dead again killed twice now by the post digital surveillance syndicate if i am still alive then you may be my only hope if they have killed me then this letter will have been distributed in unencrypted form to all the social media sites and all the news agencies in the world their name will be known to everyone and the story of what they tried to do will be headline news if not then my hope is that you will keep this quiet for now for your sake as well as for mine my name is jamelia dalmar and i am partly responsible for this mess this letter is my attempt to explain my role in what happened in the hope that nothing like it will ever happen again the syndicate was a government initiative to prepare for a world in which encryption will be so secure that no one can crack it that world is almost here and the quantum technology revolution is likely to give birth to it soon if nothing changes privacy will be absolute and so will secrecy how you feel about that depends a lot on who you are and who you think has most to gain i was neutral but when my friend martin suggested that we could adapt some of the technology we developed for the ligo project i was excited at the possibilities our plan was to build behavioural template filters to track group activities on the web originally we hoped to model the spread of ideas martin was interested in the marketing angle and saw it as a way of selling products by understanding how memes propagate i was more interested in understanding how political ideas spread through a population it was a million miles from our real areas of expertise and i should have realised the dangers much earlier the war games department at dynamix saw the potential for this tool to be used as a twenty first century version of sigint allowing intelligence agencies and governments to track small group activities by matching online behaviour to known templates small groups including terrorist cells the pds syndicate had agents at just about every arms manufacturer in the west including dynamix when they became aware of our work they arranged for dynamix to recruit us on their intern scheme it was an amazing time we had every resource we could want and at first the freedom to do what we wanted gently they brought us round to working on small group dynamic tracking and following some of the recent tragedies i worked out for myself the potential of our software to detect and prevent terrorism but we needed data we called it the temp bank a database of behavioural templates which we would use to match against live online traffic to highlight areas of interest no one had ever worked on this sort of pattern based tracking before so we had no data on which to base the templates modelling communication patterns between members of a terrorist group without the templates it was impossible to carry out real time monitoring as the data rate was far too high for live analysis i raised my concerns with the head of research at dynamix and that was when i was introduced to someone from the syndicate they promised us data based on mathematical models developed by the department of defence and the project continued it was more successful than we had dared to hope a stream of high quality data filled the temp bank and the algorithm began to spot real world examples that closely matched the templates of course a lot of that was just chatter there is a world of difference between discussing and carrying out an attack and no security service can investigate every deluded fantasy online in order to find the one real plot dynamix were excited by what we had achieved but as the results rolled in they demanded more accuracy and for that we needed much better data the syndicate were happy to oblige and that is when i realised the how far they were prepared to go i tried to convince myself that the syndicate had access to a large database of existing communications that they were using to extract behavioural templates but the more i thought about it the more unlikely it seemed our software was seeing real world attack patterns that were suspiciously similar almost choreographed and i began to wonder if the pds syndicate were not just tracking terrorist activity but were encouraging it among groups that they had penetrated in order to build an encyclopaedia of behavioural templates that could be used to spot future attacks before they happened the syndicate had an achilles heel it was not possible to coordinate their research programme without leaving their own digital footprint martin and i refocused our efforts on tracking them down and found all the evidence we needed but they were the experts not us and we must have triggered an alarm somewhere they gave us one choice my death was now inevitable the only question was whether or not it would be faked once i was officially dead i would have no protection but we were valuable to them and that was the key to our survival i never knew the name of the girl they used to fake my suicide but they did assure me that she had died of natural causes i hope that much was true the syndicate were the real experts in espionage but martin and i had the edge in coding they watched us carefully but we managed to plant a virus in the database engine and it will have been triggered long before you read this it is designed to infect every copy of our algorithm and to encrypt crucial elements of the code rendering it unusable we learned a lot from studying stuxnet and the temp bank will suffer the same fate as the iranian centrifuges now the virus is released we convinced the syndicate to fund a hacker collective in norway and to allow martin to work there undercover as far as they were concerned he will be harvesting baseline data for noise filtering in social media traffic but he will be distributing this file and the virus to as many servers as he can without alerting them martin is good at this he has already hacked a number of back up company and app servers and used them as a distribution mechanism we have also been leaving a trail for the intelligence services we have no reason to believe the governments are connected with this and every reason to believe they may be our best hope of stopping them are we safe probably not or this insurance policy would have remained just that we might be on the run though unable to trigger the dead man switch that was keeping these files safe we do not plan on giving up and we urge you not to either'"
+      ]
+     },
+     "execution_count": 53,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "keyword_decipher(c8text, 'dynamix', KeywordWrapAlphabet.from_last)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 54,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('mqjdbhzpoafrgtvnixkyseuclw', -17922.293053151883)"
+      ]
+     },
+     "execution_count": 54,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cipher_alphabet, score = monoalphabetic_break_hillclimbing_mp(\n",
+    "    sanitise(c8text), workers=3,\n",
+    "    max_iterations=20000, \n",
+    "    plain_alphabet=cat(ltrs), cipher_alphabet=cat(ctls),\n",
+    "    fitness=Ptrigrams)\n",
+    "cipher_alphabet, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 55,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('dynamixzbcefghjklopqrstuvw', -17922.293053151883)"
+      ]
+     },
+     "execution_count": 55,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cipher_alphabet, score = simulated_annealing_break(\n",
+    "    sanitise(c8text), workers=3,\n",
+    "    initial_temperature=200, max_iterations=20000, \n",
+    "#     plain_alphabet=cat(ltrs), cipher_alphabet=cat(ctls),\n",
+    "    fitness=Ptrigrams)\n",
+    "cipher_alphabet, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 56,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'if you are reading this then i may be dead again killed twice now by the post digital surveillance syndicate if i am still alive then you may be my only hope if they have killed me then this letter will have been distributed in unencrypted form to all the social media sites and all the news agencies in the world their name will be known to everyone and the story of what they tried to do will be headline news if not then my hope is that you will keep this quiet for now for your sake as well as for mine my name is jamelia dalmar and i am partly responsible for this mess this letter is my attempt to explain my role in what happened in the hope that nothing like it will ever happen again the syndicate was a government initiative to prepare for a world in which encryption will be so secure that no one can crack it that world is almost here and the quantum technology revolution is likely to give birth to it soon if nothing changes privacy will be absolute and so will secrecy how you feel about that depends a lot on who you are and who you think has most to gain i was neutral but when my friend martin suggested that we could adapt some of the technology we developed for the ligo project i was excited at the possibilities our plan was to build behavioural template filters to track group activities on the web originally we hoped to model the spread of ideas martin was interested in the marketing angle and saw it as a way of selling products by understanding how memes propagate i was more interested in understanding how political ideas spread through a population it was a million miles from our real areas of expertise and i should have realised the dangers much earlier the war games department at dynamix saw the potential for this tool to be used as a twenty first century version of sigint allowing intelligence agencies and governments to track small group activities by matching online behaviour to known templates small groups including terrorist cells the pds syndicate had agents at just about every arms manufacturer in the west including dynamix when they became aware of our work they arranged for dynamix to recruit us on their intern scheme it was an amazing time we had every resource we could want and at first the freedom to do what we wanted gently they brought us round to working on small group dynamic tracking and following some of the recent tragedies i worked out for myself the potential of our software to detect and prevent terrorism but we needed data we called it the temp bank a database of behavioural templates which we would use to match against live online traffic to highlight areas of interest no one had ever worked on this sort of pattern based tracking before so we had no data on which to base the templates modelling communication patterns between members of a terrorist group without the templates it was impossible to carry out real time monitoring as the data rate was far too high for live analysis i raised my concerns with the head of research at dynamix and that was when i was introduced to someone from the syndicate they promised us data based on mathematical models developed by the department of defence and the project continued it was more successful than we had dared to hope a stream of high quality data filled the temp bank and the algorithm began to spot real world examples that closely matched the templates of course a lot of that was just chatter there is a world of difference between discussing and carrying out an attack and no security service can investigate every deluded fantasy online in order to find the one real plot dynamix were excited by what we had achieved but as the results rolled in they demanded more accuracy and for that we needed much better data the syndicate were happy to oblige and that is when i realised the how far they were prepared to go i tried to convince myself that the syndicate had access to a large database of existing communications that they were using to extract behavioural templates but the more i thought about it the more unlikely it seemed our software was seeing real world attack patterns that were suspiciously similar almost choreographed and i began to wonder if the pds syndicate were not just tracking terrorist activity but were encouraging it among groups that they had penetrated in order to build an encyclopaedia of behavioural templates that could be used to spot future attacks before they happened the syndicate had an achilles heel it was not possible to coordinate their research programme without leaving their own digital footprint martin and i refocused our efforts on tracking them down and found all the evidence we needed but they were the experts not us and we must have triggered an alarm somewhere they gave us one choice my death was now inevitable the only question was whether or not it would be faked once i was officially dead i would have no protection but we were valuable to them and that was the key to our survival i never knew the name of the girl they used to fake my suicide but they did assure me that she had died of natural causes i hope that much was true the syndicate were the real experts in espionage but martin and i had the edge in coding they watched us carefully but we managed to plant a virus in the database engine and it will have been triggered long before you read this it is designed to infect every copy of our algorithm and to encrypt crucial elements of the code rendering it unusable we learned a lot from studying stuxnet and the temp bank will suffer the same fate as the iranian centrifuges now the virus is released we convinced the syndicate to fund a hacker collective in norway and to allow martin to work there undercover as far as they were concerned he will be harvesting baseline data for noise filtering in social media traffic but he will be distributing this file and the virus to as many servers as he can without alerting them martin is good at this he has already hacked a number of back up company and app servers and used them as a distribution mechanism we have also been leaving a trail for the intelligence services we have no reason to believe the governments are connected with this and every reason to believe they may be our best hope of stopping them are we safe probably not or this insurance policy would have remained just that we might be on the run though unable to trigger the dead man switch that was keeping these files safe we do not plan on giving up and we urge you not to either'"
+      ]
+     },
+     "execution_count": 56,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cipher_translation = ''.maketrans(cipher_alphabet, string.ascii_lowercase)\n",
+    "c8text.translate(cipher_translation)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/2016/2a.ciphertext b/2016/2a.ciphertext
new file mode 100644 (file)
index 0000000..0d52e05
--- /dev/null
@@ -0,0 +1,19 @@
+INGXROK
+ZNK TUZK EUA YKTZ UBKX CGY ZXOIQOKX ZNGT O KDVKIZKJ. PGSKROG JOJT’Z PAYZ XKBKXYK ZNK CNURK SKYYGMK HKLUXK KTIXEVZOTM OZ, YNK VAZ GRR ZNK VATIZAGZOUT GTJ YVGIOTM HGIQ OT ZNK UXOMOTGR VRGIKY ZU ZNXUC ZNK IGYAGR XKGJKX ULL ZNK YIKTZ. OZ CGYT’Z BKXE YUVNOYZOIGZKJ, HAZ OZ CGY JKBOUAY, GTJ ZKRRY AY YUSKZNOTM GHUAZ ZNK CGE YNK ZNOTQY. UTK ZNOTM O GS IKXZGOT GHUAZ, ZNOY JUKYT’Z XKGJ ROQK G YAOIOJK TUZK. CNU CXOZKY UTK UL ZNUYK OT IUJK?
+
+UAX LOKRJ GMKTZ GYQKJ GXUATJ GZ ZNK ATOBKXYOZE GTJ CGY ZURJ ZNGZ PGSKROG’Y HUELXOKTJ CUXQKJ OT ZNK YGSK RGH GY NKX LUX G CNORK. NOY TGSK OY SGXZOT ZXGETUX GTJ ZNKE HUZN JOJ GT OTZKXTYNOV OT ZNKOX YKIUTJ EKGX GZ G YVOTUAZ IUSVGTE IGRRKJ JETGSOD. ZNGZ OY G YSGRR YZGXZAV CNOIN CUXQY UT ZNK LXOTMKY UL ZNK GXSY OTJAYZXE, HAZ TU-UTK YKKSY ZU QTUC SAIN GHUAZ OZ.
+
+O GS TUZ YAXK CNE JETGSOD CUARJ NGBK NOXKJ PGSKROG; EUA YGOJ ZNGZ YNK CGY CUXQOTM UT MXGBOZE CGBKY, CNOIN GXK G YKOYSURUMOIGR VNKTUSKTUT. O XKGJ GT OTZKXKYZOTM VGVKX IGRRKJ “MXGBOZE CGBKY OT KGXZNWAGQKY” CNOIN YAMMKYZKJ ZNGZ ZNKE SOMNZ HK XKYVUTYOHRK LUX ZNK JKYZXAIZOUT UL NOMN XOYK HRUIQY JAXOTM YUSK ZXKSUXY. HAZ ATRKYY JETGSOD GXK VRGTTOTM ZU ZXE ZU CKGVUTOYK KGXZNWAGQKY O GS TUZ YAXK CNE ZNOY CUARJ HK UL OTZKXKYZ ZU ZNKS. CK TKKJ ZU QTUC SUXK GHUAZ NKX CUXQ GTJ CNGZ ZNKE NOXKJ NKX ZU JU.
+
+ZNKXK GXK G RUZ UL WAKYZOUTY KBKT OT ZNK LOXYZ TUZK:
+
+CNE JOJ SGXZOT RKGBK?
+CNKXK OY NK?
+CNE IUARJT’Z YNK MKZ NURJ UL NOS?
+CNGZ CGY ZUU HOM LUX PGSKROG ZU NGTJRK GRUTK?
+CNGZ SGJK PGSKROG LKKR MAORZE?
+NUC CGY YNK VRGTTOTM ZU LOD OZ?
+
+O GS NUVOTM ZNGZ ZNK GZZGINKJ JUIASKTZ CORR GTYCKX YUSK UL ZNKYK WAKYZOUTY HAZ OZ CORR VXUHGHRE PAYZ XGOYK UZNKXY. O LUATJ OZ VGYZKJ ATJKX ZNK IUBKX UL ZNK TUZKHUUQ ZNGZ ZNK VXKBOUAY SKYYGMK CGY ZGQKT LXUS. O IGT YKK CNE ZNK VUROIK SOYYKJ OZ, ZNUAMN OZ CGYT’Z G BKXE VXULKYYOUTGR PUH.
+
+NGXXE
diff --git a/2016/2b.ciphertext b/2016/2b.ciphertext
new file mode 100644 (file)
index 0000000..4845483
--- /dev/null
@@ -0,0 +1,13 @@
+NHFXCZDYX KDS TLSCZY,
+
+RUB LSF VZCLAFOOF ZYCFSFXCFA ZY ABYLTZW?
+UDR AZA ABYLTZW PFC TB VDAF-QLXF?
+RULC LSF ABYLTZW IOLYYZYP CD AD RZCU ZC?
+RUB ZX UF XCZOO ZYMDOMFA RZCU CUFT?
+RUD LSF CUF IAX XBYAZVLCF?
+
+Z CUZYJ Z JYDR CUF LYXRFSX, LYA Z LT ISFCCB XHSF UF THXC AD CDD. CUF CUSFF TDYCUX RF XIFYC RDSJZYP LC ABYLTZW RFSF XDTF DK CUF TDXC FWVZCZYP Z ULMF FMFS FWIFSZFYVFA, QHC XHSFOB, JYDRZYP RULC RF JYDR YDR, FMFY TLSCZY THXC ULMF XDTF SFXFSMLCZDYX LQDHC RDSJZYP RZCU CUFXF IFDIOF.
+
+Z LT YDC XHSF RUD CD CLOJ CD LQDHC CUZX. Z LT VFSCLZY CULC XDTF TFTQFSX DK CUF QDLSA LC ABYLTZW LSF VDTIOFCFOB ZY CUF ALSJ LQDHC ZC, YD VDYXIZSLVB RZCU CULC TLYB TFTQFSX VDHOA ULMF XHSMZMFA TDSF CULY L RFFJ, QHC Z ULMF YD ZAFL RUZVU DK CUFT Z VLY CSHXC. Z CUDHPUC Z VDHOA CSHXC TLSCZY, QHC CULC RLX QFKDSF CUF IAX ULVJ.
+
+Z VLY’C CLOJ CD CUF IDOZVF; XIFVZLO QSLYVU LSF VFSCLZY CD KOLP ZC PZMFY CUF YLTFX DK XDTF DK CUF IFDIOF DY CUF QDLSA. RZCU CUFZS VDYYFVCZDYX RUD JYDRX RULC TZPUC ULIIFY. CUF IAX XBYAZVLCF LSF CDD QZP KDS TF CD ULYAOF LODYF. CUFB JYDR LOTDXC FMFSBCUZYP LQDHC TF, LYA Z JYDR YFWC CD YDCUZYP LQDHC CUFT. ZK Z XCLB UFSF CD KZPUC, CUFY ZC ZX DYOB L TLCCFS DK CZTF HYCZO CUFB SFLOZXF Z LT DY CD CUFT. ZK Z ULMFY’C AZXLIIFLSFA QFKDSF CUFY, CUFY Z ULMF L KFFOZYP CUFB RZOO TLJF TF AZXLIIFLS.
diff --git a/2016/3a.ciphertext b/2016/3a.ciphertext
new file mode 100644 (file)
index 0000000..9dce044
--- /dev/null
@@ -0,0 +1,9 @@
+YWJJU,
+
+ZN AWDOCZW QWK QGJBZFX GF W KSYODO LG QOWHGFZKO OWJLYIMWBOK, LYOF QO FOOT LG BFGQ YGQ NWJ KYO YWT XGL. Z YWPO KOFL LJZFZLU ZF LG QGJB MFTOJSGPOJ ZF AWDOCZW’K CWE WFT LWKBOT YOJ LG LJU LG ZFNZCLJWLO TUFWDZR NJGD LYOJO. LJZFZLU ZKF’L LGG YWHHU LYOJO, AWDOCZW’K GNNZSO ZKF’L DMSY EZXXOJ LYWF W EJGGD SCGKOL, EML QO FOOT LG LJU LG NZFT LYO SGTO EWKO JONOJJOT LG ZF LYO YZTTOF TZWJU OFLJU.
+
+ZF LYO DOWFLZDO, Z YWPO EOOF QGJBZFX GF LYO CZKL GN IMOKLZGFK UGM WFT AWDOCZW QOJO WKBZFX. NZJKL: QYU TZT DWJLZF COWPO? WSSGJTZFX LG YZK NCWLDWLO YO NCOQ LG XOFOPW NGJ LWCBK QZLY W SGDHWFU SWCCOT SZLWTOCCO. GMJ CGSWC WXOFLK WJO DWBZFX OFIMZJZOK, EML ZL KOODK LYWL LYOU WJO LYWL JWJOKL GN LYZFXK, WF OKLWECZKYOT WJDK DWFMNWSLMJOJ QZLY DGFOU QGJJZOK. KOSGFT: QYOJO ZK DWJLZF FGQ? FG-GFO BFGQK. SZLWTOCCO TOFU WFU BFGQCOTXO GN YZD, WFT LYOJO ZK FG JOSGJT GN YZD COWPZFX LYO SGMFLJU. YO YWK TZKWHHOWJOT.
+
+LYO DGKL ZFLJZXMZFX LYZFX NJGD AWDOCZW’K CWKL DOKKWXO ZK LYO JONOJOFSO LG LYO HTK KUFTZSWLO. Z YWPO YOWJT JMDGMJK GN LYZK DUKOCN ZF QYZLOYWCC. ZL ZK WCC POJU YMKY-YMKY WFT ZL ZK FGL OPOF SCOWJ ZN ZL ZK WF GNNZSZWC ZFZLZWLZPO.
+
+LYO EZX FOQK NGJ FGQ ZK W EJOWBLYJGMXY GF LYO KG SWCCOT KMZSZTO FGLO. XZPOF YGQ KDWCC AWDOCZW’K GNNZSO QWK, LJZFZLU QGFTOJOT QYU KYO YWT BOHL W EJGBOF HJZFLOJ ZF LYOJO FORL LG LYO QGJBZFX GFO. LJZFZLU GHOFOT ZL MH WFT NGMFT W NOQ DGTZNZSWLZGFK QYZSY HGZFLOT LYO CWKOJ KLJWZXYL WL LYO HWHOJ ZFKLOWT GN LYO TJMD. KYO XGL ZF LGMSY QZLY LYO CWE WFT XGL LYOD LG LWBO WFGLYOJ CGGB WL LYO COLLOJ. LYOU NGMFT LYO WLLWSYOT DOKKWXO EMJFOT ZFLG LYO HWHOJ NZEJOK. ZL ZK ZDHGKKZECO LG KOO QZLY LYO FWBOT OUO, EML LYO SYWJJZFX KYGQK MH MFTOJ YZXY HGQOJOT NCMGJGKSGHU. GPOJ LG UGM NGJ LYO TOSJUHLZGF.
diff --git a/2016/3b.ciphertext b/2016/3b.ciphertext
new file mode 100644 (file)
index 0000000..9e12e1d
--- /dev/null
@@ -0,0 +1 @@
+DFKAJ FDRSD NCXQU XKNRA BBAKW AGRJJ SDRXU NKARS DNCXQ NIANJ CNBBU FCGND SKWNK IABXA JFDGF JKVIN RMNKA XDKAI DJLFI CFJKF LXKJV FFRXR ANJKW AGIFY AUKPA PFIZA RFDLF IRSDN CXQPN JJXVD NBIAU FVDXK XFDXD NDFXJ SADOX IFDCA DKUXK NRABB AXJNC NYFIN ICJCN DMLNU KMIAI KWNKV FKBAL KEAWX DRXDK WARXV XKNBN VANDR JAACJ KFEAB FFZXD VKFEM SXKJP NSENU ZXDKF KWACN IZAKE SKNZX DVFOA IJCNB BAICF IADXC EBAUF CGAKX KFIJN LKAIP ABALK RSDNC XQPAP AIAEF KWNGG IFNUW ARESJ FCAFD AUBNX CXDVK FPFIZ LFIUX KNRAB BAJNS XDVKW ASPAI AXCGI AJJAR ESKWA PFIZP ARXRK WAIAN DRKWN KKWAS PFMBR EAXDK AIAJK ARXDR AOABF GXDVK WAUFR APAPI FKAXK FBRKW ACPWA IAKFV FXKWF MVWKC NIKXD PNJVF XDVKF RFKWA JNCAE MKKWA DWAKF BRCAW APNDK ARKFK NBZPX KWKWA CWAJN XRKWN KFMIU FRACX VWKEA FLXDK AIAJK KFGFP AILMB GAFGB ANDRX KWFMV WKWAP NJKIS XDVKF VAKCA KFYFX DWXCN DRPFI ZPXKW KWACD FPXKW XDZWA PNJKI SXDVK FPNID CANLK AICNI KXDRX JNGGA NIARX PNJNG GIFNU WARES JFCAF DAUBN XCXDV KFPFI ZLFIN VFOAI DCADK NVADU SZDFP DNJKW AGRJJ SDRXU NKAKW ASPFM BRDKK ABBCA PWNKK WASRX RFIPW SKWAS PAIAX DKAIA JKARE MKKWA SPNDK ARKFZ DFPPW AIACN IKXDW NRVFD AXWNO ANBCF JKLXD XJWAR KAJKX DVKWA BNKAJ KOAIJ XFDFL KWADA KXKXJ EAKKA IKWND NDSFL KWAGI AOXFM JOAIJ XFDJE SJAOA INBFI RAIJF LCNVD XKMRA NDRXW NOADK KMDAR XKSAK XKWXD ZXKWN JIANB GFKAD KXNBN DRXKW XDZKW NKRSD NCXQU XKNRA BBAND RKWAG RJJSD RXUNK AKWXD ZKWNK KFFXN CNLIN XRXKW XDZXD AARKF WXRAX RFDKZ DFPPW AIAKF IMD
diff --git a/2016/4a.ciphertext b/2016/4a.ciphertext
new file mode 100644 (file)
index 0000000..a6f1a54
--- /dev/null
@@ -0,0 +1 @@
+MWJJT WDEVM WJBXF XWCDG VBGKF JLGLM FHEKK TDEXV WLFAN LXLMX DZXMW PFAFR NDLGN DJWPF BQMTL MFTCX RMLAF XDLFJ FKLFE XDYWC FBXWW DECWJ LXDWK KMFLG BENKX DLMFM XEEFD CFKKW RFXKF DLBWK LQFFZ YWCFB XWMWE AFFDQ GJZXD RGDKX RDWBJ FVGRD XLXGD WLETD WCXSW LOXJK LXQWK HNUUB FEATL MXKWK XVGNB EDLKF FMGQX LJFBW LFELG QFWHG DXKFE RJWPX LTQWP FKANL LMFDX LGGZW BGGZW LMFJA GGZKM FBOWD EXLAF RWDLG CWZFK FDKFX LQWKO NBBGO AGGZK GDRFD FJWBJ FBWLX PXLTA BWVZM GBFKW DEDFN LJGDK LWJKY WCFBX WQWKD GLQGJ ZXDRG DRJWP XLTQW PFKAN LGDRJ WPXLW LXGDW BQWPF KXVWD KFFMG QLMFO XFBEW RFDLK QGNBE MWPFR GLVGD ONKFE XDLMF NKLMF TKGCF LXCFK NKFAG LMDWC FKOGJ LMFKW CFLMX DRANL LMFTJ FWBBT WJFEX OOFJF DLRJW PXLTQ WPFKW JFWKF XKCGB GRXVW BHMFD GCFDG DWKTG NWBJF WETOX RNJFE GNLRJ WPXLW LXGDW BQWPF KWJFF DLXJF BTEXO OFJFD LFXDK LFXDH JFEXV LFELM FCWMN DEJFE TFWJK WRGWD ELMFT QFJFE FLFVL FEATL MFBXR GLFWC BWKLT FWJLM FKXRD WBKWJ FRXPF DGOOA TLMXD RKBXZ FAXDW JTABW VZMGB FKTKL FCKWD EWJFX DVJFE XABTO WXDLL MFTFW KXBTR FLKQW CHFEA TBGVW BDGXK FXLQW KWDWC WUXDR OFWLE FLFVL XDRLM FCWDE YWCFB XWQWK HWJLG OLMWL LGWEE LGGNJ VGDON KXGDK MFQWK XDLMF LFWCJ FKHGD KXABF OGJEF KXRDX DRLMF KFWJV MWBRG JXLMC KWDEL MFDGX KFOXB LFJKN KFELG KHGLL MFKXR DWBGO WRWBW VLXVF PFDLW RWXDK LLMFD GXKFG OKFXK CGBGR XVWBW VLXPX LTKGK MFEXE ZDGQK GCFLM XDRWA GNLRJ WPXLT QWPFK LGGXK LXBBE GDLZD GQFSW VLBTM GQETD WCXSQ FJFNK XDRMF JFSHF JLXKF GJQMW LLMFH EKKTD EXVWL FWJFG JEGXO TGNVW DRFLW DTXDL FBGDL MWLXL CXRML MFBHR NXEFC TFDIN XJXFK LMFDG XKFKX WCMFW JXDRK NRRFK LLMWL HEKWJ FKFJX GNKBG LKGOV WKMBG LKGOX DOBNF DVFKG XKNRR FKLQF XDVJF WKFLM FKFVN JXLTO GJONL NJFCF KKWRF KQMFD TGNJF HBTLJ TNKXD RWEGN ABFFD VJTHL XGDJF PFJKX DRLMX DRKAF OGJFW HHBTX DRWZF TQGJE VXHMF JLGLM FCFKK WRFXQ XBBAF GNLGO VGDLW VLOGJ LMFJF KLGOL MFQFF ZXWCL WZXDR WVJWK MVGNJ KFXDD FNLJG DKLWJ ETDWC XVKXD LMFMG HFLMW LXVWD OXLXD AFLLF JQXLM LMFBG VWBKX MWPFW LFKLW LETDW CXSGD LMNJK EWTOG JWDXD LFJDK MXHXD LMFXJ HJGRJ WCCXD RKFVL XGDXO XVWDR FLWVV FKKLG LMFXJ DFLQG JZLMF DCWTA FQFVW DKLWJ LLGND JWPFB LMXKX DLMFC FWDLX CFXOG NDELM FWLLW VMFEC FCGKB XHOGB EFENH NDEFJ GDFBF RGOYW CFBXW KEFKZ WLOXJ KLXLM GNRML XLQWK YNKLW OXSOG JWQGA ABTEF KZANL XLLNJ DFEGN LLGAF WOWDL WKLXV HBWVF LGMXE FWKFV JFLXL JFCXD EFECF GOLMF HNJBG XDFEB FLLFJ QMXVM RXPFD LMFZF TQGJE XKHJG AWABT DGVGX DVXEF DVFXL BGGZK BXZFY WCFBX WWDEC WJLXD KMWJF EWBGP FGOGB EEFLF VLXPF KLGJX FKLJX DXLT
diff --git a/2016/4b.ciphertext b/2016/4b.ciphertext
new file mode 100644 (file)
index 0000000..7188233
--- /dev/null
@@ -0,0 +1 @@
+NRAT IMOS ONNG AAIU GNYO ISOE ETAW RDRG NFOI OLOK RALT EEMU OROL ELYT IWLL IONO NRFA TEST EHIL DAEL TMOC IRNO EFES HOMT GNWI IEME TYNU ITTP PORO HTIS EHOA VTIY AMKL WUCO VEEH IBTE LNID CANI MXAA DTYN AEHR ETDE OUNE LARE AHTW WIYN GLAZ PPZL ABUE SIAR EHTE RTYG BUOM SOLO VOEC LITL LSCA TIPE TIMA EMDI MCUH ISIW THGH TINE SOOM TELA DDOC ULTA HTIT ISCS YLAP HCAM TIEA MTHN HPDI ATUO NOSI ETNW THEH OHUG TVEE RNNI EILO DONE OEPL PIHN GTEV RYEI RNGO YEST HRAE TEOE PLPO BUTA ITON AOFR MNCU HIMT OSOG AHVE DOCU LYTW HEOO NWHK ODNT IREN STPE ATHE SETO EIRT SHCE AUIS TMEM DAKN ELDA IEDT AYNI GLZA SMAI DIED VPSR ODTA APDE TSTE THTH GTAR IDGE OORW TEAA SIWH TTNH AETU THBA MRTS LALY EBOE RTHM ASHR OITG GNAL ITLE RIUO RFOT RSSE ESAL LHTF AIEP DWMS EWAB UOLD CICE SNAE GEHL EPTH LALY EACN RENI KWHE TITA OTOL SIET IREB FONT CIOA FTOR ILFA GDEM ANIH GTTI HTER TCNE AELL IGEI TNTH REIG HSET TVHO ARTY EISK TSHE KTTA CATF HEOO SMET VEEN RLLY PACA TUDO CULT TMHA EYSS TAID NGLB FUIO NACE HAEL CRVA EAHK NWEI IDTH NLUL AFTE TYRI KSPN PMBA EHTE T
diff --git a/2016/5a.ciphertext b/2016/5a.ciphertext
new file mode 100644 (file)
index 0000000..1ae1c40
--- /dev/null
@@ -0,0 +1 @@
+SCFFP TJTGS CFRJZ XCVLG LYGLZ IJSLW CJLGJ XLGGC ELIFZ XXCFJ TYNSC JTGJS LJLXB HCYVT GTJCY LJNZF VZIBC FJJTX LGBTL GUCXL WTCTX BWTLR JSCJT JNCGS LFAZR TYEGV TWWGJ SCJRP YCXTO NLFLT YJLFL GJLRT YGZTH LECYJ ZNZYR LFTIU CXLWT CNCGN ZFVTY EZYCF LAFKT JXLYJ JZZWK GTYEG ZATCW XLRTC HKJJS CJGZK YRGCH TJZWR GASZZ WAZKW RGSLC YRXCF JTYSC MLHLL YRLML WZBTY ECGAF LLYTY ECWEZ FTJSX IZFCE LYJGJ FPTYE JZBTA VZKJJ SLXZG JFLWT CHWLZ YLGHP RCJCX TYTYE SZNNZ KWRJS CJSCM LITJJ LRNTJ SSLFF LCWLO BLFJT GLTYG TEYCW YZTGL CYCWP GTGGK FLWPJ SLRCJ CTGYJ JSCJY ZTGPT RTRSC MLGZX LWKAV NTJSH CAVEF ZKYRZ YJSLB RGGPY RTACJ LJSLP NLFLT YTJTC WWPGL JKBJZ RLCWN TJSCI KJKFL TYNST ASDKC YJKXJ FCYGX TGGTZ YXCVL GTJTX BZGGT HWLJZ AFCAV ATBSL FGKGT YERTE TJCWX LJSZR GBRGG JCYRG IZFBZ GJRTE TJCWG KFMLT WWCYA LCYRJ SLPNL FLCYC FXGWL YEJSA CHTYL JZIIT ALTYT JTCJT MLVLB JAZXB WLJLW PGLBC FCJLI FZXJS LZJSL FTYJL WWTEL YALCE LYATL GTJST YVJSL BWCYN CGJZJ CWRLY TCHTW TJPZY CWWGT RLGCY RTJNC GGJFK AJKFL RJZBF LMLYJ TYJLF CELYA PFTMC WFPJS LGPYR TACJL SCRBF TXLXT YTGJL FTCWG TEYZI IHKJC IJLFJ SCJJS LFLTG YZBCB LFJFC TWCYR JSLFL SCGHL LYYZY LNGZI CYPBF ZEFLG GTYGT RLFGJ STYVJ SLGPY RTACJ LNCGA WZGLR RZNYT YUCYK CFPCI JLFFK XZKFG ZIKYC KJSZF TGLRG KFMLT WWCYA LHKJE TMLYJ SCJHK WVAZW WLAJT ZYTYJ SLKVT GCKJS ZFTGL RTJTG SCFRJ ZTXCE TYLNS CJJSL PNLFL KBJZT VYZNJ SCJGL MLFCW ZIJSL BLZBW LNSZW CKYAS LRBRG WLIJJ SLATM TWGLF MTALT YILHF KCFPC YRJNZ YZNSC MLHZC FRBZG TJTZY GCJAT JCRLW WLJZJ SLHLG JZIXP VYZNW LRELY ZYLZI JSLGL YTZFG SCRRT FLAJA ZYJCA JNTJS UCXLW TCZFX CFJTY HKJTG KBBZG LTJTG BZGGT HWLJS CJATJ CRLWW LNCGU KGJJS LMLST AWLIZ FBRGJ ZVLLB CYLPL ZYJSL JNZZI JSLXT GJTWW RZYJV YZNNS PJSLP NLFLF LECFR LRCGG BLATC WJSZK ESXCP HLJFT YTJPS CGGZX LJSTY EIZFK GGSLG LYJJS LIZWW ZNTYE XLGGC ELSTR RLYTY CYTXC ELITW LTYTY GJCEF CXCGZ FJZIN TGSPZ KNLFL SLFLJ STYEG ZTCXE KLGGT YEJSC JGSLI LLWGJ SLYLL RJZHL ICTFW PRTGA FLJLG SLSCG CWGZT YAFLC GLRJS LGLAK FTJPW LMLWZ ISLFA ZXXGH KJKYI ZFJKY CJLWP RKLJZ CXTOK BNTJS SZKGL VLLBT YENLN LFLYJ CHWLJ ZGLJK BCGLA KFLAS CYYLW IZFVL PLOAS CYELH LIZFL JFTYT JPWLI JJZUZ TYJSL RPYCX TOJLC XIZFJ KYCJL WPGSL TGEZZ RCJTX BFZMT GTYEC YRGSL SCGJC VLYCW LCRIF ZXXCF JTYCY RKGLR CAZWK XYJFC YGBZG TJTZY ATBSL FJSCJ CWGZL OBWCT YGJSL GJLEC YZEFC BSPJF TYTJP VYZNG JSCJJ SLZBB ZGTJT ZYNTW WITYR TJFLC GZYCH WPGJF CTESJ IZFNC FRJZA FCAVT IJSLP GBZJT JCNZF RZINC FYTYE JFTYT JPGAT BSLFT GJZKE SLFJZ AFCAV JSCYX CFJTY GCYRT SCRJZ SKYJC WTJJW LHTJI ZFJSL AFTHH KJXCP HLPZK NTWWI TYRTJ XZFLL CGTWP VYZNT YECWW JSTGC JWLCG JGSLR TRYJF LGZFJ JZXCF JTYGF LMLFG TYEJF TAVGZ XCPHL NLGSZ KWRAZ YGTRL FZKFG LWMLG WKAVP TRZYJ NCYJJ ZBKGS ZKFWK AVJZZ ICFCY RTRZY JNCYJ JZLOB ZGLJF TYTJP JZXZF LFTGV JSCYY LALGG CFPNS LYPZK FLBWP TGKEE LGJNL IZWWZ NJFTY TJPGC RMTAL CYRKG LCMTE LYLFL ATBSL FCVLP NZFRZ IWLYE JSJSF LLGSZ KWRHL CRLDK CJLHL GJASC FWTL
diff --git a/2016/5b.ciphertext b/2016/5b.ciphertext
new file mode 100644 (file)
index 0000000..d37a460
--- /dev/null
@@ -0,0 +1 @@
+ANROH AESTM VEYES HAEKS TKCEH VRTEA EEHRK NLNND EBMSS OBOGN HAIOR GLASU SAFAU AIUAA ONAEG EEPTM DFLTE HESOE ARFME EOTAE LSAPA ATLIK ENHAI SETIZ AAEAH EOBOT TNTDR TLTFA SVNED SRNWT ASETO DLLNY DELOS ELLTP IKEHW LOOTC TTAEY ITSRR HANER MAIAS EDDAI ADEAI MBTLO RUAUA NUHNT MTTMO TGWUS LTSOF YASED UALSO ODESY SNUNA GDAPO DAEEI SLGEC KBUCR HUIEG OYIRI PEMNR DLTTN EPHEE FIASE MTAEO IILEE GATNR OEEIM YTCDN UETEH EROIE NNSIR YTTLE TUSTG GCMSU TCTAH EETIA IESDA HENSG VOERS NHSTI ORTDB HETSA EEBHE RTLEY NSGEE HEREH TOETH EDTTE EICEE STATT ELIFW OIEPB MEUEJ IDOHT TIAED VMHUS SDTSN OEIKA SCDTI LVCTC EASCV EDNNI EIOTU TLRTO SEDWA HOURE EITIA HEHAF CTBIT SYMNO TREOF DTELA ONUOA KMSCI DESHT STISE RSTSU BGELH XEIYH EUMIT NTHAL ACOYX ODIAT AEHLD AAMFL EOGSA NATRJ IAMVN IMGAT TRIAN ICNWH SBUIT YLCTE IEEDW BESOF HOESD AIOSC SFINO MUENT KETUF NOILF ASVNB ESSFT OSESV NAWOR IPOFH AEBHE TTLVD NOEBT BLUAK ECECF FADMS AONIE ACOER ODEHE EDNIH VHYNE PVAHO METTL AWICA ITWHE GEEHA OTATE EHLER EHILC HAGMR MVREE TIGYO ETFAR OEEIY OSIDT THADT OSOOU TIASI OHNUT SIRMA NRCRT RYRCI MIDDE EICUH CTDIW NDHNT LYAEB HUOPR WNOME EATTL EEAEK NNDOG USEAF IDETS ABAOK EANHH HVAND HSCGT HMTAD LTEIR OFAEE HHEFE MAOEA LLCOD AAEEH EIODT EMMAE MDPEH NSETW HAISN ILRIK BHAIF AOHOK NTSEI CNAAL POHHS NCREE EMTHD EYGTR FEIBO OHGSE COILT EHENT IKGGN SHTIS EITTR TIKAG CELNT RNREE AIRCO UNMSG EERHO VNRLN IKNNT SHNEM UIWSS WBOTI PIFEI TESEE OLETT THAAN CENOD IARLV ETNNR UTCOD TAAAS TBPEA ROTIA NAYAA MTEWN ITTHO PNLDR OTHEW OTNLJ ICOMN YMBIU YENIA WTHUN NREEO HLDFW GCTWE TATID OKOTT EEHUF IWFHR CSTEF TIISD AFIAR DAAEH AEEOO UDASU SNTSA RDHIY NMEOP RENRC EUCSF ONAHL BCTEE ECHEI ETTGE SHAEB HHOMT HETTC TTBMS HMRDA ALIDT MNIEO IAOST ELESH LBPNT OLNEM RIEBO TNIWO TRMHR PUUGW TCUTN ETTHG NIAVE HINII
diff --git a/2016/6a.ciphertext b/2016/6a.ciphertext
new file mode 100644 (file)
index 0000000..9173fe7
--- /dev/null
@@ -0,0 +1,2 @@
+
+PZAED IRAHN NESGU AVMNJ TVFHR OAFUA ZHEQG UGSTN ZAPCE EUOYD EPLII WIAGS YGWUA CUZEZ MSGZA IWTUG UTZTJ SSFSF RTUGL UEFEQ GUGLO OWAZS JBJEE JOELO NNOVV SHKPV UIBFF EGMGZ EBLHR JHNUK RJSUW HNVTB KPRFD NDOGG FGAMR GNYAN RSNQL HRFSN OEEWW NLCUA NTGNR GFGZE YSPGG PFZEJ SSHKI AYHNV BRWNP GMCJO ZASRV AAVAA SUGGM NLEQK CNFFY SGTWD GZEFL RRSMS GRNFA YQSVK WRZAI WATWN GKOAL HROAL LOVFT RJVVW WUAMN FDVSM UGPVF GGZIF OIYDG VNEHK EAGUT ZTBMN ESVRD TUASZ QSGWR LANGZ EZWAA LIZWI PSLYW DVFAS WWSSV BMRFO IGZTU WEGBE AWSGW NJZOS GLYGW RVMNJ TVFTB SLBUA YTAAC HRASP SREQI AYOHL AYDCN KHGJA AKAPL IBFSV FAAWF SGRGL OFLAL GFSYR VVWUA CUASN DIGLL RARBF IPYII WNGZE JSYJW FBMNQ ZIZZE VKTES VRDLV FGHFD RJTUW NNEEW SMRKA AVIJG NQWRR VISLH NLWNK AUANG LHNLH RKTVD LUSSS WEYAN TKFBJ JNEEY AAUWI FMSVF GNXAX WPNKS CGRGO HVUHJ SSTGO QWNBM GULOS GOYLH RTAAC AAVIN ELBGK VFGSG RJSRQ LORPA ZANVF GVLAF AAZFO GKUEW HBOHR OOHDD USVRG BGSIA WDBFE BXTUA SDMAY ATLGU GKIQW TUWTE SDROE USVRL IRVHV KNBJW RYINF TESNF SCGAO AKTBS NNUCB MNGAN FOIGR EEDAA VWUAC UAGHW SFASA GSHJP EASRO EUSDG ZEHKU NDDVX FVUUY LIRKG RLTVF GNUCR KSSJO ZLHRK WVKSN MTUGR VLIRK BHLTU ANTKA EWAYG TRSSV WRGZE EWTUS NGZEL MSRVT BTENF DJATU UOBHE ESTVG NSJOZ LHRXI FAGNA NRVAP UEFKT BSSGJ OAYBB PHRDD VFMNJ TVFSA WWASM RLHRW NPDOF WDYWT GWRSJ OZLHN LBBPP EGMVK EFLOF ZEQDI TZTBF HVKRB DEVFA YDTUA SOMTH FFBJT HFAGW LLATV KATSI AWNPJ YCLEQ SNQLH VKTVE EGZEP APUWR VKAOA TFLRB FGRJT USNGZ EBFEF OEUSV RTERF DRSLV FGJAT UACBM LQOAV LFBJT UWIAL EENIR OWVLH ZSRGA NOMTV ZAIWA SWEYA NTLHN LTUWI ALEEN IROWV DLTGB RLTRJ ISAKA GWZGR RANNV VNFCR KOVOI YDSCW NQSLV LTYWT VEENF AYQSV FGVLI ALHRZ OCWOS YEGLI AYAOJ ENCOA WTUAN TLHNL PHRZY WSZWT UWMNF ATWRN LTUWS JASFT AACMR FTVGN RVTUS TGZEY SSGLI ZWHRK AJEAE LIAAN CWRFG NUWWN KTESV RDLVF GJATU SYBMN TOOZS NNFDG ZEQWS PJICL IBFSB MNQWD NDOGD IXWJN EEYAA VVIQF TCACX MPBFT UASNL FVJSG TEPSU FWINK SHEEQ LHNLT UASJS SCJIB JTBZE EVENL HOMTJ ZEAAC UWCXW DGZEQ STRKI GVIQF TGAEH HTUWY FWEZL OUSVR TERFA GLHRT AACTB YEGZE ELHEW EQSYF SFGWR WSMRD INKDR STUEO EWLNL EEZAE JY
diff --git a/2016/6b.ciphertext b/2016/6b.ciphertext
new file mode 100644 (file)
index 0000000..297ddf4
--- /dev/null
@@ -0,0 +1 @@
+CRMMY MRPYA BQSPH LTPVR BTSOC GXYBJ DWLSL MYIVX HPGRM QKAFN CDNHR UBKPZ BTFLR LTBRX URSMY MEXJI OAECG FIARE ETCYA VWZGC AZTIJ VRLMU IKXIO ORRVH LSVRX NHIKA ZXITP NWEEE WADIY QRKRB AGVRV KIVBY IPFRS BRJBX NIYRF BJEIA ECRJI ASSIE ZGWJI YTMEL RZVEF PMQRV PKOWY WWHID QTMKT CAVNP PLZSW SIOMI EURPP EFWIZ TCBKU LRWZZ EATFM ETEEF PIJLZ VMYCE HZSGR RMBIO VZIEM KHMPP RLJIK NPWXR TCEIJ HWTPV WRGRL GFMJT IEBUI VQGLW VXRMZ OVBJM XIYTB RXURS MYMEX JIOAE CVFLT RGKBF NIAHK AVSGA XYXJI ABJJB XNIYW WKFMI YEIZV SMAWF KEEBJ SIDKO NVPKX ITPRR FBJEB UIGKZ NKVTC XEODR PWXRT CEIZL KHMQI MXCOX ZIEMF FIYEI ZVDIG ESTJE WSXVF GLIGI JHWTI EKVMJ IOAEC LKHIG ECEFW BUIDM FBMSM CMVRM QJIHD TPRRF BJEIA HZGKE ZCVVM VDQAV VTCTQ ZINXS ETVIM XKHQF EGIIO IPLTT EBMNH RIKEL GSRPZ DMIEI BVTGB JJBXN IYLRK MEAGM EZGRW OPVFJ BWGLN BKHQA EEWFU BFMUX KHMCL PLZCI YWTBV NKRWR LRNMK EDICE WSETH DMMEG ZTCAX CPZVR TQBRF YKHMG ITAEO TBKPP VHIII TTIRQ RHFNK AVNPP LZSWS EKHPM WQICP YIKUW LZXEA GWKAR TBUMJ TGPZB ETADA GOIJX ESQGM MXVNW HKYMF TZNGB BEDQI MUNRL NBSKY RLTNG IHJSI FLFIG IVTGV GKRMB VRBIP WEXTH ECWHV JXRNL GSTTI RGBYK ZRIBN RREPS QFYJB EGARM JFFMM GIILV MJRHU XUIVG LVULI TQMEZ WAJEM TMYIA JSLEU PZBZZ WVAVR ARGUL MFWFU KRCFM MXRLB RVETK IDRXF MYEKN QVKRS GFXVF JCCEV VGKLG VRLLV IBUEJ GFTMF GRIVD WHVRM KEVGM FGKHI GXYXK EUCPR MVBIA ORIGR WNGYL YOCYH JVRLM GSREC OEGVR VBIVT SWFLL BVTCX KAZTI KLRNL GSJXR RKUJF KGABG IIGJT PNXDT PSQTR RERNB VWFVZ ATBVG HKEVG MRECY MIIEM VRZBV ZLKBM UEMBF UZCEK MVRVF QFKVS XRGLE RTQII CRKHM YSEZS AARPZ GVTMP LEBHU MFAYB THIEI BXPTW GVZTE GCYEK BEGBU IJHLR KRSWZ IADVX RMZOV NPNTM EAPSL EUBMZ SUBWI MQXFI IODVH VTKEU CPRMV BIFIU GVTEB VBTEA TLWZL KOWYJ FKWIV QMEZC OVTVR GXEKB VIXCA BVSEL ZNVRX NHIKB EEWYZ CBUMJ TEATL WZLTO CYHJB XNIYE TMZVQ GCJIZ KMFED HEGBE EELEA BVSET CCZVQ ZGRLW EXVKI OZVWK ZIOCC WKKZG ORVZG XSCEZ VBCLI AGVTE DBNVX XKIVT IRKCY QAXVK MEVGM FGKOX EIMXE TKEMD X
diff --git a/2016/7a.ciphertext b/2016/7a.ciphertext
new file mode 100644 (file)
index 0000000..1a7c8d8
--- /dev/null
@@ -0,0 +1 @@
+ELUOP PAIJO NPAVX VHLDQ ZCDUY LZVJK WTDVL VGZZE LLWKU AYMLF KUSSK PLOJZ EXHPK LZYGH VLHZD MSMXX PEXFV UHPPP ARAXP YQHXF INPJF EEHZT BHQJI QYQAE ZNQZT SEJIP XWZXS BEPDL MDYMP EYEEF LOLUE JIYJI YXFCE DMYIL HTRVV VLMLP DHLQY SEGOA VHLEA YIVHF JTSYX YHZLY SFYWW MKELC NOVHB AGLYG KILUN TLUCK MOAMO XFYPH BLFFI TEKHV WNYTM OXXIP CCAGA JCLMS GSYGL PASFI OWTPX KYHOV HLLUP OZLLW ELQWA HWPTC BUSUL LXTHH OISOV HXKLP OVBXG HZOMD RAAYT AVPUM TEMUI ZNELP AIJUH LMISL SWPSP PQFSR QOAGH SEWII JUJPP AXSBE OVHSD MZCIL RJIYT OUMNC WSBVF WLLJM OXLUS EMCIA FPMMD WWCCL QKMKV FDAAM XIPYW YSWFW PLHXA WJMLL XUYEZ ZWKFC PMPAS TYCLL UEJYS EWUEW HZSBP AFITE IJMFO XXWJR AYCLG LLLYG PQSIT YHCIT PSXLT TLQSD DTMNE LIZQM OXFCY LUVAW BEEIO XVHLC WUCSL EYQAV SGDTB JIHMF DMOXL USEGA RAUEC MJVSY YSBPA WPPTT LFWQD YWPWM FNYWJ IUHLW TPINL FDVLZ WMCFW MCLHP HBYIV HFDQR RSVZW AVIZN OYIKI JIETV VQYHT PJLVS GCTND EDYSE UVVXX YLWAW DFLNT SEVYS NBHAQ FPDWS GYHTP JZMVH LVVHF WBEEI FKGFZ YPJIL LPECW QGWZE AZIUW LOMZM JISEC HRMHT POHKF YZEGJ EJCAD VVGXI DPOYE ZWRYQ KRWJW TIIRG XPDIL PWLDL EAGWJ DFALL LYWWM KELCN CMYYL WLQCU EEMXC ILLLL ZQARV GQSNQ OAELT QEHPS IEOMN RGFPM OUEJY SEIOX WFTMW TIZNO PEVLK YNLZA PDUNL TSEUY SEMRE EIEOM DSDFL YMLFV USPPS MLHFD VVMLM PFYLV GGJYI YIOMY LWAHW MFQMY XUYAD CZIZN EFJYI FCLEM YRGLP JEHPS YGLPV XWPTE KLPDI NRVPO UUSLN VVWVX PUHVG ZWLCZ YFODL EAMLU SEBBS VYEYQ VTWQC PGDED MTSTS EUIEO MKRSG POGSH WNLPX LVVHL OMAEL CRLGS LYCSP UHGWV ENMWW MMPSB ZMZNE FWIEV YVDIU IZQYZ QAEYC EDMCR ALPOV BHGCC PXLLL AYTZB HZWYL ZIIEU DPPAX SXPZM KMNHP ENVWS QYZQA TALND MKWJU XWIKK FCSNB HQFUX ZEHXS BEOMJ MLIYZ ASEWQ CPDLA GBHPQ CVWNY TBHHW VTCKZ IVYSD MPXAP TEKHI ZNSEQ DHWCW WIAIJ YSEAA MKCGD QOXSB EOMDS ZMDTA FPSHL CMOXJ OQOVH OFUMD QOXXI PRIAS GZJMJ VPWPP TZAIJ IEEVL WWLPH AARWA LSKUE JVZWA VRSHT XQOJG YRLBV SXXLS MDXSB EPDLM DYMZB KIEYP DMOKF CCZBP RGGYP MIHSB PHSUE TMDTE ZIZNX ZZMOF UMEVL VWZQT LFPWL TEVLR SNFZJ HKFCV WIAWS QENMW WMMPS BAEZN EYMYE HJLPU HGWVE TZLZW QZSOU MFITE ALYIL PSBYY XLPOV BINCE NMSPG WPSBF FFYVL BUIWV OLPUS ANNLZ LLLLF QWUSK XYFWM RWYMO IOWWM DPVRE WQZYB HLLXY LMZMU LPIMA EZYET PDEKU HEQKI ECLWK LLKCS ENVCL CWLOL PWBEE CVFSX PRVLP DUSNV LLOSE TZBGW MDVVH FWBEQ WAWWN YZQAE JNPYM WIUHL WMLVX UYZVV MLCOP XEIYH TSAPL HUQZB YEHML PDPXU YWWWJ IZNQZ NSEZY MYWKI LCDTD KEZYS EIOXV YXTIS GWBOY IRRSV LQWFF TIWPP ARAGT SNVIY UEZWM HSBPH BHLLX PWILZ WLPHZ LHJUS RVPLK OASBB SEIEO VHLYH TGQSI FIPXW ZVGZQ QWSPW QZZBL FGNOP ZHIHJ LPPAE ZNEFW KILHT ZXLAF YSHVL ZWYGC MZIJB DLKZM ZNAPS LLWLP SEUMS FAIMA SFXWF WDVGN ZYLSY GWPSA PLLHZ OMZWW LAYMO ALOME VBSUW LVVHF SYGLP VXLIY OVHWA MLMPZ EUUYZ GSIJC EYMRV GQZEL LQAUW NMOXK LTQBH WLHPX MNRSL CLTHM UHLYQ MWLWP AABWW BEZBK IFLFE MDOFU MDAPA KYSEP AMOJT SAUSA NLWMY WJIYJ IYXLO ZMIUA GHVJL HIJFL DIDXS BHWIL ZWLZE BVRWL LNOUM CUEEQ AYGVL VTHXG NOPZH TWLAE WUWSQ OYIKR ABPMB HLLFW LBMID XLSMO XSBEO MAELM ENMWW MMPSB KPABN LAHIJ YSEMT MLZZE VBSEU PWJHV WXTDV VGSNY PXZIZ NDPON YKMNT BZMJY ENIYE ZWPNQ VZLUS EBJEX YSEMA MHMPO TSELU VFMOX ZNTHA RRAFZ YLUYG ZDRVP KFIWP JZXUY ADCZI ZNQZP JVSYD LVVMK MPCXW SXIWZ WAEWL PHALW SVLEI KEFXE LPAKF CELBZ WAMJW IUEJI QPTWQ SMLYL HIVCG ZZWSL MEDMB UWLOP ABJWL PSVPX JUXPJ VXKYX LRKIL WPAAB WWQEL PAPSY GPZAS FXTOM DXMVC ZVFEJ NYTBY EEZZO VHXUY ADCZI ZNQZA JMJNP XWPFW BEYML ALYMY WPXSF PCZVG XIPPZ NIVBR TPHHW QZSAZ MKSWL VHWWC ETZVL LOLJB PWJYG TVBIZ NSEQD XMIOP SJIZW JCWAW KCSWM AEZWF PVUMW WYPQJ WJYEF XTSUH TPUTE JAZCX LXSOO LZNEE ICQBB SHICO ILFGN OPUPE DWOYI UMLLL XALQS DQZMT EFYSE VPWLH PXCJS VSETB UIVCJ EQSEM KSRQO KFCJC ZHGKU HEKLT KODPP AWAHX ZZMWH YCOVH EKHTX MJRSX YPBAE FCCZV FEJNY TBYEE BETED IAPCP BUMEI CQALX GH
diff --git a/2016/7b.ciphertext b/2016/7b.ciphertext
new file mode 100644 (file)
index 0000000..d097a1f
--- /dev/null
@@ -0,0 +1 @@
+HTPEG WEEHW AOHCP NIRXE IEXZG OGDQK UEGBY KHWAO CDOTQ OTSLY OELDU MOSEQ OQYTP RNNIG ABADV QIAXV OODEE GWSSF QRGGS YEGWS SEQSX BTKBR FTGBY KBKEU QNETC KSOQB FOTSY QEOSU RBCTE KYORM TPLRA TTKMO BKEUO KCNDZ MROTR NCOYW QKPSH VTCVN FTQET CALWA VVFUK BSKFH RASAQ VFCRS GBTTT QWNEV YFRHE AQCHS QQTNN DPBTC PZEGR EAKKO HURRO CXNQG KNCQS TBSNQ BMTZO OSEBO RXKDE HEHRO YKEOB BFIKQ TTCIZ CCORU IHGYT IMBAH OAWOO ZSOQR OCDSS OQDGE YMKLO AQKXO BKPSF HSVLK WTEHN ATKTO UKNSI OCYDL TQGIT NUOCR KCEPO SRQCQ QCQSR HLWNO SKENN BTFLO LENAW BOCYT NETRN OWDEK SOQIP DWHEA WLOVV YFSCD OTLIN SOSYQ OPYNH TOCON RPTHN AWCOO DYTCO RETHL ULAEQ RPBNZ CSEHC ISDNR TNDTS PSQFC RBNPS YSRBE UELKE QTEYQ QLZLY KSOBD KNTGT WBURR BLQAK BSCVL IIUVT FQBPA KGSTC LSFSC KSKSO BAORE BQEVC BHQBL SVIQO ULKOT HQNFO IOSAH RATKT OXQUE HRYNB KPSKQ OFNWS EUOCX SOQYO VEFSC NREQS PUOED LFWKF ORUIN GTKGO ASDQS GEYMK QOPIO DEVSF NCERS QUPES OQYWB EKBQK PIADC OIUGN CTOII VOQBT ZCPEN BHZKA GOYCQ PCDET MIWFE BGEUE ORYCG SYEKM OQIPD AOCUI NGTHW AOQVT ETVCU BTOYS OQYBQ YBGLT NKVTF VQTFH STQES RQDEU MUKNS IOCYF ERRBL SRHQS THKPE TRPEW BEOSB QKQMP ZBRUE BLHTH HCSBD ACIGC YRENT HRAUQ NENKT ONOTW THUIK HIOOS GQEGO HXIRW TEINS QYFFQ NKTLT RSCNE TRGEY DANRL HFPTK TOFDQ TSOQR AGFTL HVNTS NYIIV OQETS BKFYO SEPQI VLTOY EHMIR WHEAW GOTBO QXRHR AKBRR GTXPR SEHFL RBIFL QOODE GAENO OUXWL ELSEH THMIR UDKQA DVTIH ROICC QTOYE HMIRI HWOIB CRQLP LWHEA WXOBO FYQEV RTRGX QLBQN TBYYR EBTRT TEENR MSDHQ OQXTC LOIFE QTHUA TOOUW BNTSI BDUKH SNQVR ARCTH VRSEC QSNSO QYSFH RGUTR OUREI OVUQP UTTLA VNVMT SLXDN HOAWB OEPGQ ECKEO THEAU OTUVL CLBPE QGCEE KQNTB GEUEO RYEBT QGELR SOQYV TTYHM IRVTT XHQOV FOKRK QFENK NOBLE LCQRR WGOEO LSOGE YNHUA TOVUF NHTZX DSTUL QFSCQ QGHYC NVSCU EURLK ASLOD TSBQR MRPET LMENH TASGS TFOTD HQTUN IWQIP OKOME GGFTT GOEXV TCMBM ARGEY NKFOS KTYEO BDUKB SEMCT RQVRI UITZB RYDCF SOSCQ RLIQO EAEBB SRQGP ECDAQ VBDUB GCYEQ ETSBK FYGEY NOUTE QTTNG SUQDK SYSGB ZUFKR LOBGT VWIWS OQOKD YSGBZ UCKRG EYIGO ENKKO MANE
\ No newline at end of file
diff --git a/2016/8a.ciphertext b/2016/8a.ciphertext
new file mode 100644 (file)
index 0000000..158e05c
--- /dev/null
@@ -0,0 +1 @@
+SVGFL BCSLU JGEXA LYOHA EXMOG RMXSO MACSM MHPCI OQEAO WJOUY EODDP LULLZ HASAX PZJSF LDOQK QJDBZ YHGGG CHVFX TFXPN MKCVH EAQJU LHAWB TFXPV XRDSR AZANV HYMXP PSMUJ OEXAL EKPLX PHAWB XZVUQ ZJJJB LZDFK SHAHA YGGVI XFPCF VDGFP LNNLU LVMUL BUIIX SBGNE XWBIX BPRCS BIOAL MIZXX ZVUJG CSLBC IPCYC HAOGH LZTJO OBKPC SRIDR WBDBS VAZDF SIMUJ OHAWB KPSOG VIXAZ PIMAG CLGEX WQLUL VMULB OQXZN MBMQH OCZCM JNHHA WAFXF JSRAD IFDRG ULUUG WBSBX DHLRC IFFXG ATAHA MWEAV XNDEX GKFJX PJNDR JODRA HCGAZ LVMUL BOQBZ WBTAD RVXYI WQYNC SLGDE CSZCX ZLZDJ GRIXB ZWBRH OQVXW UNMAZ OQACU GCRYT DRCAY KXYHR MZIOK QNCIX EXHAO CXDYV YIMEL UEXHA OCXDY VPLMU SNAPQ VMKFJ RIKUC WHBPF JTCHW BHAMW JDOBA ZLZVX KRSAO CSRXZ LZDJQ IDRYI EOXGU GEKJI KLCSV UCWTF GGUDD SMJCW EQJBY KREAD DRPFL UALGC BZALK RQZCS IAIXR BTEIX LZHRW QRSCS JNDRB DDRYI JOAZL ZXZDH JBNDC FSINS CWCIP IMAHA YGGVI XFPCF ZCDRG ULUUG WBWAI XIXMJ YOJBU LEOQR UOIAJ ODREX JTPSW BMINN LBJOM JLBWG DJSOM AKOZX NFLZO WVKUC GNACB COCJI ANUOR BLGDR ONGNV LULWA YKXYN DYITX JJJBR BPFUN IODBL ULZMA ANKYQ ESRMI BDGGU DZGMX KDIKN NYWAZ SNHAM WVXMG QIJTV HCIGF SVULU OAPWA OQIBV NAGKR JVBZY HALJJ PTHAW BFLNN SMLYC SLBCI BZGFJ VULCH WBHAY TUULA WBCSR SXDQW NVYKX YDFRB ZWGFW GMMKR CFYTG GRLAN KRAUS AANRI DRSJC SLBCI RIXZX WSCMJ EKXZR IDRDB FJJOA NNJGF PLJOD RSCTV PLULL ZGCYY ALGGR LOQOQ GCJIW UWLAN IFDRQ DYHVL HAEXM PEPIO KDYOZ KQIPL JBEXA LLXXJ DRDJA LYHMJ FJDRG FBMCO YKDVH AWBHA MWEAV XGGRL EXYMB DMAYT JJJBT VMPDR SJCSL BCIRI XZZCJ JMMYK XYNDH AKDVX CGHAX DGATA DRMRI KBZRI DRKPG CKGQH OCZKQ IVDCF PLDJU LXPJO MINNH CWBNS QVKCX YEAQJ ULZJH AVXWB CFAZL ZNDWU MUCJE OFJJT ULHAS OUPIX HLZCF JVNMJ VHLUH AMWEA VXCIG FSVEX ERADE OMUHA EXQBW ALZVX DHDBL BCIHA SOMAB JXRWB VNDVP LHAEX OHDRI SCFWW TFJVS MACLU IXSRC WPPXZ BIMRS CGDEA VXGGR LEXYM JODRW UBQYC MIVYY TEACF WTMXA LGMMX QIANR VPFDH DBPLU LKRYI XPGHA ZOPIX UCTFL ZOQAC MUHAW BFLNN SMZBI XGRKH EXMPO GCSJH ZXZHC ISASM OWKXQ HALCN IXXZP ZDHAA VXEON NDJIK XGSOL MGNHA SAYIW DOPIX ILYKD BEAQJ ULIBG CKGBZ SRTRK XMINN QLSCM JEKCI VCIOU UCGQI YNCSB PSCVL RRQRC SXJXZ TKGIJ OHASB IOBIA YALKR ACBCO CJIAN UOGUL UUGWB YGQZE XZVLO AZHAM WEAVX EXALE KJIAU YTAVL ZHOSB GFQVA DWBWM WADRL UAYAL KRACB COCJI ANUOS AVLHP JBIXQ VPVKX QHCSM GANHN CDSOX MEPQM KCCIZ KKPUL MUJOE XCHUG TADRW UJOCF LZZZM AKOZX OWPLU LIACI DJZJX KAZEO CISIV XJVHA WBVLK RYMBP HAWYA NUBQW EQXJA LFXGN NDJGK EEXCY RRHOQ ICFUO HAMWE AVXYY SBEXQ OYNIO IKSWU LKRVS DREOF EYIVX BZXPH PTLCF ZCCSU SWBGF USGCR ZJDKX QRIXW QLUXZ XNSBX WSCMJ EKANN JGFPL RZLUI XCJCI BCWBM IHVDR HVADE QJBRB NMMRS CGDHA MWEAV XUOLG MKXEK YWWQC LZVXK RSAYT DRJHJ TJOEK HPFED RIAQB KRVLS ACSNN JVIAS RSOXM CEQES RDRBJ KPXZT OOPMJ KHAZR BLTPF DHDBP LULKR YIXPB ZJTKX MINNR RMASB GIJOH AYKUN EOMUU LIXCS LBCIR IDRNP LUSCC FDBNU ZRKSR ZIAJB WBUUL AWBKD OQAZQ JHOUY SVCHU GJJNN NDZCI XGGZW PPYKX YXZXP FJRIQ ZDRCF DFFED RHOOT SOHNB QADHN NNJTJ VEOMU OPOBW GZXYC WBHAQ IMRHR OWJTW QYIEO DDPLU LANRV QHCFH AKQTI MIYCL BSMRR ULYMX PPSMU JOQWP LULEX HASAM ZDRVX HAMWB ZAGBZ RIEPO PIXWO SBBPR XJTCI KXADE XZVLO UUCFZ PQHCF HAOCT EKZWG DIADV XFJRX DJSOA LYHMJ FJEAV XANCJ DHYKS RGFWG DBLUE AVXNQ YKUNP LJOQZ DRNTK XQRGE BQADH NNNJT JVRBL GDRGU LUUGW BQIMA KQTFW BAGDB BZJIK DZRPW AZLZO QCFMI FBQHO BCIBC ANDBL UHAWA FXFJK HIXWB MIHVO QJTHH EXWBA ZHAWN KZMIX DHBPF PLXPQ YIXAZ SAHBD VAZSC ULYMH AIXBZ BJLGM UJOEB GNHAU UUVAD LAKEI XQYIX IXYTK PAZEA VLAOV LUJXZ ZCDRV XGCEX EOFED RGULU UGWBS OULPL RZAZL ZKHIX WBWAA LNVAL YHMJF JANTO MRSCG DNPLU EXQOY MXPPS MUJOB ZBJLG MUJOV LHPJB IXYSO QHAXD YVRPG CLGEX MMKRV SQZDR FIULM JEXYY RIKUA LYHMJ FJZTB PJBHA OCJOI XDHWA ZRSRE AEYAN JKADS CMACF ZCFXG ATAHA WBDRY IQYAD EQJBK SHAHA UULXL ZZZYK DVGRW AOQVL TKFXZ XJBAG DBBZJ IOCDL YTPFQ CHASB FXTFE AKSJI VNLUL VMULB UIALX MADCS FWQIY KFBQI IBHAO CXDYV APCSL UGCLG EXCIU USRYX MXSBZ RSWRI DRRCQ WWFWB WQZCD RKPOG JBSCY TCGEX KWXZZ CDRMR IKVHS RDRCN VXBJV XRISF YKRCS OXDKG HAUUU CCOAY TAOQM OHDAP OCWDQ ZGCEQ JBOAV XIBAN QVRBL GLZJJ BZPIM AHAQI MRHRO WJTAN HRRRK RLBQI LXZCX ZPLSR DRNDE MNFIB HAWAK EHAMW XZXPH ASACI HNTLG FPLBD PLMUK SHAHA SOEPF JKXQH GROQN DCFMZ CFRRI KHRJB WUNTQ IIBHA QVOBK QJOAQ XPZJC IBCIX DRWUU DJKEX HRJDX RHAEX UNQJH BTFRI QZDRG POGAL GGUDD SOCWL IOIAR CQVAD HAQIM RHROW JTFLN NSMNR FBALY HMJFJ LZACR SVXKG HAOCB QADGC PLULA LGGUD JKHPS FHAWA KDHAO CPFRS GFCFT XGFMJ QIWDQ IQYCS YYDJZ JXKMI NNLUJ HADJV JJTOC FDFSI MUJOO SGFPL BDQJH BGFAN UOULH LPTAC BCOCJ IANUO OWMUP FWQLU JJINS AMVOB ALUCJ ODREA BTIXC SJIBJ LGIBO QSVUU YTAQB DQRYT DREMH AADAL KCSEQ ZACMZ UGMIY COQAD LZVNB DQRAN UOJHL BYAAL RBFBA ZHAQI MRHRO WJTLZ HOQZS OZCDR KBCFU OHAGR AYVTK MLBNF JGMXM JDFSI MUJOS RQMYT VXKRH OQZSO PLULL VMULB EZYHL ZGCYY ACVXH AOCDV LZZJW UUDVU LMQIM GOQDR JXQZD RQDYH LZLXI FWMQI DRANN JGFPL NNWTI KRIOG ADMOA LTADR GULUU GWBCS LULZW UBDNT VXEXL VMULB OQJDY YTOCS HAANH RHAEX OHDRC AULDH DJAZH AQIMR HROWJ TLZFJ VDGFP LHIGI JODRX ZQCIX WUJIS OPLXP RPHOQ ICFPL JBALO QWOCW LDGVI XRBNM WBQWE PFJKX MINNL TWWJB HAWBH AMWTF AZAZL ZCIZC DRHLC ILBTF RBLGD RNDXZ DHYKP FVSUU LAWBQ ILXDO OGHAK DAYMG QIPLU LDFEA YMFVR CUGSN EADFA LKSJI ZRDJY TDRPJ OBANP PGRMX CSVXK RSVAN UOIBN QEXCY JBDFY VHAQI MRHRO WJTAN HRRRW UJIIL ADWBA DIABD OPIXK RGCTT PFHHO SANYP QWHNV XDVEA SMUND BNHCJ CSRCY TQZPF UOHAY TUULA WBYTG FWGRR ULHAK QHAIX XZLUS NEADF HAWBE AKREO BPYWE QJIEX KJSCM JEKAN NJGFP LVLDJ YTDRS RADYO MZSXL BKXDR VXSAV LVXOQ ULRBL GDRZQ KGMRH ROWJT LZYYS BHAUU KRQHC SLUOP IXSJC SEOJO IOOBC FUOKS DOQIC IIADF JOSTO GCHWB UCGNJ JPTLX PLHAE XMOCF IKRIS FCSTZ ALTAJ JEOXG LBTFH AKQXY JDAPM ITFPP KE
diff --git a/2016/8b.ciphertext b/2016/8b.ciphertext
new file mode 100644 (file)
index 0000000..7e2d938
--- /dev/null
@@ -0,0 +1 @@
+10200 20020 12002 11120 00210 02010 21012 10021 10201 12011 20002 00101 11210 10011 21100 01121 10000 02000 00012 01112 00012 00012 01012 11002 01012 00012 00112 01102 11002 12020 20202 01121 10210 12000 20012 00200 20121 12102 00102 00102 01002 01002 00002 11111 21110 12010 01200 00020 10002 01110 02000 00021 01110 20000 10200 00002 01110 20100 02000 11200 01121 10002 11121 01210 02010 20012 01200 20121 02112 01020 00200 12011 21102 01102 10102 00102 11102 00012 01110 11200 10010 20010 00120 00000 02001 01002 11000 11111 10210 11000 01100 21010 10110 11121 01010 00001 12010 10000 00002 11101 11002 10100 01002 11100 10012 10000 10012 01000 00102 10200 20020 12002 12020 20202 10211 20120 02002 10111 21000 02100 11210 00020 10002 11100 21001 02010 01200 00120 00102 01012 00012 00112 01102 11002 11120 00210 02010 21012 01121 10210 12000 20012 00200 20121 12102 01210 21120 02012 11112 01002 01112 10002 00012 11002 00102 00012 11112 10002 10200 20020 12002 01012 00002 00112 01102 11012 11002 01102 00012 10012 10102 01110 02000 00021 01110 20000 10200 00002 00210 21120 12002 01012 00012 00112 01102 11002 01112 00012 00012 01012 11002 10000 02000 00121 10011 20100 11200 11002 11112 10002 00112 00002 10002 11002 01102 00012 10012 10102 00012 00012 01112 11102 10002 01100 10100 02001 01000 00020 01010 00010 20010 10100 10200 01001 11002 11201 20120 02002 11011 01000 02010 10101 00020 11111 10010 20010 11010 10210 00001 01002 01002 00112 00112 11102 00002 01200 20020 12102 11121 00201 12000 20002 01020 00200 12011 21102 11111 12100 01021 01001 21110 00200 00002 00011 21000 12110 00201 00020 00002 11001 21000 12100 11210 01120 01002 11021 10201 02000 20002 11121 00201 12000 20002 01020 00200 12011 21102 10112 10112 11012 01012 00102 11011 10121 10100 01201 11101 12001 01011 20100 00002 11201 20120 02002 01020 00200 12011 21102 11010 21010 02001 10201 10021 00002 01010 20000 12001 01201 10121 10002 11002 11102 10112 00012 00002 11112 10002 00112 00002 10002 00200 20121 12102 01111 20101 12110 01200 10020 00102 01200 20020 12102 00001 11020 10100 10210 11101 12101 10101 20100 10002 11021 10201 02000 20002 01020 00200 12011 21102 10101 21001 02100 11210 11020 10012 10200 20021 12002 11102 10102 00002 01002 11012 01012 00002 00112 01102 11012 00100 20100 02010 10201 01021 00002 01200 20020 12102 01200 20020 12002 11112 10002 00112 00002 10002 00200 20121 12102 10101 11020 01000 10201 00101 12110 00001 21000 00002 10112 10112 11012 01012 00102 10200 20020 12002 11021 00210 02010 20012 01012 00012 00112 01102 11002 01210 21120 02012 11002 00102 00012 11112 10002 11201 20120 12002 01102 00102 00002 01002 11012 11120 00210 02010 21012 11112 10002 00112 00002 10002 00002 00012 11102 01112 00002 01112 00012 00012 01012 11002 11100 21000 02000 10210 01020 10012 01020 01200 12111 20002 11121 01210 02010 20012 01020 01200 12111 20002 11102 00012 10012 01012 10102 11002 11002 10112 10012 00002 11211 20120 12002 10112 10002 01112 01002 10002 11211 20120 12002 01020 01200 12111 20002 01102 10102 10112 00012 00002 01210 21120 02012 11002 11102 10112 00012 00002 11201 20120 12002 01001 11211 10001 20011 10020 00100 02000 00002 01101 02010 11120 01101 20000 01200 00002 11021 10201 02000 20002 12020 20202 10211 20120 02002 01001 12111 00020 01011 21010 00200 01012 00101 11101 02101 10110 00021 11001 10011 21111 10101 01200 00000 01002 01020 01200 12111 20002 01112 00012 00012 01012 11002 00112 10112 11112 01112 00002 01112 00012 00012 01012 11002 10000 02000 00121 10011 20100 11200 11002 11201 20120 12002 01210 21120 02012 10000 00210 00110 20001 10020 00101 02011 00012 01200 20020 12102 00011 11200 10101 21101 00121 01000 02010 00002 01210 21120 02012 01102 10002 10112 11012 00002 11201 20120 02002 11102 10102 00002 01002 11012 11000 10020 11101 00200 00111 02101 11010 21000 00002 11201 20120 02002 01020 00200 12011 21102 11002 00102 00012 11112 10002 01102 00102 00002 01002 11012 11011 11210 00011 21000 01120 10100 02001 10012 11002 00002 10112 00012 00002 10200 20020 02012 11112 10002 00112 00002 10002 00002 01012 10112 10112 01002 11000 12011 10120 00011 21011 10210 00002 11111 21110 12010 01200 00020 10002 01020 00200 12011 21102 11101 11002 10100 01002 11100 10012 10000 10012 01000 00102 11121 11200 12001 21002 12120 20202 11000 10010 21010 11101 02100 11111 10201 01100 10021 01000 00012 11101 10100 20100 01001 02010 00000 01200 00000 00120 00100 10102 01200 20020 12102 00001 00211 01110 20110 01121 11101 12000 00002 01020 01200 12111 20002 12120 20202 11010 21010 02001 10201 10021 00002 11201 20120 02002 11111 21000 02000 10201 01121 10012 01101 00111 20101 01000 12111 11000 01210 11010 01020 00010 10002 11112 10002 00112 00002 10002 00200 20121 12102 11210 21021 12002 10110 02100 01021 11011 21110 11200 01002 01102 00102 00002 01002 11012 11210 21020 12002 11020 10201 12101 20002 11120 11210 12100 20002 10110 20110 02110 11211 01020 00002 10200 20020 02012 01102 00102 00002 01002 11012 11010 21010 02001 10201 10021 00002 11201 20120 12002 11011 02101 01020 11010 20001 10200 00012 10002 00102 01112 11112 10002 11021 10201 02000 20002 01020 00200 12011 21102 11110 10210 11001 20001 00121 00000 02010 01102 00111 11111 20000 10001 02011 01010 11201 11010 10021 00100 00112 00011 10111 21010 00000 12110 01000 01211 01000 01020 01001 10002 11201 20120 12002 11001 12000 00021 01111 20001 00200 00012 01200 20020 12102 11002 10102 10012 00012 10102 01001 20010 02001 00210 10121 00112 01200 20020 12102 10200 20020 02012 11112 10012 10012 11102 00002 10200 20020 12002 11011 11210 00011 21000 01120 10100 02001 10012 11111 01200 11101 21001 11121 10001 12010 01002 00101 11211 01100 20100 01121 10001 02000 10012 11112 10002 00112 00002 10002 00200 20121 12102 10111 10021 01000 00200 10100 12011 10001 20100 01102 11021 10201 02000 20002 11210 21021 12002 11112 10002 00112 00002 10002 10100 11210 01000 21111 11121 11111 02000 00012 11120 01200 02110 21012 11120 00210 02010 21012 00012 00002 01112 11102 00002 10110 21000 02000 00201 10020 10112 01102 00102 00002 01002 11012 00001 01200 10101 20101 10120 11100 12000 00002 12120 20202 11020 00210 02010 20012 11201 20121 02002 11121 00200 02011 21102 11120 00210 02010 21012 10021 10201 12011 20002 11021 10201 02000 20002 11121 00200 02011 21102 11120 00210 02010 21012 01110 20001 02000 11201 00021 10002 11120 11200 12101 21002 01102 10102 10102 01102 00012 01200 20020 12102 11112 11012 10012 00002 10002 12020 20202 11121 11200 12001 21002 10100 11210 00110 21100 10120 10010 02001 10002 01020 00200 02100 21112 11012 10012 00112 01102 11002 01210 21120 02012 00101 02010 01020 10110 21101 00200 00002 01001 12111 00121 01001 20010 00200 01002 11110 10002 10110 10002 10111 10102 10001 10102 01110 01002 01102 00102 00002 01002 11012 10210 20120 12102 11110 20000 02100 10211 00020 01002 10100 21011 02000 00200 01020 00012 11002 10102 10112 11012 00002 10200 20021 12002 01020 00200 12011 21102 00111 11111 20000 10001 02011 01010 11201 11010 10021 00100 00112 10210 20120 12102 00001 10002 00100 01002 01011 00102 01010 11102 00100 00002 01020 01200 12111 20002 01020 00200 12011 21102 11112 00102 10102 00012 00102 00100 10211 01000 20100 11021 11011 02000 00012 12020 20202 11121 11200 12001 21002 00110 00200 00000 21110 01021 01001 02010 01002 10210 20020 02012 01020 00200 12011 21102 01111 01110 10121 01100 00000 01200 11000 10001 12111 10100 00011 20000 01000 10002 11020 01200 12101 20102 01112 10112 01012 10002 00002 11121 11200 12001 21002 01200 20020 12102 01110 20000 02000 10210 00021 10002 00110 11101 12000 11000 11020 10000 00101 21110 00101 00210 10100 10002 00001 10020 01101 00201 10100 12010 10001 21000 00102 01100 01200 00011 20010 11121 00011 12000 10002 01200 20020 12102 00110 20110 02010 11201 01021 00002 10110 21100 12110 00201 10121 00102 11010 10101 21000 10000 12010 00000 11201 00000 01120 01010 10002 11201 20121 02002 01020 00200 12011 21102 10021 00201 02011 21012 10111 11111 20101 01100 02010 10101 11211 00000 00020 00100 00012 10210 20120 12102 11000 20010 02000 10211 11021 00002 01200 20020 12102 01001 21000 02100 11201 01020 00002 01020 00200 12011 21102 10001 02111 01021 01100 21111 00200 00002 10200 20021 12002 10011 20001 12001 01200 10120 00002 01001 12111 00121 01001 20010 00200 01002 11121 11200 12001 21002 11000 01000 20100 10100 02010 11110 10200 01111 01020 01000 01002 11201 20120 02002 01020 00200 12011 21102 01000 01112 11100 00112 10111 00112 00101 00002 00000 10012 11110 21110 02011 11200 00120 01002 11021 10201 02000 20002 11121 11210 02100 20012 10200 20020 02012 11211 20120 12002 12120 20202 11121 10200 12000 21012 10200 20021 12002 10111 11210 00011 21111 01121 10000 02000 00012 00101 10121 10000 01201 00010 12111 00101 20000 10102 01200 20121 02112 11000 10110 11120 10011 01100 11201 01110 01001 12000 11100 00000 21000 00100 00012 11120 01200 02110 21012 00001 21010 12111 11201 01120 00002 00101 11002 11011 11002 01000 10012 11110 00012 00000 10102 12020 20202 11121 11200 12001 21002 01002 10102 10112 01112 00002 11000 01000 20100 10100 02010 11110 10200 01111 01020 01000 01002 11201 20120 02002 11000 10110 11120 10011 01100 11201 01110 01001 12000 11100 00000 21000 00100 00012 11120 01200 02110 21012 01110 11112 10000 00102 00100 01012 11000 01002 00001 00002 10011 20001 12001 01200 10120 00002 10001 02111 01021 01100 21111 00200 00002 01011 11200 10010 20010 01020 11100 12110 01112 12120 20202 01011 10111 21010 01000 12000 01000 01211 10000 01020 00100 10002 10200 20020 02012 11121 11200 12001 21002 12120 20202 01111 11210 00001 21011 00120 00001 02000 00002 01101 21000 12101 11200 01120 00002 00102 01012 01012 11102 00002 11020 01200 12101 20102 00112 10102 11012 11002 00002 10011 21101 12011 01201 10120 00002 10200 20021 12002 00000 01102 00101 00102 11011 00112 10111 00112 01000 10002 11021 10201 02000 20002 12020 20202 11111 02100 00021 00010 21110 00201 01002 11002 01102 00012 10012 10102 00111 10021 01001 00211 01011 02110 00110 20000 00002 01020 00200 12011 21102 01110 01201 11011 20011 11120 00011 12000 10002 01112 10002 10102 00112 01012 01011 00201 10001 21011 01121 01001 12000 00002 01020 00200 12011 21102 11021 11200 12001 21002 11001 21110 12101 11200 01121 00002 00010 00010 20011 10101 02010 01011 10201 10100 10020 00001 00012 10210 20020 02012 01110 10200 11100 20110 10120 00000 02010 00012 11121 11210 02100 20012 01020 00200 12011 21102 01001 01112 10001 00102 00011 00012 11010 00002 00100 10002 01020 01200 12111 20002 01112 00012 00012 01012 11002 01112 00002 00012 01102 10002 01200 20020 12102 00200 20121 12102 11002 01002 01102 01102 10002 11211 20120 12002 12120 20202 01010 12010 10020 01101 20010 00211 00112 01010 20011 02001 10210 11020 00012 10101 01200 10010 21110 01121 10001 02000 11012 00011 11210 11001 20111 00120 11101 02100 00002 10200 20021 12002 11111 02101 01021 01010 21000 00200 10012 11111 11121 00010 11201 10001 12000 10000 20000 10012 11001 11101 10201 00000 10100 20101 11011 11120 00100 00101 12001 00001 00002 11011 10121 10100 01201 11101 12001 01011 20100 00002 11021 10201 02000 20002 11000 10010 12101 01110 10121 00111 11101 20101 10010 01210 10000 00102 01200 20020 12102 00110 20110 02010 11201 01021 00002 10111 21110 02110 11210 00020 00002 10110 21100 12110 00201 10121 00102 11010 10101 21000 10000 12010 00000 11201 00000 01120 01010 10002 01200 20121 02112 01011 11121 10000 11210 01001 12000 11000 20010 10012 11111 02010 01020 11011 21000 01200 00002 00110 11102 00011 00012 01000 00012 11100 01012 10101 00102 01200 20020 12102 01111 20101 12110 01200 10020 00102 00001 10012 00110 10012 01101 00112 01010 00112 10000 01002 10111 21110 02110 11210 00020 00002 10110 12110 01121 10001 20110 11210 01002 11111 01112 01000 00112 01110 00112 00100 00002 00001 00012 00001 01102 00110 10102 01110 10102 01111 10102 10000 00012 10111 20000 12111 11211 00120 00002 01020 00200 12011 21102 00121 01200 12101 20002 11101 11002 10100 01002 11100 10012 10000 10012 01000 00102 11020 10200 02100 21002 11010 12110 10120 11101 20010 01201 00102 10210 20020 02012 01102 10102 00102 00102 01012 10110 21000 02000 00201 10020 10112 00001 20101 02101 11210 11020 10012 10012 11112 01112 01012 00002 01110 11010 00211 10010 00101 21010 00100 11120 00010 10011 12000 10001 10002 11201 20120 02002 01020 00200 12011 21102 10102 10102 01102 01102 10012 11111 01112 01000 00112 01110 00112 00100 00002 00001 00012 01110 10200 11100 20110 10120 00000 02010 00012 11012 10012 00112 01102 11002 01012 00002 00112 01102 11012 00110 02000 11020 11011 21110 01210 00002 11100 21111 02000 11200 01120 10002 10200 20021 12002 11020 01200 12101 20102 11002 10102 00112 01102 10002 01012 00002 00112 01102 11012 10011 10021 11111 00201 10111 02011 00010 20000 01002 01020 01200 12111 20002 01110 10200 11100 20110 10120 00000 02010 00012 01200 20020 12102 00101 10210 01000 21111 00021 11100 02000 01012 11201 20120 12102 11201 20121 02002 01010 20000 12001 01201 10121 10002 11000 12010 01120 10111 20001 10200 10002 11100 02100 01021 10111 21111 01200 10002 10200 20020 02012 11121 11200 12001 21002 11211 20120 02002 10101 11211 11011 20101 01120 00000 02000 10012 01002 00102 00112 00012 10002 10210 20120 12102 11020 10200 02100 21002 00001 20101 02101 11210 11020 10012 00111 01021 01001 00211 10011 12111 10111 20000 10002 10210 20120 12102 11110 20000 02100 10211 00020 01002 11102 11102 00102 00002 10012 11021 10201 02000 20002 10210 20020 02012 01010 20011 02001 10210 11020 00012 01020 00200 12011 21102 00000 10201 00001 20111 00121 11101 02000 00002 01200 20020 12102 01200 20020 12002 11102 10102 00002 01002 11012 10210 20120 12102 11100 02111 00020 01010 20000 10210 01002 10101 12101 00021 11011 20100 00210 01012 01012 00002 00112 01102 11012 00111 10201 00100 20100 10021 11001 02100 11112 11201 20120 12102 01110 21001 02100 10211 00020 01002 01200 20020 12102 11001 11210 10011 20011 01120 11000 02100 00012 11201 20121 02002 10111 21110 02110 11210 00020 00002 10110 21100 12110 00201 10121 00102 01110 11200 11100 20110 10120 00000 12010 00002 00110 11120 11000 11201 01101 12010 10000 21000 00012 11021 10201 02000 20002 01111 11112 00000 10112 00110 00112 11001 00002 00000 10012 11002 10102 10112 11012 00002 10200 20021 12002 01020 00200 12011 21102 00101 02100 01021 11110 21111 00200 00012 00110 01012 01110 00012 01011 00112 01001 00112 10010 00002 12020 20202 11000 02101 00020 01110 20110 10210 00002 11020 00200 02100 20112 01020 01200 12111 20002 01101 02101 00021 11110 20011 01201 00002 01020 00200 12011 21102 01001 01112 10001 00102 00011 00012 11010 00002 00100 10002 10200 20021 12002 11020 01200 12101 20102 11001 10021 00011 10210 00001 12111 00011 20001 10002 01200 20020 12102 00001 02000 00020 10110 20101 10200 10012 11021 10201 02000 20002 00000 10211 01010 20110 11021 11010 02000 10012 00001 01102 00110 10112 01110 10112 01111 10102 10000 00002 01020 00200 02100 21112 10210 20120 12102 10000 02100 00021 11010 20110 10200 00002 01012 01012 00002 00002 00102 10210 20120 12102 11110 02010 00021 01110 21000 10200 00002 10200 20020 02012 01020 00200 12011 21102 00002 00112 01102 01012 10002 01102 01102 00112 10002 10002 12120 20202 01010 11020 10101 10200 00001 12000 01011 20010 10002 10200 20021 12002 00110 11101 12000 11000 11020 10000 00101 21110 00101 00210 10100 10002 00001 10012 00110 10012 01101 00112 01010 00112 10000 01002 11111 21000 02000 10201 01121 10012 10210 20120 12102 11110 21000 02000 10201 00021 01002 11020 10201 12011 21002 01200 20020 12102 01011 21100 02100 10200 01120 01012 11111 10211 10110 20100 11020 00001 02010 00012 11002 00102 10012 00012 00102 11111 02010 01020 11011 21000 01200 00002 00100 11201 10000 20100 00120 10110 12100 00002 01200 20020 12102 11111 11102 00100 01002 00101 01002 10010 00102 10110 01112 10011 21101 12011 01201 10120 00002 10200 20021 12002 11000 01020 10010 10201 01111 02000 11110 20010 00012 11210 21020 12002 11020 10201 12101 20002 11020 10200 02100 21002 00002 01012 10112 10112 01002 11000 02101 00020 01110 20110 10210 00002 11201 20121 02002 01112 00012 00012 01012 11002 11002 10102 10102 11102 00012 10200 20021 12002 01000 01211 00011 20000 11121 00011 02001 10002 01100 20110 02001 10210 11021 00002 00110 11120 11000 11201 01101 12010 10000 21000 00012 00010 02000 01020 10011 21111 11210 00002 11210 21021 12002 10210 20120 12102 11020 10200 02100 21002 11210 21020 12002 01012 01012 00002 00002 00102 11201 20121 02002 11111 21000 02000 10201 01121 10012 01200 20020 12102 01102 01102 00112 10112 10002 01020 00200 12011 21102 00001 10012 00110 10012 01101 00112 01010 00112 10000 01002 01001 11112 10000 00112 10011 10112 01010 00002 00000 00012 11001 11110 11120 01101 00100 01210 11010 10000 12110 00001 00010 20000 10000 10002 01000 01121 10001 11200 00111 12100 01101 20011 00002 00010 01200 01001 20100 11121 10011 02101 10002 00000 01210 10011 21110 11120 10111 12000 10002 10200 20021 12002 12120 20202 00001 01102 00110 10102 01110 10102 01111 10102 10000 00012 10110 21100 12110 00201 10121 00102 11011 10210 00000 20000 00020 00110 02101 10112 01020 00200 12011 21102 00001 10012 00110 10012 01101 00112 01010 00112 10000 01002 10200 20020 02012 11121 11200 12001 21002 10011 11010 20110 11000 02010 01100 11200 11110 10120 00000 01002 01200 20020 12102 11001 20111 02101 11210 11020 00012 11020 00200 02100 20112 00112 10102 11012 11002 00002 01002 00102 00112 00012 10002 01110 10111 21010 00101 12101 00010 11201 00011 00020 00010 00012 11211 20120 12002 01020 00200 12011 21102 01012 01012 00002 00002 00102 01002 11002 10012 10012 00102 11121 11200 12001 21002 01020 11200 12101 20002 01120 00200 02011 21002 11112 00102 00102 10012 10112 01020 01200 12111 20002 11002 00102 10012 00012 00102 11111 11121 11001 01201 01110 12000 00101 20000 10002 12020 20202 01110 02110 10021 00110 21001 10200 00002 01210 21120 02012 11110 01120 01001 11210 11111 12110 11101 20000 00002 11012 10002 00002 00012 10112 01020 00200 12011 21102 10102 00102 01002 11002 10002 10200 20021 12002 00101 01121 01011 00211 11011 02111 10111 20000 00012 10210 20020 02012 01110 10200 11100 20110 10120 00000 02010 00012 11021 10201 02000 20002 01102 00102 00002 01002 11012 11121 11200 12001 21002 11012 10012 00112 01102 11002 12020 20202 11121 11200 12001 21002 11001 01100 20101 00000 02010 10001 10200 01100 11020 01000 10002 01200 20020 12102 11001 10210 10010 21011 01121 10110 12000 00002 00102 01012 01012 11102 00002 01020 00200 12011 21102 11101 11002 10100 01002 11100 10012 10000 10012 01000 00102 01012 00002 00112 01102 11012 00101 10021 10101 00201 01011 02111 00110 20000 00002 11201 20120 12102 01012 01012 00002 00002 00102 01100 20110 02001 10210 11021 00002 11201 20121 02002 01010 01011 11211 00011 00010 21000 11000 10120 00110 00010 02001 10001 00002 01001 12100 00121 00111 20101 01200 00002 00001 10002 00100 01002 01011 00102 01010 11102 00100 00002 01200 20121 02112 01020 00200 12011 21102 00010 00010 20011 10101 02010 01011 10201 10100 10020 00001 00012 10200 20021 12002 00001 10200 00100 20101 11120 11101 12000 00002 11021 10201 02000 20002 01020 00200 12011 21102 00100 10211 01000 20100 11021 11011 02000 00012 11101 11002 00100 10002 10100 10102 11000 00102 00010 01002 10200 20020 02012 11121 11200 12001 21002 01002 10102 10112 01112 00002 11110 11011 21000 01100 02101 11110 01210 11111 10020 10000 00102 01112 00112 00012 01002 11002 10210 20120 12102 11020 10200 02100 21002 01000 20110 02001 10200 11020 00002 01200 20020 12102 11002 00102 00012 11112 10002 12120 20202 10001 02101 01121 01101 21011 00201 00002 10200 20021 12002 11112 00102 00102 10012 10112 11111 01210 10000 20001 00121 00000 02010 00112 01012 01012 00002 00002 00102 01110 02000 00020 01110 21000 10200 00002 01020 00200 12011 21102 00002 00112 01102 01012 10002 01102 01102 00112 10002 10002 11021 10201 02000 20002 01020 00200 12011 21102 11110 10102 10101 00012 01101 00012 00011 00102 00100 01102 00111 20011 12011 01211 00021 01002 01200 20020 12102 10102 11002 10002 11102 00012 00112 10102 11012 11002 00002 11010 21010 02001 10201 10021 00002 00100 10120 01110 01211 01011 12100 01011 20100 00002 01102 00102 00002 01002 11012 11110 11200 01000 21101 11121 01110 02000 00012 01011 00211 00000 21001 01020 00111 02001 01002 01020 00200 12011 21102 00001 10012 00110 10012 01101 00112 01010 00112 10000 01002 10200 20021 12002 11101 02000 11021 00111 21101 11200 10002 12120 20202 11020 00210 02010 20012 10200 20021 12002 01102 00102 00002 01002 11012 11121 11200 12001 21002 01102 10102 00102 00102 01012 11100 00200 10001 21000 01121 10001 12010 11002 01000 20001 02001 11201 11121 10002 11201 20120 12002 12120 20202 11010 21010 02001 10201 10021 00002 10200 20021 12002 01000 00110 20000 01010 02000 01111 11200 11111 01120 00000 00002 00010 01200 01001 20100 11121 10011 02101 10002 01111 11111 20010 01101 12001 10110 11200 11011 00020 00010 00012 11021 10201 02000 20002 11001 11120 11100 11210 11101 12101 10000 20000 10012 11020 00200 02100 20112 11211 20120 02002 10011 02100 10020 00011 20000 10201 10002 11021 10201 02000 20002 11210 21020 12002 10110 10121 00010 00211 10100 12111 01000 20001 00112 10001 10210 11000 21110 01121 11001 12000 10002 11120 11210 12100 20002 11001 01110 02011 01001 10020 10110 01001 20001 10000 01200 10010 10102 00001 20101 02101 11210 11020 10012 00110 00200 00000 20110 01020 10001 02000 10002 01101 11201 10110 20010 01121 00001 02000 10012 11111 02010 01020 11011 21000 01200 00002 11201 20120 02002 10000 20100 12010 11211 01120 00002 01200 20020 12102 01102 00102 00102 10002 00002 01020 00200 12011 21102 11020 10201 12101 20002 00112 10102 11012 11002 00002 01102 10002 01002 10102 00012 01110 10200 11100 20110 10120 00000 02010 00012 10002 10102 01112 01112 10002 00110 00200 00000 21110 01021 01001 02010 01002 01200 20121 02112 11102 10102 00002 01002 11012 10210 20120 12102 11020 10200 02100 21002 11110 00021 00001 00201 00101 02011 01010 20010 01002 01020 00200 02100 21112 11211 20120 12002 01020 00200 12011 21102 00111 01210 10001 21110 10121 11000 12000 10102 01110 02100 00021 01110 21100 10200 00002 11201 20120 02002 01012 00002 00112 01102 11012 00011 00020 01110 00201 10101 02010 00010 20000 00002 01002 10102 10112 01112 00002 11110 11121 00011 00201 10101 12011 01010 20001 00012 11021 10201 02000 20002 01020 01200 12111 20002 01102 00102 00002 01002 11012 10210 20120 12102 10000 02100 00021 11010 20110 10200 00002 01112 10002 10102 00112 01012 00000 02000 00120 10011 21100 11210 11002 01012 01012 00002 00002 00102 01020 00200 12011 21102 11101 11002 10100 01002 11100 10012 10000 10012 01000 00102 10002 10102 01112 01112 10002 11001 20111 02000 01210 11021 00012 01200 20020 12102 10111 02000 01020 01011 21100 01201 00102 11021 10201 02000 20002 01102 00102 00002 01002 11012 11201 20120 12002 11012 10012 00112 01102 11002 12020 20202 00111 10021 01001 00211 01011 02110 00110 20000 00002 01020 00200 12011 21102 11120 01200 02110 21012 01020 11200 12101 20002 01012 00002 00112 01102 11012 10002 10102 01112 01112 10002 00001 00021 10111 00201 10011 02111 10110 20000 00002 01200 20020 12102 11210 21020 12102 12020 20202 00100 20100 02010 10201 01021 00002 01200 20020 12102 11101 11020 01101 00210 10011 12110 00011 20001 00002 01101 02101 00021 11110 20011 01201 00002 01102 00102 00002 01002 11012 01020 00200 12011 21102 11101 11002 10100 01002 11100 10012 10000 10012 01000 00102 11020 10200 02100 21002 11101 12100 01120 11111 20111 11200 00002 01200 20020 12102 12120 20202 11010 20111 02101 11200 10120 00102 01010 11020 10101 10200 00001 12000 01011 20010 10002 10200 20021 12002 00110 11120 00100 11211 01001 12100 10000 20100 10012 11001 11110 11112 00110 10010 00112 10110 10100 00112 11000 00100 01012 00001 00001 00002 01102 00102 00002 01002 11012 01012 00002 00112 01102 11012 10002 10102 01112 01112 10002 11111 20101 12010 11201 00021 00012 01200 20020 12102 00001 10200 01100 21101 01021 00101 02011 00012 00110 11101 12000 11000 11020 10000 00101 21110 00101 00210 10100 10002 00001 10012 00110 10012 01101 00112 01010 00112 10000 01002 01020 00200 02100 21112 01020 00200 12011 21102 01002 10102 10112 01112 00002 12020 20202 01111 10200 00100 20000 10020 11001 02110 11112 10110 21000 02000 00201 10020 10112 10200 20020 02012 01020 00200 12011 21102 01002 10102 10112 01112 00002 11110 01120 10000 00201 10111 12000 00100 21000 00012 10200 20020 02012 10000 02100 10021 11110 21110 10200 00002 11020 01200 12101 20102 11001 10021 00011 10210 00001 12111 00011 20001 10002 11121 11200 12001 21002 10011 12100 01121 11011 21110 00200 00012 00112 10102 11012 11002 00002 11010 21010 02001 10201 10021 00002 10011 02100 10020 00011 20000 10201 10002 01000 01121 10001 11200 00111 12100 01101 20011 00002 01102 00102 00002 01002 11012 10002 10102 01112 01112 10002 11101 11111 11210 11000 00100 21010 01000 11121 01101 01010 02010 00000 10012 11011 10210 10011 21010 10121 00000 12000 00002 11011 02101 01020 11010 20001 10200 00012 11100 11010 10020 00100 11110 00210 01101 10001 02111 11101 01110 20100 00100 01002 11021 10201 02000 20002 12020 20202 00111 20011 12011 01211 00021 01002 01200 20020 12102 11100 02101 00120 01011 20100 11210 00002 10200 20020 12002 01020 00200 12011 21102 00121 01200 12101 20002 11101 11002 10100 01002 11100 10012 10000 10012 01000 00102 10002 10102 01112 01112 10002 11021 00210 02010 20012 01102 10102 00102 00102 01012 00110 11120 11000 11201 01101 12010 10000 21000 00012 00001 01102 00110 10102 01110 10102 01111 10102 10000 00012 11010 10121 00010 00201 00000 12010 00000 20010 10112 01020 00200 02100 21112 10002 10102 01112 01112 10002 01111 01111 12010 00111 01121 11001 01011 21011 01000 00200 00100 10012 10200 20020 02012 10111 21101 12010 11200 10020 00012 10110 12110 01121 10001 20110 11210 01002 01102 00102 00002 01002 11012 01012 00002 00112 01102 11012 11020 10200 02100 21002 00100 01000 21010 01100 02011 10100 10211 01010 01020 00010 01002 11201 20120 02002 10000 20100 12010 11211 01120 00002 01200 20020 12102 01110 20000 02000 10210 00021 10002 11211 20120 02002 01111 11010 01120 10000 01100 01211 11110 00100 02101 01011 01000 20001 00000 00002 10200 20021 12002 00110 11101 12000 11000 11020 10000 00101 21110 00101 00210 10100 10002 00001 10012 00110 10012 01101 00112 01010 00112 10000 01002 01102 00102 00002 01002 11012 11110 20000 02100 10211 00020 01002 00200 20121 12102 11002 01002 01102 01102 10002 01200 20020 12102 10102 11002 10002 11102 00012 01010 02000 01020 00011 21000 11201 11002 10011 01210 01001 20000 11120 00010 12011 00002 00010 02000 01020 10011 21111 11210 00002 01012 00002 00112 01102 11012 11000 10020 11101 00200 00111 02101 11010 21000 00002 01020 00200 12011 21102 11101 11002 10100 01002 11100 10012 10000 10012 01000 00102 11020 10200 02100 21002 11211 20120 02002 11111 10121 00000 01201 00111 12011 00011 20010 00002 10012 00002 01112 11102 10002 10200 20020 02012 11121 11200 12001 21002 11021 00210 02010 20012 01111 01021 01100 00200 11001 12111 10101 20000 01002 01200 20020 12102 11100 11100 20001 00110 02100 10010 01211 11000 00120 00000 00102 01010 20000 12001 01201 10121 10002 00101 01121 01011 00211 11011 02111 10111 20000 00012 00110 10002 11011 11102 01011 01112 11101 00012 00010 00002 11011 10210 00000 20000 00020 00110 02101 10112 10101 11200 11011 21100 01120 10000 02000 10012 01010 20000 12001 01201 10121 10002 11120 11200 12100 20102 01110 11200 10010 20010 00120 00000 02001 01002 01100 01102 00001 10102 00000 10102 11101 10002 00010 00012 01001 12111 00121 01001 20010 00200 01002 11021 10201 02000 20002 12020 20202 00011 11002 10000 01002 11001 01102 11111 01102 00000 10002 11020 01200 12101 20102 00010 01200 00101 21000 10121 11110 12000 00102 11201 20121 02002 00110 11120 11000 11201 01101 12010 10000 21000 00012 01002 00012 00112 01102 11002 01112 00112 00012 01002 00102 11021 10201 02000 20002 01110 20001 02000 10211 00020 01002 11121 00201 12000 20002 01020 00200 12011 21102 00100 11020 10001 00210 00111 12100 01011 20100 00002 10210 20120 12102 10000 02100 00021 11010 20110 10200 00002 01020 00200 02100 21112 01012 00002 00112 01102 11012 10002 10102 01112 01112 10002 01020 00200 12011 21102 00000 01200 10101 21101 10121 01110 12010 00102 11021 00210 02010 20012 11201 20120 12102 11021 10201 02000 20002 10210 20120 12102 01102 10102 10102 00102 01012 11002 01102 00012 10012 10102 00111 00002 01011 01002 01011 11102 01000 11102 10011 00002 11211 20120 02002 11100 21011 12010 11200 01020 00002 11001 10002 10101 00102 10110 01112 11010 11112 00001 10002 01012 00002 00112 01102 11012 11002 11102 10012 00012 10102 11201 20120 12102 11020 10201 12101 20002 11111 02000 00021 00011 21110 11201 00002 01210 21120 02012 00101 20010 02010 00201 00120 00112 11121 11200 12001 21002 11121 01210 02010 20012 11001 01010 20101 00100 02011 00000 11200 10000 10120 00101 01002 01020 00200 12011 21102 11112 01002 01112 10002 00012 11010 11121 00100 01200 11000 12101 10010 20100 10002 11121 11200 12001 21002 11001 00210 00001 20010 01120 11011 12110 11002 10201 20121 12002 11021 00210 02010 20012 10200 20020 02012 11110 21000 02000 10201 00021 01002 00200 20121 12102 01000 20100 02001 10210 01020 00002 11102 01002 01112 10112 00002 12020 20202 11121 11200 12001 21002 10011 11111 20000 00100 02000 01001 11211 10100 00020 00000 00012 00102 00102 01002 01002 00002 12020 20202 11110 21000 02000 10201 00021 01002 11002 01102 00012 10012 10102 11210 21020 12002 00100 10111 21100 00000 12010 01100 01211 10110 01020 00100 10002 01020 00200 02100 21112 10210 20120 12102 10002 10102 01112 01112 10002 01111 01021 10010 00200 10001 12000 00101 21001 01002 01200 20020 12102 01002 00012 00112 01102 11002 11021 10201 02000 20002 01102 00102 00002 01002 11012 11121 11200 12001 21002 01020 00200 12011 21102 00120 00211 12010 20012 01200 20020 12102 11020 01200 12101 20102 11001 01121 01101 10210 10000 12101 00000 20101 01002 12020 20202 10000 21010 12110 11201 01120 01002 01012 01012 11102 00102 00012 01020 00200 12011 21102 11002 11102 10112 00012 00002 10200 20021 12002 01020 00200 12011 21102 11012 10102 10112 00102 10002 01012 00002 00112 01102 11012 11002 01002 01102 01102 10002 01200 20020 12102 01002 01002 00112 10012 00002 01210 21120 02012 11111 00210 00000 21001 00121 00100 12010 00002 01020 00200 02100 21112 01012 00002 00112 01102 11012 01020 00200 02000 20002 11110 02111 01020 11011 20110 11200 01002 00210 21120 12002 01102 00102 00002 01002 11012 11021 00210 12111 20102 11020 10200 02100 21002 01002 00002 00102 00102 00002 10200 20021 12002 11010 11211 00110 21000 10120 00010 02001 10002 11110 12010 10121 00111 21001 11200 10002 12020 20202 11002 00102 00012 11112 10002 01102 00102 00002 01002 11012 01112 10002 10102 00112 01012 11121 11200 12001 21002 00102 01002 01012 01012 10102 01020 00200 12011 21102 11101 11002 10100 01002 11100 10012 10000 10012 01000 00102 10002 10102 01112 01112 10002 01020 00200 12011 21102 00112 10102 11012 11002 00002 00000 01200 10101 21101 10121 01110 12010 00102 11201 20120 02002 01011 11102 01100 11102 11000 10112 11101 00012 00000 00102 01020 00200 02100 21112 01001 12111 00121 01001 20010 00200 01002 11021 10201 02000 20002 12020 20202 11020 10200 02100 21002 01020 00200 12011 21102 00102 00102 10112 10012 00102 11201 20120 02002 11011 12000 01121 00011 21100 00200 00012 01012 00002 00112 01102 11012 11011 00211 00000 20001 01020 00111 02101 01002 11201 20120 12102 11000 11112 01100 00002 10110 01112 10111 00002 00000 10012 01020 00200 02100 21112 10210 20120 12102 01111 00211 11100 21010 11020 00001 02000 01002 01200 20020 12102 01110 21011 02010 10210 00020 00012 12120 20202 01011 21010 12001 01200 10121 00102 11201 20120 02002 01020 00200 12011 21102 01010 11020 10101 10200 00001 12000 01011 20010 10002 01111 02011 01021 11011 21000 01200 10002 11021 10201 02000 20002 10200 20020 02012 11112 10002 00112 00002 10002 11002 01102 00012 10012 10102 00012 00012 01112 11102 10002 00111 00002 01011 01002 01011 11102 01000 11102 10011 00002 11112 00112 10112 01002 00012 00010 02000 01020 10011 21111 11210 00002 11120 00210 02010 21012 00102 10102 11002 11002 00002 01112 00012 00012 01012 11002 10200 20020 02012 11201 20120 12002 00111 10020 01011 00201 10111 02011 00010 20000 10002 01200 20020 12102 11001 02010 00020 10110 20011 10200 00012 00001 20101 02101 11210 11020 10012 11012 00102 10012 11102 00012 10200 20021 12002 11020 01200 12101 20102 11110 10102 10101 00012 01101 00012 00011 00102 00100 01102 11021 10201 02000 20002 01200 20020 12102 01101 00201 01010 21111 10021 01101 02000 01012 10111 11201 00010 21101 00121 10100 02001 00002 01000 10120 00101 01211 11110 12101 01001 20000 00102 10200 20021 12002 01020 00200 12011 21102 11002 00002 10012 11012 00002 00100 01112 10100 10112 11101 10112 11001 10002 00000 00012 10200 20020 02012 11111 01020 10110 00201 01001 12000 10101 21010 01002 10210 20120 12102 10101 00200 11100 21101 11020 10101 02000 00002 12120 20202 11020 00210 02010 20012 00102 01012 01012 11102 00002 10101 11121 00000 11210 00101 12100 00000 20110 10012 10101 00210 00100 21001 11021 00001 02011 10012 11021 10201 02000 20002 01020 00200 12011 21102 00002 00112 01102 01012 10002 01102 01102 00112 10002 10002 11112 10002 00112 00002 10002 11000 02100 00121 00011 21011 11201 00002 01020 00200 12011 21102 11002 11102 10112 10012 00002 01002 01002 00012 10012 00102 11211 20120 12002 01020 00200 12011 21102 10111 11201 11011 20101 00120 10000 02000 00002 10100 10110 12001 01000 10121 11010 00111 21100 10100 11200 01000 11002 11121 01210 02010 20012 01020 00200 12011 21102 01011 21010 12001 01200 10121 00102 11201 20120 12002 00101 10021 00011 00211 11011 02110 10110 20000 00002 10210 20120 12102 11101 11002 00110 10002 10100 11102 11000 01102 00010 00002 01020 00200 12011 21102 11101 11002 10100 01002 11100 10012 10000 10012 01000 00102 01200 20020 12102 01102 00102 00102 10002 01002 12120 20202 11100 02010 00120 01111 21010 11210 00002 11110 10100 20000 00001 02101 11100 01211 00110 00120 00000 10102 11201 20120 02002 11011 12101 11021 01001 20110 00200 01012 11021 10201 02000 20002 01200 20020 12102 11111 21000 12011 00200 01020 00012 01001 12111 00121 01001 20010 00200 01002 01200 20020 12102 11002 10102 00112 01102 10002 01000 20001 02001 11201 11121 10002 11000 11000 20100 10010 12010 11100 11200 01111 01121 00000 01002 11211 20120 12002 01020 11200 12101 20002 11211 20120 12002 01012 00002 00112 01102 11012 10002 10102 01112 01112 10002 11110 01002 00100 11002 10111 11102 11011 10102 00000 00002 10200 20121 12102 11112 10002 00112 00002 10002 00200 20121 12102 11000 10111 20111 01001 12001 01100 11210 10110 00021 00100 10012 01101 11020 11000 10200 11101 12101 10001 21000 00002 01012 01012 00002 00002 00102 01020 01200 12111 20002 11110 21001 02100 11201 01120 00002 01100 01112 00000 10112 00101 10112 10001 10002 00010 00012 11201 20120 02002 11111 12100 01021 01001 21110 00200 00002 00011 21000 12110 00201 00020 00002 00100 11201 10000 20100 00120 10110 12100 00002 01020 00200 02100 21112 10200 20121 12102 11112 10002 00112 00002 10002 00200 20121 12102 01100 10101 11200 10100 00011 20010 10000 01120 01010 10000 02000 10011 10012 01112 00012 00012 01012 11002 01102 00002 00112 10012 00002 11021 10201 02000 20002 01020 00200 12011 21102 01011 21010 12001 01200 10121 00102 01200 20020 12102 11211 20120 12002 01112 11102 10112 00002 00012 10000 01210 11011 21110 11121 11011 12000 10002 11211 20120 12002 10200 20121 12102 11120 11210 12100 20002 11011 10210 00000 20000 00020 00110 02101 10112 11000 11121 00100 11201 11001 12001 10000 20000 10012 01002 00012 00112 01102 11002 01001 12111 00121 01001 20010 00200 01002 11201 20120 12002 11102 10002 10002 01102 10002 10210 20020 02012 01112 00012 00012 01012 11002 10200 20121 12102 11120 11200 12101 21002 11001 01210 10100 20111 00120 01100 02000 00012 11100 02010 00020 01110 21010 10210 00002 12120 20202 11000 02101 00121 01011 20001 11201 01002 10200 20021 12002 01102 01002 00112 10102 10002 10201 20020 12102 11001 11200 11110 21010 01121 10100 02000 00012 11021 10201 02000 20002 10021 11200 02011 20002 10000 01210 11011 21110 11121 11011 12000 10002 11021 10201 02000 20002 11002 01002 01102 01102 10002 01002 00012 00112 01102 11002 11211 20120 12002 12120 20202 01100 10101 11200 10100 00001 20010 10000 00120 01010 10001 02000 10011 10002 00111 11102 10001 10112 11100 10112 01110 00102 00010 00002 10210 20120 12102 11002 01102 00012 10012 10102 11112 10102 01102 00112 00002 00012 00012 01112 11102 10002 10101 11200 11011 21100 01120 10000 02000 10012 12120 20202 00111 20110 02010 01201 00021 00002 01020 01200 12111 20002 01020 00200 12011 21102 11001 11101 10201 00000 10100 20101 11011 11120 00100 00101 12001 00001 00002 10001 10121 01100 01211 10011 12111 00111 20001 00002 10210 20120 12102 11002 01102 00012 10012 10102 11210 21020 12002 00111 12101 10121 10101 21101 10200 00002 01200 20020 12102 00110 00200 00010 20110 10121 10010 12100 00102 01020 00200 12011 21102 11000 10010 12101 01110 10121 00111 11101 20101 10010 01210 10000 00102 10021 10201 12011 20002 11110 10002 00110 00002 10111 10102 11001 10102 00000 01002 11012 10002 00002 00012 10112 01112 00012 00012 01012 11002 11021 10201 02000 20002 00001 20101 02101 11210 11020 10012 00111 12101 10121 10101 21101 10200 00002 01200 20020 12102 00110 00200 00010 20110 10121 10010 12100 00102 01012 00002 00112 01102 11012 01121 10210 12000 20012 00200 20121 12102 11020 01200 12101 20102 00102 00102 01102 11102 10012 11002 00102 00012 11112 10002 10200 20021 12002 10100 11121 00110 11210 00001 12101 11000 20100 00012 01002 00012 00112 01102 11002 10021 10201 12011 20002 10210 20120 12102 11002 11002 10012 10112 00002 00101 01121 10010 00201 00001 12111 10100 20001 01012 11021 00210 02010 20012 10201 20121 12002 01112 00012 00012 01012 11002 11110 11102 01101 11002 01101 01112 00101 00112 00010 00002 01111 12100 00020 01011 21100 10200 00012 11110 21000 02000 10201 00021 01002 11002 01102 00012 10012 10102 00011 10021 01101 00211 10011 02110 00010 20000 00002 01102 10102 00102 00102 01012 01102 00102 00002 01002 11012 10210 20120 12102 01110 21010 02101 00200 01020 01112 00200 20121 12102 11201 20121 02002 01020 00200 12011 21102 01121 01210 12100 20102 01111 12000 01020 00010 20110 01211 01112 11101 02011 00020 10011 20001 01210 01002 01200 20020 12102 00111 00201 01101 20101 11120 10001 12100 11002 01020 00200 12011 21102 00102 00102 01002 01002 00002 01121 11210 12000 20002 11101 12110 00021 00010 21000 11201 01012 01102 00102 00002 01002 11012 11121 11200 12001 21002 00001 11200 01011 21110 01120 11100 02000 00012 01010 20001 02001 11201 11121 10002 01101 20000 12001 11210 01120 00002 11002 11002 10012 10112 00002 10210 20120 12102 01200 20020 12002 11021 00210 02010 20012 01112 10112 01012 10002 00002 11201 20121 02002 11011 12101 01121 00011 20000 00210 10012 10201 20020 12102 11021 10201 02000 20002 10210 20120 12102 10102 01102 01112 01012 10102 11120 00210 02010 21012 11021 00210 02010 20012 01200 20020 12102 01010 02000 00121 00011 21001 11200 11002
diff --git a/2017/1a.ciphertext b/2017/1a.ciphertext
new file mode 100644 (file)
index 0000000..4b9d9c5
--- /dev/null
@@ -0,0 +1,4 @@
+HVMTVH,
+DO DN BMZVO OJ CZVM AMJH TJP. RZ YDY KDXF PK NJHZ XCVOOZM V XJPKGZ JA HJIOCN VBJ VIY E RVN HZIODJIZY OCZMZ OJJ, NJ RZ VGMZVYT CVQZ V ADGZ JI CZM. CZM IVHZ DN EJYDZ VIY NCZ RJMFN VN GDVDNJI WZORZZI OCZ WMDODNC GDWMVMT VIY OCZ WMDODNC HPNZPH, MZNZVMXCDIB GDIFN WZORZZI VMOZAVXON VIY DHKZMDVG MJHVI OZSON, NJ OCVO ODZN DI RDOC OCZ DIOZGGDBZIXZ TJP CVQZ WZZI MZXZDQDIB. IJOCDIB NPBBZNON OCVO NCZ CVN WZZI DIQJGQZY DI VITOCDIB NCVYT VIY NCZ CVN CZGKZY RDOC NZQZMVG DINPMVIXZ AMVPY XVNZN. NCZ CVN VI DIOZMZNODIB WVXFBMJPIY. NCZ YDY V KCY JI CPHVI HDBMVODJI NOPYDZN, HVDIGT HVOCZHVODXVG HJYZGGDIB, OCZI HJQZY JI OJ NOPYT FIJRGZYBZ HDBMVODJI RCDXC BJO CZM DIOJ OCZ WDWGDJKCDGZ XDMXPDO. VAOZM BMVYPVODIB NCZ NKZIO NJHZ ODHZ RDOC JIZ JA OCZ GJIYJI VPXODJI CJPNZN RJMFDIB JI KMJQZIVIXZ WZAJMZ OVFDIB CZM XPMMZIO KJNDODJI RDOC OCZ GDWMVMT. OCZMZ MZVGGT DN IJOCDIB NPNKDXDJPN DI CZM WVXFBMJPIY VIY D RVN DIXGDIZY OJ RMDOZ CZM JAA VN V GZVY, WPO RCZI D BJO TJPM HZNNVBZ D YZXDYZY D RVIOZY OJ HZZO CZM. D OMDZY OJ NZO OCVO PK JIGT OJ WZ OJGY OCVO NCZ DN JPO JA XJPIOMT AJM V RCDGZ. DI XVDMJ.
+D RDGG NZZ TJP OCZMZ.
+CVMMT
diff --git a/2017/1a.plaintext b/2017/1a.plaintext
new file mode 100644 (file)
index 0000000..68a461c
--- /dev/null
@@ -0,0 +1,4 @@
+MARYAM,
+IT IS GREAT TO HEAR FROM YOU. WE DID PICK UP SOME CHATTER A COUPLE OF MONTHS AGO AND J WAS MENTIONED THERE TOO, SO WE ALREADY HAVE A FILE ON HER. HER NAME IS JODIE AND SHE WORKS AS LIAISON BETWEEN THE BRITISH LIBRARY AND THE BRITISH MUSEUM, RESEARCHING LINKS BETWEEN ARTEFACTS AND IMPERIAL ROMAN TEXTS, SO THAT TIES IN WITH THE INTELLIGENCE YOU HAVE BEEN RECEIVING. NOTHING SUGGESTS THAT SHE HAS BEEN INVOLVED IN ANYTHING SHADY AND SHE HAS HELPED WITH SEVERAL INSURANCE FRAUD CASES. SHE HAS AN INTERESTING BACKGROUND. SHE DID A PHD ON HUMAN MIGRATION STUDIES, MAINLY MATHEMATICAL MODELLING, THEN MOVED ON TO STUDY KNOWLEDGE MIGRATION WHICH GOT HER INTO THE BIBLIOPHILE CIRCUIT. AFTER GRADUATING SHE SPENT SOME TIME WITH ONE OF THE LONDON AUCTION HOUSES WORKING ON PROVENANCE BEFORE TAKING HER CURRENT POSITION WITH THE LIBRARY. THERE REALLY IS NOTHING SUSPICIOUS IN HER BACKGROUND AND I WAS INCLINED TO WRITE HER OFF AS A LEAD, BUT WHEN I GOT YOUR MESSAGE I DECIDED I WANTED TO MEET HER. I TRIED TO SET THAT UP ONLY TO BE TOLD THAT SHE IS OUT OF COUNTRY FOR A WHILE. IN CAIRO.
+I WILL SEE YOU THERE.
+HARRY
diff --git a/2017/1b.ciphertext b/2017/1b.ciphertext
new file mode 100644 (file)
index 0000000..4f588ac
--- /dev/null
@@ -0,0 +1 @@
+CQNBQ JVNXO VHNBC NNVNM JWMWX KUNTR WBVNW PWJND BSDUR DBJPA RLXUJ RBJBC XAHCX XXOCN WCXUM RWCQN CJENA WBXOA XVNOX ACQNN WCNAC JRWVN WCXOO XXUBJ WMLXF JAMBF QXWNE NAXWL NUNOC CQNBJ ONCHX OCQJC PANJC LRCHC QNUXB BXOCQ NRGCQ UNPRX WBBCJ WMJAM RWKJC CUNQJ DWCNM QRVCQ AXDPQ XDCQR BURON JWMXW UHQRB DWCRV NUHMN JCQKA XDPQC QRVAN URNOJ WMHNC CQNOD UUMNY CQXOQ RBBDO ONARW PRBTW XFWXW UHCXJ ONFJW MNENW RFJBW XCCJT NWRWC XQRBL XWORM NWLND WCRUJ OCNAQ RBMNJ CQCQN CADCQ XOCQN YNARU RWFQR LQQNY UJLNM CQNNW CRANA XVJWJ AVHFJ BORWJ UUHAN ENJUN MCXVN RWCQN YJYNA BQNUN OCCXV NRWQR BFRUU JVXWP CQNVR OXDWM CQRBM NBYJC LQOAX VBNGC DBEJA DBUNP JCDBX OCQNR GCQUN PRXWC XPJRD BBDNC XWRDB YJDUU RWDBY AXLXW BDUJW MPXEN AWXAX OKARC JWWRJ MNBLA RKRWP CQNMN ONJCX OCQNW RWCQJ CLJVD UXMXW DVJCC QNFAR CRWPX OCQRB VNBBJ PNCQN RLNWR QJENB DLLNB BODUU HBJLT NMCQN LRCHR WLUDM RWPCQ NCNVY UNXOL UJDMR DBFQN ANCQN YAXLD AJCXA BPDJA MCXXT CQNRA QNAXR LORWJ UBCJW MFNFN ANJUV XBCNW LRALU NMKHC QNNWN VHOXA LNFQX BNNVN MYXBB NBBNM XOCQN YXFNA CXTWX FXDAC QXDPQ CBFQN ANFNF NANBC AXWPC QNHYX BCNMX WUHQX UMRWP OXALN BFQNA NFNFN ANFNJ TCQNH JCCJL TNMRW BCANW PCQJW MFQNW ANRWO XALNV NWCBJ CCNVY CNMCX SXRWD BCQNH FNANJ CCJLT NMXWA XDCNF NBDAE REXAB XFNXD AUREN BJWMX DACQJ WTBCX PWJND BSDUR DBJPA RLXUJ FQXRW JCRVN XOPAN JCNVN APNWL HANLX PWRBN MCQNB CAJCN PHXOC QNRWB DAPNW COXAL NBXWX DAUNO COUJW TJWML XVVJW MNMXD AANCA NJCFR CQVXV NWCBC XBYJA NMDNC XCQRB JLCRX WCQNV JSXAR CHXOX DALJE JUAHF NANBJ ENMJU XWPFR CQCQN ANBNA ENOXA LNBJU UXCQN AOAXW CURWN CAXXY BQJEN KNNWB UJDPQ CNANM JWMRC RBFRC QPANJ CBJMW NBBJW MMNNY NBCJW PNARQ JENCX ANYXA CCQJC CQNRG CQUNP RXWUX BCRCB JZDRU JCXCQ NNWNV HRONJ ACQJC ROFNJ ANCXB JENUX WMRWR DVJWM ENADU JWRDV OAXVJ BRVRU JAOJC NFNVD BCORW MCQNB CANWP CQCXL ADBQC QRBAN KNUUR XWROF NOJRU CQNWJ UUXOK ARCJW WRJRB UXBCC QRBVD LQXOJ PARLX UJBBC XAHRB FRMNU HTWXF WKDCC QNODU UCADC QVDBC ANVJR WQRMM NWOXA WXFJW MJBAN VJATN MKHVH CADBC NMBUJ ENJWM LXWOR MJWCC RAXFQ JCKNC CNAYU JLNCX QRMNJ KXXTC QJWJV XWPKX XTB
\ No newline at end of file
diff --git a/2017/1b.plaintext b/2017/1b.plaintext
new file mode 100644 (file)
index 0000000..27762f0
--- /dev/null
@@ -0,0 +1,21 @@
+the shame of my esteemed and noble kinsmen gnaeus julius agricola is a story too often told in the
+taverns of rome for the entertainment of fools and cowards who never once left the safety of that
+great city the loss of the ixth legions standard in battle haunted him throughout his life and only
+his untimely death brought him relief and yet the full depth of his suffering is known only to a few
+and even i was not taken into his confidence until after his death the truth of the peril in which
+he placed the entire roman army was finally revealed to me in the paper she left to me in his will
+among them i found this despatch from sextus varus legatus of the ixth legion to gaius suetonius
+paul linus proconsul and governor of britannia describing the defeat of then in that camu lo donum
+at the writing of this message the iceni have successfully sacked the city including the temple of
+claudius where the procurators guard took their heroic final stand we were almost encircled by the
+enemy force who seemed possessed of the power to know our thoughts where we were strong they posted
+only holding forces where we were weak they attacked in strength and when reinforcements attempted
+to join us they were attacked on route we survivors owe our lives and our thanks to gnaeus julius
+agricola who in a time of great emergency recognised the strategy of the insurgent forces on our
+left flank and commanded our retreat with moments to spare due to this action the majority of our
+cavalry were saved along with the reserve forces all other frontline troops have been slaughtered
+and it is with great sadness and deepest anger i have to report that the ixth legion lost its aquila
+to the enemy i fear that if we are to save londinium and ver ulan ium from a similar fate we must
+find the strength to crush this rebellion if we fail then all of britannia is lost this much of
+agricola s story is widely known but the full truth must remain hidden for now and as remarked by my
+trusted slave and confidant tiro what better place to hide a book than among books
\ No newline at end of file
diff --git a/2017/2017-challenge1.ipynb b/2017/2017-challenge1.ipynb
new file mode 100644 (file)
index 0000000..e030a1a
--- /dev/null
@@ -0,0 +1,193 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.caesar import *\n",
+    "from support.text_prettify import *\n",
+    "\n",
+    "c1a = open('1a.ciphertext').read()\n",
+    "c1b = open('1b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(21, -1118.7224542255447)"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score = caesar_break(c1a)\n",
+    "key_a, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "MARYAM,\n",
+      "IT IS GREAT TO HEAR FROM YOU. WE DID PICK UP SOME CHATTER A COUPLE OF MONTHS AGO AND J WAS MENTIONED THERE TOO, SO WE ALREADY HAVE A FILE ON HER. HER NAME IS JODIE AND SHE WORKS AS LIAISON BETWEEN THE BRITISH LIBRARY AND THE BRITISH MUSEUM, RESEARCHING LINKS BETWEEN ARTEFACTS AND IMPERIAL ROMAN TEXTS, SO THAT TIES IN WITH THE INTELLIGENCE YOU HAVE BEEN RECEIVING. NOTHING SUGGESTS THAT SHE HAS BEEN INVOLVED IN ANYTHING SHADY AND SHE HAS HELPED WITH SEVERAL INSURANCE FRAUD CASES. SHE HAS AN INTERESTING BACKGROUND. SHE DID A PHD ON HUMAN MIGRATION STUDIES, MAINLY MATHEMATICAL MODELLING, THEN MOVED ON TO STUDY KNOWLEDGE MIGRATION WHICH GOT HER INTO THE BIBLIOPHILE CIRCUIT. AFTER GRADUATING SHE SPENT SOME TIME WITH ONE OF THE LONDON AUCTION HOUSES WORKING ON PROVENANCE BEFORE TAKING HER CURRENT POSITION WITH THE LIBRARY. THERE REALLY IS NOTHING SUSPICIOUS IN HER BACKGROUND AND I WAS INCLINED TO WRITE HER OFF AS A LEAD, BUT WHEN I GOT YOUR MESSAGE I DECIDED I WANTED TO MEET HER. I TRIED TO SET THAT UP ONLY TO BE TOLD THAT SHE IS OUT OF COUNTRY FOR A WHILE. IN CAIRO.\n",
+      "I WILL SEE YOU THERE.\n",
+      "HARRY\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(caesar_decipher(c1a, key_a))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1113"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('1a.plaintext', 'w').write(caesar_decipher(c1a, key_a))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(9, -2106.574575493358)"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score = caesar_break(c1b)\n",
+    "key_b, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "the shame of my esteemed and noble kinsmen gnaeus julius agricola is a story too often told in the\n",
+      "taverns of rome for the entertainment of fools and cowards who never once left the safety of that\n",
+      "great city the loss of the ixth legions standard in battle haunted him throughout his life and only\n",
+      "his untimely death brought him relief and yet the full depth of his suffering is known only to a few\n",
+      "and even i was not taken into his confidence until after his death the truth of the peril in which\n",
+      "he placed the entire roman army was finally revealed to me in the paper she left to me in his will\n",
+      "among them i found this despatch from sextus varus legatus of the ixth legion to gaius suetonius\n",
+      "paul linus proconsul and governor of britannia describing the defeat of then in that camu lo donum\n",
+      "at the writing of this message the iceni have successfully sacked the city including the temple of\n",
+      "claudius where the procurators guard took their heroic final stand we were almost encircled by the\n",
+      "enemy force who seemed possessed of the power to know our thoughts where we were strong they posted\n",
+      "only holding forces where we were weak they attacked in strength and when reinforcements attempted\n",
+      "to join us they were attacked on route we survivors owe our lives and our thanks to gnaeus julius\n",
+      "agricola who in a time of great emergency recognised the strategy of the insurgent forces on our\n",
+      "left flank and commanded our retreat with moments to spare due to this action the majority of our\n",
+      "cavalry were saved along with the reserve forces all other frontline troops have been slaughtered\n",
+      "and it is with great sadness and deepest anger i have to report that the ixth legion lost its aquila\n",
+      "to the enemy i fear that if we are to save londinium and ver ulan ium from a similar fate we must\n",
+      "find the strength to crush this rebellion if we fail then all of britannia is lost this much of\n",
+      "agricola s story is widely known but the full truth must remain hidden for now and as remarked by my\n",
+      "trusted slave and confidant tiro what better place to hide a book than among books\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(sanitise(caesar_decipher(c1b, key_b))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2058"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('1b.plaintext', 'w').write(prettify(sanitise(caesar_decipher(c1b, key_b))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/2017/2017-challenge2.ipynb b/2017/2017-challenge2.ipynb
new file mode 100644 (file)
index 0000000..ff2624d
--- /dev/null
@@ -0,0 +1,487 @@
+{
+ "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) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.caesar import *\n",
+    "from cipher.affine import *\n",
+    "from cipher.keyword_cipher import *\n",
+    "from cipher.column_transposition import *\n",
+    "from support.text_prettify import *\n",
+    "\n",
+    "ca = open('2a.ciphertext').read()\n",
+    "cb = open('2b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(14, -3006.9125209110575)"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score = caesar_break(ca)\n",
+    "key_a, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "GOSSB,\n",
+      "H OL XASB FSOVAEWK EPS VGA EHKA PN IPDHA. EPKKPYHNF BPWS VHQPEE OMPWV GAS VSOXAK YA VSOUJAD GAS VP O MPPJ VSODAS HN AK-JGOKHKH TPWJ,  QWV O VOHK PN GAS OND H GOXA MAAN UOSSBHNF PWV O EAY MOUJFSPWND UGAUJT PE LB PYN. KHJA BPW H EPWND KHVVKA VP SOHTA LB TWTQHUHPNT, OND, FHXAN GAS QSPEATTHPN, VGASA HT NPVGHNF WNWTWOK OMPWV GAS MAHNF GASA HN UOHSP. TGA TAALT VP MA YAKK JNPYN, YAKK KHJAD, OND LPTV HLQPSVONVKB, YAKK VSWTVAD. HE YA GOD NPVGHNF AKTA VP FP PN H VPP YPWKD GOXA YSHVVAN GAS PEE OT O KAOD, GPYAXAS VYP DOBT OFP LB OFANVT KPTV VSOUJ PE GAS OND TGA DHTOQQAOSAD.\n",
+      "YA SON OKK VGA WTWOK UGAUJT OND EPWND GAS HN UKAPQOVSO GPTQHVOK, SAUPXASHNF ESPL ON OTTOWKV. VGA KPUOK TVOVHPN QSPUWSAD USADANVHOKT OND UPXAS EPS LA OT O KPUOK DAVAUVHXA OND H UOSSHAD PWV O TVONDOSD EHAKD HNVASXHAY YGHUG GOT FHXAN WT O GAODTVOSV PN VGA HNXATVHFOVHPN. IPDHA'T LHTEPSVWNA HT LB KWUJ.\n",
+      "TGA HT GASA VP VSOUJ DPYN O DPUWLANV OQQOSANVKB YSHVVAN MB VGA SPLON GHTVPSHON VOUHVWT. VGA GWNV EPS VGA MPPJ TVOSVAD YGAN TPLAPNA EPWND O DPUWLANV HN VGA XOVHUON KHMSOSB YSHVVAN MB KO VPWSAV. HV HNUKWDAD AZVSOUVT ESPL O KOVHN DPUWLANV VGOV OQQAOSAD VP MA ON ADHVAD XASTHPN PE VGA OFSHUPKO OND IPDHA VAKKT LA VGOV VGA TVBKA YOT SAUPFNHTOMKB VOUHVWT, OND TPLA PE VGA TANVANUAT YASA VGA TOLA OT JNPYN XASTHPNT PE VGA PSHFHNOK. GPYAXAS VGASA YASA O EAY THFNHEHUONV UGONFAT OND IPDHA VSOXAKKAD VP SPLA VP TAOSUG EPS LPSA. HN VGA OSUGHXAT TGA EPWND VOUHVWT' DAOVGMAD UPNEATTHPN YGHUG SAEASSAD VP O DPUWLANV TP TGPUJHNF VGOV VOUHVWT GHLTAKE GOD PSDASAD HV VP MA TQKHV WQ OND UPNUAOKAD OUSPTT O NWLMAS PE THVAT HN VGA ONUHANV YPSKD. NP UKWAT YASA FHXAN VP VGA NOVWSA PE VGA THVAT, MWV VGA DPUWLANV UPNUKWDAD YHVG VGA TVOVALANV \"LB KAFOUB YHKK MA O VSWVG YGHUG PWVKOTVT VGA LPWNVOHN PE FPDT YGHUG FWOSDT HVT FOVAYOB\". VGHT KAD IPDHA VP TWTQAUV VGOV VGA QBSOLHDT OV FHCO YASA O FPPD QKOUA VP TVOSV. VGOV YOT YGASA TGA YOT OVVOUJAD.\n",
+      "HV VPPJ IPDHA VGSAA DOBT VP EHND VGA DPUWLANV GHDDAN OLPNF VGA TVPNAT, OND LB FWATT HT VGOV TPLAPNA YOT YOVUGHNF GAS WNVHK TGA EPWND HV KOVA PN VGA VGHSD DOB. TGA PNKB GOD HV EPS EHXA LHNWVAT MAEPSA TGA YOT SPMMAD, MWV TGA LODA VGA LPTV PE VGOV VHLA, QGPVPFSOQGHNF VGA ESOFLANV. VGA OVVOUJAST VPPJ GAS QGPNA, MWV VGA HLOFA GOD OKSAODB WQKPODAD VP VGA UKPWD, TP OV KAOTV YA JNPY YGOV HV TOHD. QASGOQT LPSA HLQPSVONVKB YA LOB GOXA ONPVGAS UKWA VP VGA KPUOVHPN PE VGA NAZV ESOFLANV, \"VGA EWKK VSWVG LWTV SALOHN GHDDAN EPS NPY, OND OT SALOSJAD MB LB VSWTVAD TKOXA OND UPNEHDONV VHSP, YGOV MAVVAS QKOUA VP GHDA O MPPJ VGON OLPNF MPPJT?\"\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(caesar_decipher(ca, key_a))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "((5, 16, True), -2842.062950889474)"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(m_a, a_a, o_a), score = affine_break(ca)\n",
+    "(m_a, a_a, o_a), score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "AMSSZ,\n",
+      "V MB TESZ FSMDEKYG KHS DAE KVGE HR QHPVE. KHGGHOVRF ZHYS DVCHKK MWHYD AES DSMTEG OE DSMILEP AES DH M WHHL DSMPES VR EG-LAMGVGV NHYL,  CYD M DMVG HR AES MRP V AMTE WEER IMSSZVRF HYD M KEO WMILFSHYRP IAEILN HK BZ HOR. GVLE ZHY V KHYRP GVDDGE DH SMVNE BZ NYNCVIVHRN, MRP, FVTER AES CSHKENNVHR, DAESE VN RHDAVRF YRYNYMG MWHYD AES WEVRF AESE VR IMVSH. NAE NEEBN DH WE OEGG LRHOR, OEGG GVLEP, MRP BHND VBCHSDMRDGZ, OEGG DSYNDEP. VK OE AMP RHDAVRF EGNE DH FH HR V DHH OHYGP AMTE OSVDDER AES HKK MN M GEMP, AHOETES DOH PMZN MFH BZ MFERDN GHND DSMIL HK AES MRP NAE PVNMCCEMSEP.\n",
+      "OE SMR MGG DAE YNYMG IAEILN MRP KHYRP AES VR IGEHCMDSM AHNCVDMG, SEIHTESVRF KSHB MR MNNMYGD. DAE GHIMG NDMDVHR CSHIYSEP ISEPERDVMGN MRP IHTES KHS BE MN M GHIMG PEDEIDVTE MRP V IMSSVEP HYD M NDMRPMSP KVEGP VRDESTVEO OAVIA AMN FVTER YN M AEMPNDMSD HR DAE VRTENDVFMDVHR. QHPVE'N BVNKHSDYRE VN BZ GYIL.\n",
+      "NAE VN AESE DH DSMIL PHOR M PHIYBERD MCCMSERDGZ OSVDDER WZ DAE SHBMR AVNDHSVMR DMIVDYN. DAE AYRD KHS DAE WHHL NDMSDEP OAER NHBEHRE KHYRP M PHIYBERD VR DAE TMDVIMR GVWSMSZ OSVDDER WZ GM DHYSED. VD VRIGYPEP EJDSMIDN KSHB M GMDVR PHIYBERD DAMD MCCEMSEP DH WE MR EPVDEP TESNVHR HK DAE MFSVIHGM MRP QHPVE DEGGN BE DAMD DAE NDZGE OMN SEIHFRVNMWGZ DMIVDYN, MRP NHBE HK DAE NERDERIEN OESE DAE NMBE MN LRHOR TESNVHRN HK DAE HSVFVRMG. AHOETES DAESE OESE M KEO NVFRVKVIMRD IAMRFEN MRP QHPVE DSMTEGGEP DH SHBE DH NEMSIA KHS BHSE. VR DAE MSIAVTEN NAE KHYRP DMIVDYN’ PEMDAWEP IHRKENNVHR OAVIA SEKESSEP DH M PHIYBERD NH NAHILVRF DAMD DMIVDYN AVBNEGK AMP HSPESEP VD DH WE NCGVD YC MRP IHRIEMGEP MISHNN M RYBWES HK NVDEN VR DAE MRIVERD OHSGP. RH IGYEN OESE FVTER DH DAE RMDYSE HK DAE NVDEN, WYD DAE PHIYBERD IHRIGYPEP OVDA DAE NDMDEBERD “BZ GEFMIZ OVGG WE M DSYDA OAVIA HYDGMNDN DAE BHYRDMVR HK FHPN OAVIA FYMSPN VDN FMDEOMZ“. DAVN GEP QHPVE DH NYNCEID DAMD DAE CZSMBVPN MD FVUM OESE M FHHP CGMIE DH NDMSD. DAMD OMN OAESE NAE OMN MDDMILEP.\n",
+      "VD DHHL QHPVE DASEE PMZN DH KVRP DAE PHIYBERD AVPPER MBHRF DAE NDHREN, MRP BZ FYENN VN DAMD NHBEHRE OMN OMDIAVRF AES YRDVG NAE KHYRP VD GMDE HR DAE DAVSP PMZ. NAE HRGZ AMP VD KHS KVTE BVRYDEN WEKHSE NAE OMN SHWWEP, WYD NAE BMPE DAE BHND HK DAMD DVBE, CAHDHFSMCAVRF DAE KSMFBERD. DAE MDDMILESN DHHL AES CAHRE, WYD DAE VBMFE AMP MGSEMPZ YCGHMPEP DH DAE IGHYP, NH MD GEMND OE LRHO OAMD VD NMVP. CESAMCN BHSE VBCHSDMRDGZ OE BMZ AMTE MRHDAES IGYE DH DAE GHIMDVHR HK DAE REJD KSMFBERD, “DAE KYGG DSYDA BYND SEBMVR AVPPER KHS RHO, MRP MN SEBMSLEP WZ BZ DSYNDEP NGMTE MRP IHRKVPMRD DVSH, OAMD WEDDES CGMIE DH AVPE M WHHL DAMR MBHRF WHHLN?”\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(affine_decipher(ca, m_a, a_a, o_a))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('cairo', <KeywordWrapAlphabet.from_largest: 3>), -2538.6487026668074)"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(key_word, key_wrap), score = keyword_break_mp(ca)\n",
+    "(key_word, key_wrap), score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "harry,\n",
+      "i am very grateful for the file on jodie. following your tipoff about her travel we tracked her to a book trader in el-khalili souk,  put a tail on her and i have been carrying out a few background checks of my own. like you i found little to raise my suspicions, and, given her profession, there is nothing unusual about her being here in cairo. she seems to be well known, well liked, and most importantly, well trusted. if we had nothing else to go on i too would have written her off as a lead, however two days ago my agents lost track of her and she disappeared.\n",
+      "we ran all the usual checks and found her in cleopatra hospital, recovering from an assault. the local station procured credentials and cover for me as a local detective and i carried out a standard field interview which has given us a headstart on the investigation. jodie's misfortune is my luck.\n",
+      "she is here to track down a document apparently written by the roman historian tacitus. the hunt for the book started when someone found a document in the vatican library written by la touret. it included extracts from a latin document that appeared to be an edited version of the agricola and jodie tells me that the style was recognisably tacitus, and some of the sentences were the same as known versions of the original. however there were a few significant changes and jodie travelled to rome to search for more. in the archives she found tacitus’ deathbed confession which referred to a document so shocking that tacitus himself had ordered it to be split up and concealed across a number of sites in the ancient world. no clues were given to the nature of the sites, but the document concluded with the statement “my legacy will be a truth which outlasts the mountain of gods which guards its gateway“. this led jodie to suspect that the pyramids at giza were a good place to start. that was where she was attacked.\n",
+      "it took jodie three days to find the document hidden among the stones, and my guess is that someone was watching her until she found it late on the third day. she only had it for five minutes before she was robbed, but she made the most of that time, photographing the fragment. the attackers took her phone, but the image had already uploaded to the cloud, so at least we know what it said. perhaps more importantly we may have another clue to the location of the next fragment, “the full truth must remain hidden for now, and as remarked by my trusted slave and confidant tiro, what better place to hide a book than among books?”\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(keyword_decipher(ca, key_word, key_wrap))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2530"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('2a.plaintext', 'w').write(keyword_decipher(ca, key_word, key_wrap))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(0, -2059.063429379348)"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score = caesar_break(cb)\n",
+    "key_b, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'tel uutrfetnehioyitbephn da he i ood rul tie rate fre haedugsioafdeiielcgn esr pine oe reo on rhftodcrdvlsrvtdbtm moss an fnsrwturawteernofgvp uhehloastieeaooenxih btn rees tv armed hb lccelrocshnpicctvvbu a esd adam a at ids neat res at mwr oitdteoafutoteeiltiu song lro a ae alle of lts htnirwtalnrdornnef sort y ont frith lee doer do i gewitneeyolivmedttud are on du th gti set tfbrosfnrtmrutlkwg to dinu do by rfr deot tut see e ov yeeeah yau at fdot a i at rec ihfnhpaouerseselupsh lsr to wcg to eu to at raoeceyvteeeiadesmaw aetna ihieysrlemritmtchrei or nh et stop eeg mhi hau at bal of uno ho is hceoirnsdgasbboohaes ileaigageefiwgtyhwuh tue ruts held ei on oe fniienhosasnoueiytih net tsnfbsueihossiurdenl md oh yom re a as i wst gmt nrao ocmfihlnaedcariwrrd tel nsgjerurncsoegttlfca a tri rels sri do eeo ssi knuth ndt ltnribbaadsehyetppbo am thd neg epic nj chf ciypiuireectlsdewodc ter fi set et dnntgabopgsenlaaodc bed htrmoelrserruuevstrw id ftb as bott tah wear o lori bnc kg mft to cree vt seb nmr ur heed see sioylsioeuoioroubtao cneacaadlttnndeobeea niue yu cee dc no in ich mm tte oyaauwerodolstiiheiy pro hltvoueeoisdpuoiohlr hla iaea du loel pepa ahnohtarnuiibcdtsh set uaihulalcnooefawo an rene hhreuvecfdoidotrwlrr tslsa iv uta ebi i hi a heat scc we sdetwihntehettuuohh teidvttereoybcsttehh need tart to dau maes gaed muurveoxnssftnnmiehn note to svbolrhwebuentvdsrs cleb gats us do to a ihl nst nish doo a lee hon rsc pstn i this pdb nc soes ft nei see sebi wtewuretnyltaadeutdd noce ruh a edie le marino c insmod an few si see ocle lroefcldhiaatihoeaw der hls etna cyan mhoaihtftahacoehaes lrtwkeodnltehhonbnqo at hhaeltnjbrnihutinltz ctrn copes mag flo en tures n led an env n he an i eio set r the hm faa co arni uri guoesneeethdntuowpg afc eng us ie it esoeosrtebcefrnhutr fiigs das ah pate due retd berr tec in hey serr end is sdet dmo css pres gei eu ups erath ferfbceoacsmhsefgq at eaettlwttoavteefepao aol as oee et to ie i int fay lo lee fs'"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "wcat(segment(sanitise(caesar_decipher(cb, key_b))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "((1, 0, True), -2059.063429379348)"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(m_b, a_b, o_b), score = affine_break(cb)\n",
+    "(m_b, a_b, o_b), score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "teluutrfetnehioyitbephndaheioodrultieratefrehaedugsioafdeiielcgnesrpineoereoonrhftodcrdvlsrvtdbtmmossanfnsrwturawteernofgvpuhehloastieeaooenxihbtnreestvarmedhblccelrocshnpicctvvbuaesdadamaatidsneatresatmwroitdteoafutoteeiltiusonglroaaealleofltshtnirwtalnrdornnefsortyontfrithleedoerdoigewitneeyolivmedttudareonduthgtisettfbrosfnrtmrutlkwgtodinudobyrfrdeottutseeeovyeeeahyauatfdotaiatrecihfnhpaouerseselupshlsrtowcgtoeutoatraoeceyvteeeiadesmawaetnaihieysrlemritmtchreiornhetstopeegmhihauatbalofunohoishceoirnsdgasbboohaesileaigageefiwgtyhwuhtuerutsheldeionoefniienhosasnoueiytihnettsnfbsueihossiurdenlmdohyomreaasiwstgmtnraoocmfihlnaedcariwrrdtelnsgjerurncsoegttlfcaatrirelssridoeeossiknuthndtltnribbaadsehyetppboamthdnegepicnjchfciypiuireectlsdewodcterfisetetdnntgabopgsenlaaodcbedhtrmoelrserruuevstrwidftbasbotttahwearoloribnckgmfttocreevtsebnmrurheedseesioylsioeuoioroubtaocneacaadlttnndeobeeaniueyuceedcnoinichmmtteoyaauwerodolstiiheiyprohltvoueeoisdpuoiohlrhlaiaeaduloelpepaahnohtarnuiibcdtshsetuaihulalcnooefawoanrenehhreuvecfdoidotrwlrrtslsaivutaebiihiaheatsccwesdetwihntehettuuohhteidvttereoybcsttehhneedtarttodaumaesgaedmuurveoxnssftnnmiehnnotetosvbolrhwebuentvdsrsclebgatsusdotoaihlnstnishdooaleehonrscpstnithispdbncsoesftneiseesebiwtewuretnyltaadeutddnoceruhaedielemarinocinsmodanfewsiseeoclelroefcldhiaatihoeawderhlsetnacyanmhoaihtftahacoehaeslrtwkeodnltehhonbnqoathhaeltnjbrnihutinltzctrncopesmagfloenturesnledanenvnheanieiosetrthehmfaacoarniuriguoesneeethdntuowpgafcengusieitesoeosrtebcefrnhutrfiigsdasahpatedueretdberrtecinheyserrendissdetdmocsspresgeieuupserathferfbceoacsmhsefgqateaettlwttoavteefepaoaolasoeeettoieiintfayloleefs\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(affine_decipher(sanitise(cb), m_b, a_b, o_b))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "teluutrfet\n",
+      "hleedoerdo\n",
+      "eldeionoef\n",
+      "ribnckgmft\n",
+      "eoybcstteh\n",
+      "bnqoathhae\n"
+     ]
+    }
+   ],
+   "source": [
+    "for r in cb.split('\\n'):\n",
+    "    print(sanitise(r)[:10])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "the rebellion led by queen boudicca took strength from the defeat of the ninth legion the iceni were\n",
+      "joined by the trinovantes tribe as they setup on both londinium and verulam ium they razed the\n",
+      "cities to the ground and desecrated our temples suetonius informed by varus legatus of the ix legion\n",
+      "of the seriousness of the situation returned from subduing rebels on the island of mona and\n",
+      "confronted the enemy at viro conium a she travelled back along watling street in his own words\n",
+      "despite being outnumbered ten to one the bravery and heroism of our forces and my careful choice of\n",
+      "the battleground and tactics ensured our decisive and glorious victory whoever masterminded the\n",
+      "battle the enemy lost many thousands against just a few hundred of our own troops and agricola was\n",
+      "left to secure the region acting with ruthless efficiency perhaps in part to at one for his guilt\n",
+      "over the previous loss he supressed the rebellion boudicca possessed of the perilous ness of her\n",
+      "situation took her own life cursing the ixth legion as she died but a battle is not a war and the\n",
+      "true peril was about to be revealed a captured enemy spy revealed that they had be enable to\n",
+      "decipher captured battle orders and communications which had been encrypted using the caesar cipher\n",
+      "this device invented by julius caesar himself had secured military and diplomatic communications\n",
+      "across the empire for decades it was no longer safe and neither were we suetonius s despatches to\n",
+      "the emperor were careful to give himself the credit for the defeat of boudicca and left no doubt\n",
+      "that agricola was to blame for the uprising the loss of the legions aquila was said to have\n",
+      "encouraged the local tribes to rebel and it was hinted that agricola may also have been to blame for\n",
+      "the loss of the caesar cipher what suetonius failed to reveal was that it was agricola who\n",
+      "engineered the defeat of the tribes on watling street but if you wish to know the truth of that day\n",
+      "then you will need to travel further to the isle of thorns\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(cat(cat(zr) for zr in zip(*[sanitise(r) for r in cb.split('\\n')]))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "274"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(sanitise(cb.split('\\n')[0]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "6"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(cb.split('\\n'))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "the rebellion led by queen boudicca took strength from the defeat of the ninth legion the iceni were\n",
+      "joined by the trinovantes tribe as they setup on both londinium and verulam ium they razed the\n",
+      "cities to the ground and desecrated our temples suetonius informed by varus legatus of the ix legion\n",
+      "of the seriousness of the situation returned from subduing rebels on the island of mona and\n",
+      "confronted the enemy at viro conium a she travelled back along watling street in his own words\n",
+      "despite being outnumbered ten to one the bravery and heroism of our forces and my careful choice of\n",
+      "the battleground and tactics ensured our decisive and glorious victory whoever masterminded the\n",
+      "battle the enemy lost many thousands against just a few hundred of our own troops and agricola was\n",
+      "left to secure the region acting with ruthless efficiency perhaps in part to at one for his guilt\n",
+      "over the previous loss he supressed the rebellion boudicca possessed of the perilous ness of her\n",
+      "situation took her own life cursing the ixth legion as she died but a battle is not a war and the\n",
+      "true peril was about to be revealed a captured enemy spy revealed that they had be enable to\n",
+      "decipher captured battle orders and communications which had been encrypted using the caesar cipher\n",
+      "this device invented by julius caesar himself had secured military and diplomatic communications\n",
+      "across the empire for decades it was no longer safe and neither were we suetonius s despatches to\n",
+      "the emperor were careful to give himself the credit for the defeat of boudicca and left no doubt\n",
+      "that agricola was to blame for the uprising the loss of the legions aquila was said to have\n",
+      "encouraged the local tribes to rebel and it was hinted that agricola may also have been to blame for\n",
+      "the loss of the caesar cipher what suetonius failed to reveal was that it was agricola who\n",
+      "engineered the defeat of the tribes on watling street but if you wish to know the truth of that day\n",
+      "then you will need to travel further to the isle of thorns\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(column_transposition_decipher(sanitise(cb), \n",
+    "                                           tuple(range(274)), \n",
+    "                                           fillcolumnwise=True, \n",
+    "                                           emptycolumnwise=False)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "the rebellion led by queen boudicca took strength from the defeat of the ninth legion the iceni were\n",
+      "joined by the trinovantes tribe as they setup on both londinium and verulam ium they razed the\n",
+      "cities to the ground and desecrated our temples suetonius informed by varus legatus of the ix legion\n",
+      "of the seriousness of the situation returned from subduing rebels on the island of mona and\n",
+      "confronted the enemy at viro conium a she travelled back along watling street in his own words\n",
+      "despite being outnumbered ten to one the bravery and heroism of our forces and my careful choice of\n",
+      "the battleground and tactics ensured our decisive and glorious victory whoever masterminded the\n",
+      "battle the enemy lost many thousands against just a few hundred of our own troops and agricola was\n",
+      "left to secure the region acting with ruthless efficiency perhaps in part to at one for his guilt\n",
+      "over the previous loss he supressed the rebellion boudicca possessed of the perilous ness of her\n",
+      "situation took her own life cursing the ixth legion as she died but a battle is not a war and the\n",
+      "true peril was about to be revealed a captured enemy spy revealed that they had be enable to\n",
+      "decipher captured battle orders and communications which had been encrypted using the caesar cipher\n",
+      "this device invented by julius caesar himself had secured military and diplomatic communications\n",
+      "across the empire for decades it was no longer safe and neither were we suetonius s despatches to\n",
+      "the emperor were careful to give himself the credit for the defeat of boudicca and left no doubt\n",
+      "that agricola was to blame for the uprising the loss of the legions aquila was said to have\n",
+      "encouraged the local tribes to rebel and it was hinted that agricola may also have been to blame for\n",
+      "the loss of the caesar cipher what suetonius failed to reveal was that it was agricola who\n",
+      "engineered the defeat of the tribes on watling street but if you wish to know the truth of that day\n",
+      "then you will need to travel further to the isle of thorns\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(column_transposition_decipher(sanitise(cb), \n",
+    "                                           tuple(range(6)), \n",
+    "                                           fillcolumnwise=False, \n",
+    "                                           emptycolumnwise=True)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1999"
+      ]
+     },
+     "execution_count": 24,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('2b.plaintext', 'w').write(prettify(column_transposition_decipher(sanitise(cb), \n",
+    "                                           tuple(range(274)), \n",
+    "                                           fillcolumnwise=True, \n",
+    "                                           emptycolumnwise=False)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/2017/2017-challenge3.ipynb b/2017/2017-challenge3.ipynb
new file mode 100644 (file)
index 0000000..29b37cf
--- /dev/null
@@ -0,0 +1,1720 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import os,sys,inspect, collections\n",
+    "currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))\n",
+    "parentdir = os.path.dirname(currentdir)\n",
+    "sys.path.insert(0,parentdir) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.caesar import *\n",
+    "from cipher.affine import *\n",
+    "from cipher.polybius import *\n",
+    "from support.text_prettify import *\n",
+    "from support.language_models import *\n",
+    "\n",
+    "ca = open('3a.ciphertext').read()\n",
+    "cb = open('3b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(24, -2521.8122372384537)"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score = caesar_break(ca)\n",
+    "key_a, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "KETQEK,\n",
+      "I HBYOUBH AYKG KYTG ELYOH CBEH QYO AEIZ IR HBG BYAFIHED, ERZ UIVGR CBEH BEA BEFFGRGZ I HBIRW I IH CYODZ LG UYYZ HY CYTW HYUGHBGT.\n",
+      "\n",
+      "ORNYTHOREHGDQ IH AGGKA HBEH I EK RYH HBG YRDQ YRG HTQIRU HY NIRZ HBG LYYW. HBGTG IA E HBTIVIRU LDESW KETWGH EKYRU LILDIYFBIDGA NYT ERQHBIRU EA YDZ EA HBIA. IH IA VGTQ VEDOELDG ERZ IN HBG LYYW ZIAEFFGETA IRHY HBG ABEZYCQ CYTDZ YN FTIVEHG DILTETIGA CG KIUBH RYH AGG IH EUEIR NYT SGRHOTIGA AY IH IA TGEDDQ IKFYTHERH CG UGH HY IH NITAH.\n",
+      "\n",
+      "HESIHOA SDGETDQ CERHGZ HY KEWG IH ZINNISODH HY EAAGKLDG HBG GRHITG ZYSOKGRH, AY BG BEZ IH BIZZGR EH E ROKLGT YN AIHGA ETYORZ HBG ERSIGRH CYTDZ. HBG LTIHIAB DILTETQ ZGSIZGZ HY AGRZ AYKGYRG HY HTQ HY NIRZ EDD HBG FIGSGA. HBGIT GJFGTHA NIUOTGZ HBG SBEFHGTA CGTG DIWGDQ HY LG GRSTQFHGZ HYY AY, UIVGR KQ LESWUTYORZ, HBGQ EAWGZ KG HY UY. HBGQ CGTG TIUBH YN SYOTAG, HBG NITAH SBEFHGT CEA ZIAUOIAGZ OAIRU E SEGAET ABINH ERZ HBG AGSYRZ LQ E ASQHEDG SIFBGT, ERZ I EK LGUIRRIRU HY CYRZGT CBEH YHBGT SIFBGTA HESIHOA KIUBH SBEDDGRUG OA CIHB. EA NET EA CG WRYC HBG TYKERA CYODZ RYH BEVG BEZ HBEH KERQ HY SBYYAG NTYK. I AOFFYAG BG KIUBH BEVG WRYCR ELYOH AYKG NYTK YN HBG FYDQLIOA SIFBGT.\n",
+      "\n",
+      "HBG ZYSOKGRHA I BEVG NYORZ AY NET (HESIHOA DEAH HGAHEKGRH ERZ SBEFHGTA YRG ERZ HCY YN BIA BIZZGR LYYW) GESB UIVG E SDOG HY HBG DYSEHIYR YN HBG RGJH YRG, ERZ EA AYYR EA HBGQ DGH KG YOH YN BYAFIHED I FDER HY HTQ HY DYSEHG HBG HBITZ SBEFHGT, CBISB HESIHOA HGDDA OA IA BIZZGR YR HBG IADG YN HBYTRA. HBGTG ETG AGVGTED FDESGA IR HBG ERSIGRH CYTDZ HBEH HBIA KIUBH TGNGT HY, LOH I BEVG E FTGHHQ UYYZ IZGE YN CBGTG IH KIUBH LG.\n",
+      "\n",
+      "IN I HBIRW YN ERQHBIRU GDAG I CIDD UGH IH HY QYO, ERZ EA TGMOGAHGZ I CIDD SYFQ IR QYOT NTIGRZ BETTQ. I AOUUGAH CG HIUBHGR AGSOTIHQ E DIHHDG. KEQLG IN CG LDYSW YOT SIFBGT HGJHA DIWG HBG GJFGTHA IH CIDD FOH YNN SEAOED IRHGTSGFHA. HBG FGYFDG CG ETG OF EUEIRAH ETG ORDIWGDQ HY LG ZGHGTTGZ LQ KOSB, LOH CG ZYR'H CERH HY IRVIHG GJHTE IRHGTDYFGTA HY HBG FETHQ.\n",
+      "\n",
+      "LQ HBG CEQ, KQ NTIGRZ IR HBG AYOW HYDZ KG HBEH BG KGH YRG YN QYOT EUGRHA CBY CEA EAWIRU IN BG WRGC CBGTG I CEA, CBISB AGGKA E LIH YZZ UIVGR HBEH QYO WRYC I EK AHOSW BGTG. CEA HBEH POAH HY HBTYC YOT TIVEDA YNN HBG ASGRH?\n",
+      "\n",
+      "EDD HBG LGAH,\n",
+      "\n",
+      "PYZIG\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(caesar_decipher(ca, key_a))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "((7, 22, True), -2146.240223193519)"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(m_a, a_a, o_a), score = affine_break(ca)\n",
+    "(m_a, a_a, o_a), score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "MARYAM,\n",
+      "I THOUGHT SOME MORE ABOUT WHAT YOU SAID IN THE HOSPITAL, AND GIVEN WHAT HAS HAPPENED I THINK I IT WOULD BE GOOD TO WORK TOGETHER.\n",
+      "\n",
+      "UNFORTUNATELY IT SEEMS THAT I AM NOT THE ONLY ONE TRYING TO FIND THE BOOK. THERE IS A THRIVING BLACK MARKET AMONG BIBLIOPHILES FOR ANYTHING AS OLD AS THIS. IT IS VERY VALUABLE AND IF THE BOOK DISAPPEARS INTO THE SHADOWY WORLD OF PRIVATE LIBRARIES WE MIGHT NOT SEE IT AGAIN FOR CENTURIES SO IT IS REALLY IMPORTANT WE GET TO IT FIRST.\n",
+      "\n",
+      "TACITUS CLEARLY WANTED TO MAKE IT DIFFICULT TO ASSEMBLE THE ENTIRE DOCUMENT, SO HE HAD IT HIDDEN AT A NUMBER OF SITES AROUND THE ANCIENT WORLD. THE BRITISH LIBRARY DECIDED TO SEND SOMEONE TO TRY TO FIND ALL THE PIECES. THEIR EXPERTS FIGURED THE CHAPTERS WERE LIKELY TO BE ENCRYPTED TOO SO, GIVEN MY BACKGROUND, THEY ASKED ME TO GO. THEY WERE RIGHT OF COURSE, THE FIRST CHAPTER WAS DISGUISED USING A CAESAR SHIFT AND THE SECOND BY A SCYTALE CIPHER, AND I AM BEGINNING TO WONDER WHAT OTHER CIPHERS TACITUS MIGHT CHALLENGE US WITH. AS FAR AS WE KNOW THE ROMANS WOULD NOT HAVE HAD THAT MANY TO CHOOSE FROM. I SUPPOSE HE MIGHT HAVE KNOWN ABOUT SOME FORM OF THE POLYBIUS CIPHER.\n",
+      "\n",
+      "THE DOCUMENTS I HAVE FOUND SO FAR (TACITUS LAST TESTAMENT AND CHAPTERS ONE AND TWO OF HIS HIDDEN BOOK) EACH GIVE A CLUE TO THE LOCATION OF THE NEXT ONE, AND AS SOON AS THEY LET ME OUT OF HOSPITAL I PLAN TO TRY TO LOCATE THE THIRD CHAPTER, WHICH TACITUS TELLS US IS HIDDEN ON THE ISLE OF THORNS. THERE ARE SEVERAL PLACES IN THE ANCIENT WORLD THAT THIS MIGHT REFER TO, BUT I HAVE A PRETTY GOOD IDEA OF WHERE IT MIGHT BE.\n",
+      "\n",
+      "IF I THINK OF ANYTHING ELSE I WILL GET IT TO YOU, AND AS REQUESTED I WILL COPY IN YOUR FRIEND HARRY. I SUGGEST WE TIGHTEN SECURITY A LITTLE. MAYBE IF WE BLOCK OUR CIPHER TEXTS LIKE THE EXPERTS IT WILL PUT OFF CASUAL INTERCEPTS. THE PEOPLE WE ARE UP AGAINST ARE UNLIKELY TO BE DETERRED BY MUCH, BUT WE DON'T WANT TO INVITE EXTRA INTERLOPERS TO THE PARTY.\n",
+      "\n",
+      "BY THE WAY, MY FRIEND IN THE SOUK TOLD ME THAT HE MET ONE OF YOUR AGENTS WHO WAS ASKING IF HE KNEW WHERE I WAS, WHICH SEEMS A BIT ODD GIVEN THAT YOU KNOW I AM STUCK HERE. WAS THAT JUST TO THROW OUR RIVALS OFF THE SCENT?\n",
+      "\n",
+      "ALL THE BEST,\n",
+      "\n",
+      "JODIE\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(affine_decipher(ca, m_a, a_a, o_a))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2163"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('3a.plaintext', 'w').write(affine_decipher(ca, m_a, a_a, o_a))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "Counter({'c': 1064, 'd': 1368, 'l': 756, 'm': 566, 'x': 1092})"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "collections.Counter(sanitise(cb))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[('xm', 317),\n",
+       " ('dd', 240),\n",
+       " ('xx', 197),\n",
+       " ('ld', 185),\n",
+       " ('cd', 177),\n",
+       " ('dl', 159),\n",
+       " ('dc', 155),\n",
+       " ('cc', 154),\n",
+       " ('lc', 133),\n",
+       " ('xd', 105),\n",
+       " ('cx', 92),\n",
+       " ('xc', 88),\n",
+       " ('dm', 70),\n",
+       " ('cl', 58),\n",
+       " ('ml', 51),\n",
+       " ('cm', 48),\n",
+       " ('ll', 45),\n",
+       " ('lx', 41),\n",
+       " ('md', 36),\n",
+       " ('xl', 27),\n",
+       " ('mx', 27),\n",
+       " ('lm', 12),\n",
+       " ('mc', 5),\n",
+       " ('dx', 1)]"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "collections.Counter(chunks(sanitise(cb), 2)).most_common()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'etoainhsrdlumwycfgpbvkxqz'"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ltrs = [p[0] for p in english_counts.most_common() if p[0] != 'j']\n",
+    "cat(ltrs)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'etoanisrhdlufcmwgybpvkxqz'"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ltrs = cat(p[0] for p in \n",
+    "           collections.Counter(sanitise(open('1b.plaintext').read() + open('2b.plaintext').read())).most_common()\n",
+    "          if p[0] != 'j')\n",
+    "ltrs"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ltrs = 'etoanisrhdlufcmwgybpvkxqz'"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['xm',\n",
+       " 'dd',\n",
+       " 'xx',\n",
+       " 'ld',\n",
+       " 'cd',\n",
+       " 'dl',\n",
+       " 'dc',\n",
+       " 'cc',\n",
+       " 'lc',\n",
+       " 'xd',\n",
+       " 'cx',\n",
+       " 'xc',\n",
+       " 'dm',\n",
+       " 'cl',\n",
+       " 'ml',\n",
+       " 'cm',\n",
+       " 'll',\n",
+       " 'lx',\n",
+       " 'md',\n",
+       " 'xl',\n",
+       " 'mx',\n",
+       " 'lm',\n",
+       " 'mc',\n",
+       " 'dx']"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "prs =  [p[0] for p in collections.Counter(chunks(sanitise(cb), 2)).most_common()]\n",
+    "prs"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "24"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(prs)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'cc': 'R',\n",
+       " 'cd': 'N',\n",
+       " 'cl': 'C',\n",
+       " 'cm': 'W',\n",
+       " 'cx': 'L',\n",
+       " 'dc': 'S',\n",
+       " 'dd': 'T',\n",
+       " 'dl': 'I',\n",
+       " 'dm': 'F',\n",
+       " 'dx': 'Q',\n",
+       " 'lc': 'H',\n",
+       " 'ld': 'A',\n",
+       " 'll': 'G',\n",
+       " 'lm': 'K',\n",
+       " 'lx': 'Y',\n",
+       " 'mc': 'X',\n",
+       " 'md': 'B',\n",
+       " 'ml': 'M',\n",
+       " 'mx': 'V',\n",
+       " 'xc': 'U',\n",
+       " 'xd': 'D',\n",
+       " 'xl': 'P',\n",
+       " 'xm': 'E',\n",
+       " 'xx': 'O'}"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "trans = {pr[1]: pr[0].upper() for pr in zip(ltrs, prs)}\n",
+    "trans"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['ml',\n",
+       " 'lc',\n",
+       " 'ld',\n",
+       " 'cx',\n",
+       " 'xm',\n",
+       " 'ld',\n",
+       " 'dd',\n",
+       " 'ld',\n",
+       " 'dc',\n",
+       " 'dd',\n",
+       " 'dl',\n",
+       " 'dm',\n",
+       " 'xm',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xx',\n",
+       " 'dd',\n",
+       " 'dc',\n",
+       " 'dm',\n",
+       " 'xm',\n",
+       " 'dd',\n",
+       " 'cd',\n",
+       " 'cc',\n",
+       " 'ld',\n",
+       " 'dm',\n",
+       " 'dc',\n",
+       " 'dc',\n",
+       " 'xm',\n",
+       " 'dd',\n",
+       " 'dm',\n",
+       " 'cm',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xm',\n",
+       " 'lx',\n",
+       " 'ld',\n",
+       " 'cc',\n",
+       " 'xx',\n",
+       " 'cx',\n",
+       " 'xl',\n",
+       " 'xx',\n",
+       " 'dd',\n",
+       " 'dd',\n",
+       " 'cx',\n",
+       " 'xm',\n",
+       " 'ml',\n",
+       " 'ld',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xl',\n",
+       " 'cd',\n",
+       " 'dm',\n",
+       " 'xd',\n",
+       " 'ld',\n",
+       " 'xc',\n",
+       " 'xc',\n",
+       " 'xx',\n",
+       " 'xx',\n",
+       " 'dd',\n",
+       " 'ml',\n",
+       " 'xx',\n",
+       " 'dd',\n",
+       " 'cx',\n",
+       " 'ld',\n",
+       " 'cc',\n",
+       " 'll',\n",
+       " 'dc',\n",
+       " 'dd',\n",
+       " 'dl',\n",
+       " 'xm',\n",
+       " 'xm',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xm',\n",
+       " 'lc',\n",
+       " 'xx',\n",
+       " 'xd',\n",
+       " 'cc',\n",
+       " 'xm',\n",
+       " 'ld',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xm',\n",
+       " 'dl',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xm',\n",
+       " 'dd',\n",
+       " 'dl',\n",
+       " 'cd',\n",
+       " 'cd',\n",
+       " 'cm',\n",
+       " 'dc',\n",
+       " 'cc',\n",
+       " 'cd',\n",
+       " 'dl',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xm',\n",
+       " 'dd',\n",
+       " 'xx',\n",
+       " 'xc',\n",
+       " 'dd',\n",
+       " 'ld',\n",
+       " 'xc',\n",
+       " 'xx',\n",
+       " 'cx',\n",
+       " 'xx',\n",
+       " 'xl',\n",
+       " 'ld',\n",
+       " 'cx',\n",
+       " 'ld',\n",
+       " 'dd',\n",
+       " 'md',\n",
+       " 'dd',\n",
+       " 'cd',\n",
+       " 'cd',\n",
+       " 'mx',\n",
+       " 'xm',\n",
+       " 'dl',\n",
+       " 'xc',\n",
+       " 'cd',\n",
+       " 'cl',\n",
+       " 'xm',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xm',\n",
+       " 'lc',\n",
+       " 'dm',\n",
+       " 'll',\n",
+       " 'xm',\n",
+       " 'cc',\n",
+       " 'dm',\n",
+       " 'cl',\n",
+       " 'xm',\n",
+       " 'dl',\n",
+       " 'ld',\n",
+       " 'xc',\n",
+       " 'xx',\n",
+       " 'cx',\n",
+       " 'xd',\n",
+       " 'ld',\n",
+       " 'dc',\n",
+       " 'xx',\n",
+       " 'xd',\n",
+       " 'mx',\n",
+       " 'xx',\n",
+       " 'cc',\n",
+       " 'dd',\n",
+       " 'xx',\n",
+       " 'll',\n",
+       " 'xm',\n",
+       " 'lx',\n",
+       " 'xx',\n",
+       " 'xc',\n",
+       " 'xm',\n",
+       " 'xd',\n",
+       " 'xl',\n",
+       " 'md',\n",
+       " 'lc',\n",
+       " 'ld',\n",
+       " 'dc',\n",
+       " 'xx',\n",
+       " 'dl',\n",
+       " 'cl',\n",
+       " 'md',\n",
+       " 'ml',\n",
+       " 'ld',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'cd',\n",
+       " 'dm',\n",
+       " 'dd',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xm',\n",
+       " 'dc',\n",
+       " 'dm',\n",
+       " 'cm',\n",
+       " 'cm',\n",
+       " 'cd',\n",
+       " 'dl',\n",
+       " 'dd',\n",
+       " 'cd',\n",
+       " 'lx',\n",
+       " 'xx',\n",
+       " 'll',\n",
+       " 'dl',\n",
+       " 'ld',\n",
+       " 'xc',\n",
+       " 'cd',\n",
+       " 'cx',\n",
+       " 'xx',\n",
+       " 'xx',\n",
+       " 'cc',\n",
+       " 'xd',\n",
+       " 'lc',\n",
+       " 'ld',\n",
+       " 'dc',\n",
+       " 'dd',\n",
+       " 'xx',\n",
+       " 'cx',\n",
+       " 'xm',\n",
+       " 'cc',\n",
+       " 'dd',\n",
+       " 'xm',\n",
+       " 'xd',\n",
+       " 'dc',\n",
+       " 'xc',\n",
+       " 'cd',\n",
+       " 'dm',\n",
+       " 'dd',\n",
+       " 'dc',\n",
+       " 'xd',\n",
+       " 'xm',\n",
+       " 'lx',\n",
+       " 'xm',\n",
+       " 'xx',\n",
+       " 'dd',\n",
+       " 'ml',\n",
+       " 'cd',\n",
+       " 'dm',\n",
+       " 'cx',\n",
+       " 'xd',\n",
+       " 'lc',\n",
+       " 'xx',\n",
+       " 'mx',\n",
+       " 'xm',\n",
+       " 'xl',\n",
+       " 'xm',\n",
+       " 'xm',\n",
+       " 'cc',\n",
+       " 'ld',\n",
+       " 'cc',\n",
+       " 'xm',\n",
+       " 'mx',\n",
+       " 'ld',\n",
+       " 'dd',\n",
+       " 'xx',\n",
+       " 'xl',\n",
+       " 'cx',\n",
+       " 'xm',\n",
+       " 'xx',\n",
+       " 'cc',\n",
+       " 'xd',\n",
+       " 'ml',\n",
+       " 'ld',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'ld',\n",
+       " 'dd',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xm',\n",
+       " 'cx',\n",
+       " 'cd',\n",
+       " 'dc',\n",
+       " 'dc',\n",
+       " 'cd',\n",
+       " 'lx',\n",
+       " 'xl',\n",
+       " 'dl',\n",
+       " 'ld',\n",
+       " 'dd',\n",
+       " 'xx',\n",
+       " 'cc',\n",
+       " 'cc',\n",
+       " 'ld',\n",
+       " 'xx',\n",
+       " 'lc',\n",
+       " 'xx',\n",
+       " 'mx',\n",
+       " 'ld',\n",
+       " 'cc',\n",
+       " 'll',\n",
+       " 'dl',\n",
+       " 'xm',\n",
+       " 'xx',\n",
+       " 'cx',\n",
+       " 'ld',\n",
+       " 'dc',\n",
+       " 'xm',\n",
+       " 'xd',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xx',\n",
+       " 'dd',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xm',\n",
+       " 'ld',\n",
+       " 'xc',\n",
+       " 'xm',\n",
+       " 'cc',\n",
+       " 'ld',\n",
+       " 'ml',\n",
+       " 'xm',\n",
+       " 'dl',\n",
+       " 'xm',\n",
+       " 'dl',\n",
+       " 'xm',\n",
+       " 'xx',\n",
+       " 'xd',\n",
+       " 'ld',\n",
+       " 'cc',\n",
+       " 'll',\n",
+       " 'lc',\n",
+       " 'ld',\n",
+       " 'dc',\n",
+       " 'xc',\n",
+       " 'cd',\n",
+       " 'cl',\n",
+       " 'cl',\n",
+       " 'dm',\n",
+       " 'cc',\n",
+       " 'ld',\n",
+       " 'xc',\n",
+       " 'xx',\n",
+       " 'dd',\n",
+       " 'ld',\n",
+       " 'cd',\n",
+       " 'cc',\n",
+       " 'dc',\n",
+       " 'xx',\n",
+       " 'll',\n",
+       " 'dl',\n",
+       " 'ld',\n",
+       " 'xc',\n",
+       " 'cd',\n",
+       " 'cx',\n",
+       " 'xx',\n",
+       " 'xx',\n",
+       " 'dl',\n",
+       " 'dl',\n",
+       " 'xx',\n",
+       " 'cc',\n",
+       " 'll',\n",
+       " 'xm',\n",
+       " 'xd',\n",
+       " 'dd',\n",
+       " 'cd',\n",
+       " 'cm',\n",
+       " 'cx',\n",
+       " 'xx',\n",
+       " 'cc',\n",
+       " 'dd',\n",
+       " 'lx',\n",
+       " 'xx',\n",
+       " 'cx',\n",
+       " 'dc',\n",
+       " 'xm',\n",
+       " 'ld',\n",
+       " 'cc',\n",
+       " 'lx',\n",
+       " 'cd',\n",
+       " 'dl',\n",
+       " 'cl',\n",
+       " 'xx',\n",
+       " 'dd',\n",
+       " 'ld',\n",
+       " 'cd',\n",
+       " 'cc',\n",
+       " 'xx',\n",
+       " 'xl',\n",
+       " 'cd',\n",
+       " 'dm',\n",
+       " 'dd',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xm',\n",
+       " 'cm',\n",
+       " 'cx',\n",
+       " 'xx',\n",
+       " 'cc',\n",
+       " 'cc',\n",
+       " 'xm',\n",
+       " 'xd',\n",
+       " 'xd',\n",
+       " 'ld',\n",
+       " 'dc',\n",
+       " 'cm',\n",
+       " 'cd',\n",
+       " 'dc',\n",
+       " 'ld',\n",
+       " 'dd',\n",
+       " 'ld',\n",
+       " 'cd',\n",
+       " 'cc',\n",
+       " 'cd',\n",
+       " 'lx',\n",
+       " 'dd',\n",
+       " 'dl',\n",
+       " 'cd',\n",
+       " 'cd',\n",
+       " 'cm',\n",
+       " 'dc',\n",
+       " 'dc',\n",
+       " 'xm',\n",
+       " 'dd',\n",
+       " 'dd',\n",
+       " 'ld',\n",
+       " 'cc',\n",
+       " 'll',\n",
+       " 'xx',\n",
+       " 'dd',\n",
+       " 'dl',\n",
+       " 'xx',\n",
+       " 'cm',\n",
+       " 'ld',\n",
+       " 'cc',\n",
+       " 'dd',\n",
+       " 'cd',\n",
+       " 'ml',\n",
+       " 'lc',\n",
+       " 'ld',\n",
+       " 'xc',\n",
+       " 'lc',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xm',\n",
+       " 'ld',\n",
+       " 'xc',\n",
+       " 'xm',\n",
+       " 'cc',\n",
+       " 'ld',\n",
+       " 'lx',\n",
+       " 'xm',\n",
+       " 'cx',\n",
+       " 'cx',\n",
+       " 'ld',\n",
+       " 'dd',\n",
+       " 'ld',\n",
+       " 'dc',\n",
+       " 'dc',\n",
+       " 'dd',\n",
+       " 'ld',\n",
+       " 'cx',\n",
+       " 'cx',\n",
+       " 'dm',\n",
+       " 'cc',\n",
+       " 'xc',\n",
+       " 'cx',\n",
+       " 'xm',\n",
+       " 'xx',\n",
+       " 'dl',\n",
+       " 'lc',\n",
+       " 'cd',\n",
+       " 'ml',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xm',\n",
+       " 'dc',\n",
+       " 'xx',\n",
+       " 'mx',\n",
+       " 'xx',\n",
+       " 'll',\n",
+       " 'xm',\n",
+       " 'dd',\n",
+       " 'dl',\n",
+       " 'ld',\n",
+       " 'xl',\n",
+       " 'xm',\n",
+       " 'dc',\n",
+       " 'lc',\n",
+       " 'xx',\n",
+       " 'xd',\n",
+       " 'cx',\n",
+       " 'xm',\n",
+       " 'xx',\n",
+       " 'dl',\n",
+       " 'cc',\n",
+       " 'xm',\n",
+       " 'xd',\n",
+       " 'dd',\n",
+       " 'cd',\n",
+       " 'xd',\n",
+       " 'xm',\n",
+       " 'xc',\n",
+       " 'ld',\n",
+       " 'cm',\n",
+       " 'lc',\n",
+       " 'xm',\n",
+       " 'dl',\n",
+       " 'cd',\n",
+       " 'dm',\n",
+       " 'dl',\n",
+       " 'xx',\n",
+       " 'dl',\n",
+       " 'cl',\n",
+       " 'md',\n",
+       " 'dc',\n",
+       " 'xc',\n",
+       " 'cd',\n",
+       " 'cl',\n",
+       " 'cl',\n",
+       " 'dm',\n",
+       " 'cc',\n",
+       " 'ld',\n",
+       " 'xc',\n",
+       " 'xx',\n",
+       " 'dd',\n",
+       " 'ld',\n",
+       " 'cd',\n",
+       " 'cc',\n",
+       " 'dc',\n",
+       " 'xx',\n",
+       " 'dc',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xm',\n",
+       " 'md',\n",
+       " 'lc',\n",
+       " 'xx',\n",
+       " 'xd',\n",
+       " 'cc',\n",
+       " 'cd',\n",
+       " 'ml',\n",
+       " 'dl',\n",
+       " 'ld',\n",
+       " 'dd',\n",
+       " 'ld',\n",
+       " 'cc',\n",
+       " 'll',\n",
+       " 'cd',\n",
+       " 'lx',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xm',\n",
+       " 'ld',\n",
+       " 'dl',\n",
+       " 'cd',\n",
+       " 'ml',\n",
+       " 'cc',\n",
+       " 'lc',\n",
+       " 'cd',\n",
+       " 'ml',\n",
+       " 'xm',\n",
+       " 'mx',\n",
+       " 'xm',\n",
+       " 'dl',\n",
+       " 'xm',\n",
+       " 'mx',\n",
+       " 'xm',\n",
+       " 'dl',\n",
+       " 'md',\n",
+       " 'xx',\n",
+       " 'dl',\n",
+       " 'cl',\n",
+       " 'md',\n",
+       " 'lc',\n",
+       " 'xx',\n",
+       " 'dc',\n",
+       " 'ld',\n",
+       " 'dd',\n",
+       " 'dc',\n",
+       " 'dd',\n",
+       " 'dl',\n",
+       " 'xx',\n",
+       " 'ld',\n",
+       " 'dd',\n",
+       " 'cd',\n",
+       " 'dl',\n",
+       " 'dc',\n",
+       " 'xx',\n",
+       " 'cc',\n",
+       " 'xd',\n",
+       " 'ld',\n",
+       " 'dd',\n",
+       " 'dc',\n",
+       " 'xm',\n",
+       " 'xm',\n",
+       " 'cl',\n",
+       " 'dc',\n",
+       " 'cx',\n",
+       " 'ld',\n",
+       " 'lm',\n",
+       " 'xm',\n",
+       " 'cx',\n",
+       " 'md',\n",
+       " 'dd',\n",
+       " 'cd',\n",
+       " 'cl',\n",
+       " 'xm',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xx',\n",
+       " 'dd',\n",
+       " 'cd',\n",
+       " 'cc',\n",
+       " 'xm',\n",
+       " 'cd',\n",
+       " 'dl',\n",
+       " 'cl',\n",
+       " 'cd',\n",
+       " 'dl',\n",
+       " 'xm',\n",
+       " 'cd',\n",
+       " 'lx',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xm',\n",
+       " 'cx',\n",
+       " 'cd',\n",
+       " 'xc',\n",
+       " 'xx',\n",
+       " 'cx',\n",
+       " 'dd',\n",
+       " 'dl',\n",
+       " 'ld',\n",
+       " 'xl',\n",
+       " 'xm',\n",
+       " 'dc',\n",
+       " 'cm',\n",
+       " 'xm',\n",
+       " 'cd',\n",
+       " 'cm',\n",
+       " 'cx',\n",
+       " 'xm',\n",
+       " 'dd',\n",
+       " 'dm',\n",
+       " 'dl',\n",
+       " 'cc',\n",
+       " 'xm',\n",
+       " 'xd',\n",
+       " 'dc',\n",
+       " 'cd',\n",
+       " 'cl',\n",
+       " 'xm',\n",
+       " 'cd',\n",
+       " 'cc',\n",
+       " 'xm',\n",
+       " 'dc',\n",
+       " 'lc',\n",
+       " 'xm',\n",
+       " 'xx',\n",
+       " 'xd',\n",
+       " 'cx',\n",
+       " 'cd',\n",
+       " 'mx',\n",
+       " 'xm',\n",
+       " 'cd',\n",
+       " 'dl',\n",
+       " 'cl',\n",
+       " 'cd',\n",
+       " 'cc',\n",
+       " 'xm',\n",
+       " 'md',\n",
+       " 'ld',\n",
+       " 'dd',\n",
+       " 'ld',\n",
+       " 'dc',\n",
+       " 'xx',\n",
+       " 'cx',\n",
+       " 'cx',\n",
+       " 'dd',\n",
+       " 'dl',\n",
+       " 'xm',\n",
+       " 'xx',\n",
+       " 'xc',\n",
+       " 'lc',\n",
+       " 'xm',\n",
+       " 'dl',\n",
+       " 'md',\n",
+       " 'xl',\n",
+       " 'dm',\n",
+       " 'dd',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'ld',\n",
+       " 'dc',\n",
+       " 'xx',\n",
+       " 'xc',\n",
+       " 'dd',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'dl',\n",
+       " 'xm',\n",
+       " 'xx',\n",
+       " 'dd',\n",
+       " 'xm',\n",
+       " 'cc',\n",
+       " 'xm',\n",
+       " 'xd',\n",
+       " 'dd',\n",
+       " 'cd',\n",
+       " 'dm',\n",
+       " 'cc',\n",
+       " 'xd',\n",
+       " 'xm',\n",
+       " 'dl',\n",
+       " 'cl',\n",
+       " 'ld',\n",
+       " 'cc',\n",
+       " 'xm',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xm',\n",
+       " 'xm',\n",
+       " 'cl',\n",
+       " 'cm',\n",
+       " 'ld',\n",
+       " 'dl',\n",
+       " 'xm',\n",
+       " 'dc',\n",
+       " 'xm',\n",
+       " 'cc',\n",
+       " 'dd',\n",
+       " 'ld',\n",
+       " 'dl',\n",
+       " 'xm',\n",
+       " 'dc',\n",
+       " 'md',\n",
+       " 'dc',\n",
+       " 'dd',\n",
+       " 'xm',\n",
+       " 'cl',\n",
+       " 'cd',\n",
+       " 'lx',\n",
+       " 'dc',\n",
+       " 'xm',\n",
+       " 'xc',\n",
+       " 'dm',\n",
+       " 'dl',\n",
+       " 'xm',\n",
+       " 'xc',\n",
+       " 'cd',\n",
+       " 'cl',\n",
+       " 'cl',\n",
+       " 'dm',\n",
+       " 'cc',\n",
+       " 'ld',\n",
+       " 'xc',\n",
+       " 'xx',\n",
+       " 'dd',\n",
+       " 'ld',\n",
+       " 'cd',\n",
+       " 'cc',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xm',\n",
+       " 'xc',\n",
+       " 'xx',\n",
+       " 'xm',\n",
+       " 'dc',\n",
+       " 'xx',\n",
+       " 'dl',\n",
+       " 'xc',\n",
+       " 'ld',\n",
+       " 'cm',\n",
+       " 'lc',\n",
+       " 'xm',\n",
+       " 'dl',\n",
+       " 'cm',\n",
+       " 'xm',\n",
+       " 'dl',\n",
+       " 'lc',\n",
+       " 'xx',\n",
+       " 'cm',\n",
+       " 'dc',\n",
+       " 'cl',\n",
+       " 'cd',\n",
+       " 'dl',\n",
+       " 'xm',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xx',\n",
+       " 'cc',\n",
+       " 'dl',\n",
+       " 'cd',\n",
+       " 'xx',\n",
+       " 'xd',\n",
+       " 'dc',\n",
+       " 'lc',\n",
+       " 'xx',\n",
+       " 'xd',\n",
+       " 'xm',\n",
+       " 'cc',\n",
+       " 'xx',\n",
+       " 'xl',\n",
+       " 'cx',\n",
+       " 'xm',\n",
+       " 'xd',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xm',\n",
+       " 'xm',\n",
+       " 'cl',\n",
+       " 'cm',\n",
+       " 'ld',\n",
+       " 'dl',\n",
+       " 'xm',\n",
+       " 'dd',\n",
+       " 'cd',\n",
+       " 'lx',\n",
+       " 'dm',\n",
+       " 'cc',\n",
+       " 'xc',\n",
+       " 'dd',\n",
+       " 'ld',\n",
+       " 'cd',\n",
+       " 'cc',\n",
+       " 'dc',\n",
+       " 'xm',\n",
+       " 'xc',\n",
+       " 'dm',\n",
+       " 'dl',\n",
+       " 'xm',\n",
+       " 'cx',\n",
+       " 'md',\n",
+       " 'xx',\n",
+       " 'cc',\n",
+       " 'xd',\n",
+       " 'ld',\n",
+       " 'dd',\n",
+       " 'dc',\n",
+       " 'cx',\n",
+       " 'cd',\n",
+       " 'dc',\n",
+       " 'dc',\n",
+       " 'ml',\n",
+       " 'xx',\n",
+       " 'dc',\n",
+       " 'xx',\n",
+       " 'xd',\n",
+       " 'ld',\n",
+       " 'dc',\n",
+       " 'xx',\n",
+       " 'dc',\n",
+       " 'dd',\n",
+       " 'xm',\n",
+       " 'dl',\n",
+       " 'dd',\n",
+       " 'dm',\n",
+       " 'dl',\n",
+       " 'cc',\n",
+       " 'ld',\n",
+       " 'cc',\n",
+       " 'll',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xx',\n",
+       " 'dd',\n",
+       " 'cx',\n",
+       " 'cd',\n",
+       " 'dc',\n",
+       " 'dc',\n",
+       " 'ld',\n",
+       " 'cc',\n",
+       " 'dd',\n",
+       " 'cd',\n",
+       " 'xx',\n",
+       " 'mx',\n",
+       " 'ld',\n",
+       " 'xc',\n",
+       " 'dd',\n",
+       " 'cd',\n",
+       " 'dl',\n",
+       " 'md',\n",
+       " 'cd',\n",
+       " 'cc',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xm',\n",
+       " 'xl',\n",
+       " 'xx',\n",
+       " 'dd',\n",
+       " 'dd',\n",
+       " 'cx',\n",
+       " 'xm',\n",
+       " 'lx',\n",
+       " 'ld',\n",
+       " 'xm',\n",
+       " 'cx',\n",
+       " 'xd',\n",
+       " 'xd',\n",
+       " 'xm',\n",
+       " 'dc',\n",
+       " 'xm',\n",
+       " 'dl',\n",
+       " 'mx',\n",
+       " 'xm',\n",
+       " 'xd',\n",
+       " 'cl',\n",
+       " 'cd',\n",
+       " 'dl',\n",
+       " 'xm',\n",
+       " 'dl',\n",
+       " 'xm',\n",
+       " 'xc',\n",
+       " 'cd',\n",
+       " 'll',\n",
+       " 'cc',\n",
+       " 'ld',\n",
+       " 'dd',\n",
+       " 'ld',\n",
+       " 'cd',\n",
+       " 'cc',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xx',\n",
+       " 'cc',\n",
+       " 'ld',\n",
+       " 'dd',\n",
+       " 'dl',\n",
+       " 'xm',\n",
+       " 'xc',\n",
+       " 'xm',\n",
+       " 'ld',\n",
+       " 'mx',\n",
+       " 'xm',\n",
+       " 'xd',\n",
+       " 'cm',\n",
+       " 'xm',\n",
+       " 'dl',\n",
+       " 'lc',\n",
+       " 'xx',\n",
+       " 'cm',\n",
+       " 'dc',\n",
+       " 'dc',\n",
+       " 'dm',\n",
+       " 'xm',\n",
+       " 'dd',\n",
+       " 'cd',\n",
+       " 'cc',\n",
+       " 'ld',\n",
+       " 'dm',\n",
+       " 'dc',\n",
+       " 'cc',\n",
+       " 'xm',\n",
+       " 'mx',\n",
+       " 'xm',\n",
+       " 'dl',\n",
+       " 'lm',\n",
+       " 'cc',\n",
+       " 'xm',\n",
+       " 'ml',\n",
+       " 'cd',\n",
+       " 'dl',\n",
+       " 'cm',\n",
+       " 'xm',\n",
+       " 'dl',\n",
+       " 'lc',\n",
+       " 'xx',\n",
+       " 'cm',\n",
+       " 'dc',\n",
+       " 'lc',\n",
+       " 'xm',\n",
+       " 'lx',\n",
+       " 'xx',\n",
+       " 'ld',\n",
+       " 'cx',\n",
+       " 'xm',\n",
+       " 'xd',\n",
+       " 'dd',\n",
+       " 'cd',\n",
+       " 'dm',\n",
+       " 'cc',\n",
+       " 'xd',\n",
+       " 'xm',\n",
+       " 'dl',\n",
+       " 'dc',\n",
+       " 'dd',\n",
+       " 'xx',\n",
+       " 'cc',\n",
+       " 'xd',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xm',\n",
+       " 'xc',\n",
+       " 'dm',\n",
+       " 'cc',\n",
+       " 'cc',\n",
+       " 'ld',\n",
+       " 'cc',\n",
+       " 'll',\n",
+       " 'cd',\n",
+       " 'lx',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xm',\n",
+       " 'cm',\n",
+       " 'cx',\n",
+       " 'xx',\n",
+       " 'cc',\n",
+       " 'xl',\n",
+       " 'dm',\n",
+       " 'dd',\n",
+       " 'xm',\n",
+       " 'ld',\n",
+       " 'dd',\n",
+       " 'lc',\n",
+       " 'xm',\n",
+       " 'dl',\n",
+       " 'ml',\n",
+       " 'xx',\n",
+       " 'md',\n",
+       " 'xd',\n",
+       " 'xm',\n",
+       " 'dc',\n",
+       " 'cm',\n",
+       " ...]"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "scb = sanitise(cb)\n",
+    "scbp = chunks(scb, 2)\n",
+    "scbp"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'MHALEATASTIFETHOTSFETNRAFSSETFWTHEYAROLPOTTLEMATHPNFDAUUOOTMOTLARGSTIEETHEHODREATHEITHETINNWSRNITHETOUTAUOLOPALATBTNNVEIUNCETHEHFGERFCEIAUOLDASODVORTOGEYOUEDPBHASOICBMATHNFTTHESFWWNITNYOGIAUNLOORDHASTOLERTEDSUNFTSDEYEOTMNFLDHOVEPEERAREVATOPLEORDMATHATTHELNSSNYPIATORRAOHOVARGIEOLASEDTHOTTHEAUERAMEIEIEODARGHASUNCCFRAUOTANRSOGIAUNLOOIIORGEDTNWLORTYOLSEARYNICOTANROPNFTTHEWLORREDDASWNSATANRNYTINNWSSETTARGOTIOWARTNMHAUHTHEAUERAYELLATASSTALLFRULEOIHNMTHESOVOGETIAPESHODLEOIREDTNDEUAWHEINFIOICBSUNCCFRAUOTANRSOSTHEBHODRNMIATARGNYTHEAINMRHNMEVEIEVEIBOICBHOSATSTIOATNISORDATSEECSLAKELBTNCETHOTNRENICNIENYTHELNUOLTIAPESWENWLETFIREDSNCENRESHEODLNVENICNREBATASOLLTIEOUHEIBPFTTHASOUTTHIEOTEREDTNFRDEICARETHEECWAIESERTAIESBSTECNYSEUFIEUNCCFRAUOTANRTHEUOESOIUAWHEIWEIHOWSCNIETHORINODSHODEROPLEDTHEECWAIETNYFRUTANRSEUFIELBORDATSLNSSMOSODASOSTEITFIRARGTHOTLNSSARTNOVAUTNIBNRTHEPOTTLEYAELDDESEIVEDCNIEIEUNGRATANRTHORATIEUEAVEDWEIHOWSSFETNRAFSREVEIKREMNIWEIHOWSHEYOALEDTNFRDEISTORDTHEUFRRARGNYTHEWLORPFTEATHEIMOBDESWATETHEVAUTNIBOGIAUNLOORDTHERARTHLEGANRIECOAREDARDASGIOUENRHEOIARGTHASREMSULOFDAFSUOESOIOFGFSTFSGEICORAUFSREINECWEINIASSFEDOSEUIETWINULOCOTANRESTOPLASHARGOUAWHEISUHNNLTNDEVELNWOREMSBSTECNYACWEIAOLUAWHEISATMNIKEDARSEUIETYNINVEITMERTBBEOISDEVELNWARGREMCETHNDSTNSEUFIEUNCCFRAUOTANRSOUINSSTHEECWAIESTFDBARGTHEMNIKSNYTHEGIEEKSOGESEFULADORDHBWOTAOORDEVERNLDEIMNIKSYINCORUAERTPOPBLNRTHESUHNNLDEVELNWEDREMMOBSTNSOYEGFOIDUNCCFRAUOTANRSYINCINCESERECAESTHESEREMSBSTECSMEIEMIATTERDNMRORDDASTIAPFTEDARTHEUNDEXNUUFLTNIFCWEIHOWSTHECNSTSTIAUTLBGFOIDEDDNUFCERTAROLLHASTNIBMHERATMOSYAROLLBUNCWLETEDCORBBEOISLOTEITHEECWEINIDNCATAORASSFEDOREXEUFTAVENIDEIMHAUHWIEYOUEDEVEIBUNWBNYTHEUNDEXTHOTATMOSTNPEGFOIDEDPBEVEIBLEGANRTNTHELOSTCORTHEDEYEOTNYTHEAUERAORDTHESFAUADENYPNFDAUUOWEIHOWSWINTEUTEDTHERARTHLEGANRYINCDASSNLFTANROGIAUNLOMOSLOIGELBLEYTTNHASNMRDEVAUESARTHEWINVARUETHNFGHATMOSCODEULEOITNHACTHOTTNIETFIRMNFLDCEOROTPESTDASGIOUEORDOTMNISTDEOTHAROPIEOKMATHTIODATANRTHERARTHIOASEDOREMSTORDOIDTHELEGANRMOSEXALEDARDASGIOUETNERDFIETHEHOIDORDDORGEINFSMNIKNYSFPDFARGTHEUOLEDNRAAARTHEPLEOKMALDEIRESSESNYUOLEDNRAOSFETNRAFSNIDEIEDTHERARTHTNCOIUHTNEPNIOUFCMHAUHTHEBMEIETNCOKETHEAIPOSEYNIIOADSARTNUOLEDNRAOTHEFRSWNKERIEOSNRYNITHEAIEXALEMOSTHOTARTELLAGERUEIEWNITSSFGGESTEDTHOTTHASMOSMHEIETHEBCAGHTYARDTHEAILNSTOQFALOTHNSEMHNMNFLDIEODNRCFSTYNLLNMCBYOATHYFLSLOVETAINMHNYOUESOGIOVETOSKWEIHOWSTHELOIGESTTNDOTEOSHETIOVELSTNUNRUEOLTHEYNFITHUHOWTEINYTHASTIOGAUTOLE'"
+      ]
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "scbpt = cat(trans[p] for p in scbp)\n",
+    "scbpt"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'while it is true that suetonius setup the final vat tle with vou di ccaat watling street he had neither the troops nor the tactical avi lity to ober come the huge numerical disad ban tage faced vy his army without the support of agricola and his talented scouts defeat would habe veen in ebita vle and with it the loss of vr it anni ahab ing realised that the iceni were reading his communications agricola arranged to plant false information av out the planned disposition of troops setting a trap into which the iceni fell it is still unclear how the saba get rives had learned to decipher our army s communications as they had no writing of their own howe be reber y army has its traitors and it seems likely to me that one or more of the local t rives people turned someones head lobe or money it is all treachery vut this act threatened to undermine the empires entire system of secure communication the caesar cipher perhaps more than road shade nav led the empire to function securely and its loss was a disaster turning that loss into a bic tory on the vat tle field deser bed more recognition than it recei bed perhaps suetonius ne berk new or perhaps he failed to understand the cunning of the plan vut either way despite the bic tory agricola and the ninth legion remained in disgrace on hearing this news claudius caesar augustus germanicus nero emperor issued a secret proclamation est av lishing a cipher school to de belo pa new system of imperial ciphers it worked in secret for ober twenty years deb eloping new methods to secure communications across the empire studying the works of the greeks ages euclid and hypatia and eben older works from ancient vav yl on the school deb eloped new ways to safeguard communications from rome s enemies these new systems were written down and distri vu ted in the codex occult orum perhaps the most strictly guarded document in all history when it was finally completed many years later the emperor domitian issued an execut i be order which preface de bery copy of the codex that it was to ve guarded vye bery legion to the last man the defeat of the iceni and the suicide of vou dic ca perhaps protected the ninth legion from dissolution agricola was largely left to his own debi ces in the prob in ce though it was made clear to him that to return would mean at vest disgrace and at worst death in av reak with tradition the ninth raised a new standard the legion was exiled in disgrace to endure the hard and dangerous work of suv du ing the caledon ii in the v leak wildernesses of caledonia suetonius ordered the ninth to march to evora cum which they were to make their vase for raids into caledonia the unspoken reason for their exile was that intelligence reports suggested that this was where they might find their lost aquila those who would read on must follow my faithful sla be tiro who faces agra be task perhaps the largest to date a she trabel s to conceal the fourth chapter of this tragic tale'"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "tr = {}\n",
+    "tr['E'] = 'e'\n",
+    "tr['T'] = 't'\n",
+    "tr['O'] = 'a'\n",
+    "tr['A'] = 'i'\n",
+    "tr['I'] = 'r'\n",
+    "tr['H'] = 'h'\n",
+    "tr['S'] = 's'\n",
+    "tr['M'] = 'w'\n",
+    "tr['P'] = 'v'\n",
+    "tr['L'] = 'l'\n",
+    "tr['Y'] = 'f'\n",
+    "tr['R'] = 'n'\n",
+    "tr['G'] = 'g'\n",
+    "tr['F'] = 'u'\n",
+    "tr['B'] = 'y'\n",
+    "tr['V'] = 'b'\n",
+    "tr['N'] = 'o'\n",
+    "tr['D'] = 'd'\n",
+    "tr['U'] = 'c'\n",
+    "tr['W'] = 'p'\n",
+    "tr['C'] = 'm'\n",
+    "tr['K'] = 'k'\n",
+    "tr['X'] = 'x'\n",
+    "tr['Q'] = 'q'\n",
+    "\n",
+    "# english: etoainhs rdlumwycfgpbvkxqz\n",
+    "# texts: etoanisrhdlufcmwgybpvkxqz\n",
+    "\n",
+    "\n",
+    "tt = ''.maketrans(tr)\n",
+    "wcat(segment(scbpt.translate(tt)))\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2969"
+      ]
+     },
+     "execution_count": 27,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('3b.plaintext', 'w').write(prettify(scbpt.translate(tt)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'A': 'i',\n",
+       " 'B': 'y',\n",
+       " 'C': 'm',\n",
+       " 'D': 'd',\n",
+       " 'E': 'e',\n",
+       " 'F': 'u',\n",
+       " 'G': 'g',\n",
+       " 'H': 'h',\n",
+       " 'I': 'r',\n",
+       " 'K': 'k',\n",
+       " 'L': 'l',\n",
+       " 'M': 'w',\n",
+       " 'N': 'o',\n",
+       " 'O': 'a',\n",
+       " 'P': 'v',\n",
+       " 'Q': 'q',\n",
+       " 'R': 'n',\n",
+       " 'S': 's',\n",
+       " 'T': 't',\n",
+       " 'U': 'c',\n",
+       " 'V': 'b',\n",
+       " 'W': 'p',\n",
+       " 'X': 'x',\n",
+       " 'Y': 'f'}"
+      ]
+     },
+     "execution_count": 20,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "tr"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'cc': 'n',\n",
+       " 'cd': 'o',\n",
+       " 'cl': 'm',\n",
+       " 'cm': 'p',\n",
+       " 'cx': 'l',\n",
+       " 'dc': 's',\n",
+       " 'dd': 't',\n",
+       " 'dl': 'r',\n",
+       " 'dm': 'u',\n",
+       " 'dx': 'q',\n",
+       " 'lc': 'h',\n",
+       " 'ld': 'i',\n",
+       " 'll': 'g',\n",
+       " 'lm': 'k',\n",
+       " 'lx': 'f',\n",
+       " 'mc': 'x',\n",
+       " 'md': 'y',\n",
+       " 'ml': 'w',\n",
+       " 'mx': 'b',\n",
+       " 'xc': 'c',\n",
+       " 'xd': 'd',\n",
+       " 'xl': 'v',\n",
+       " 'xm': 'e',\n",
+       " 'xx': 'a'}"
+      ]
+     },
+     "execution_count": 21,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "fm = {pr[1]: tr[pr[0].upper()] for pr in zip(ltrs, prs)}\n",
+    "fm"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "order = 'xlcdm'"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "avcde\n",
+      "fghik\n",
+      "lmnop\n",
+      "qrstu\n",
+      "bwxy\n"
+     ]
+    }
+   ],
+   "source": [
+    "for c in order:\n",
+    "    for r in order:\n",
+    "        if c+r != 'mm':\n",
+    "            print(fm[c+r], end='')\n",
+    "    print('')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# monoalphabetic_break_hillclimbing_mp(scbpt, alphabet=string.ascii_lowercase, fitness=Pbigrams)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "while it is true that suetonius setup the final battle with boudicca at watling street he had\n",
+      "neither the troops nor the tactical ability to overcome the huge numerical disadvantage faced by his\n",
+      "army without the support of agricola and his talented scouts defeat would have been inevitable and\n",
+      "with it the loss of britannia having realised that the iceni were reading his communications\n",
+      "agricola arranged to plant false information about the planned disposition of troops setting a trap\n",
+      "into which the iceni fell it is still unclear how the savage tribes had learned to decipher our army\n",
+      "s communications as they had no writing of their own however every army has its traitors and it\n",
+      "seems likely to me that one or more of the local tribespeople turned someones head love or money it\n",
+      "is all treachery but this act threatened to undermine the empires entire system of secure\n",
+      "communication the caesar cipher perhaps more than roads had enabled the empire to function securely\n",
+      "and its loss was a disaster turning that loss into a victory on the battlefield deserved more\n",
+      "recognition than it received perhaps suetonius never knew or perhaps he failed to understand the\n",
+      "cunning of the plan but either way despite the victory agricola and the ninth legion remained in\n",
+      "disgrace on hearing this news claudius caesar augustus germanicus nero emperor issued a secret\n",
+      "proclamation establishing a cipher school to develop a new system of imperial ciphers it worked in\n",
+      "secret for over twenty years developing new methods to secure communications across the empire\n",
+      "studying the works of the greeks ages euclid and hypatia and even older works from ancient babylon\n",
+      "the school developed new ways to safeguard communications from rome s enemies these new systems were\n",
+      "written down and distributed in the codex occult orum perhaps the most strictly guarded document in\n",
+      "all history when it was finally completed many years later the emperor domitian issued an executive\n",
+      "order which prefaced every copy of the codex that it was to be guarded by every legion to the last\n",
+      "man the defeat of the iceni and the suicide of boudicca perhaps protected the ninth legion from\n",
+      "dissolution agricola was largely left to his own devices in the province though it was made clear to\n",
+      "him that to return would mean at best disgrace and at worst death in a break with tradition the\n",
+      "ninth raised a new standard the legion was exiled in disgrace to endure the hard and dangerous work\n",
+      "of subduing the caledon ii in the bleak wildernesses of caledonia suetonius ordered the ninth to\n",
+      "march toe bora cum which they were to make their base for raids into caledonia the unspoken reason\n",
+      "for their exile was that intelligence reports suggested that this was where they might find their\n",
+      "lost aquila those who would read on must follow my faithful slave tiro who faces a grave task\n",
+      "perhaps the largest to date a she travels to conceal the fourth chapter of this tragic tale\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(polybius_decipher(scb, '', order, order)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "False"
+      ]
+     },
+     "execution_count": 26,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "scbpt.translate(tt) == polybius_decipher(scb, '', order, order)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/2017/2017-challenge4.ipynb b/2017/2017-challenge4.ipynb
new file mode 100644 (file)
index 0000000..25e04d0
--- /dev/null
@@ -0,0 +1,669 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import os,sys,inspect, collections\n",
+    "currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))\n",
+    "parentdir = os.path.dirname(currentdir)\n",
+    "sys.path.insert(0,parentdir) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.keyword_cipher import *\n",
+    "from cipher.vigenere import *\n",
+    "from support.text_prettify import *\n",
+    "from support.language_models import *\n",
+    "\n",
+    "ca = open('4a.ciphertext').read()\n",
+    "cb = open('4b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "UGXXV,\n",
+      "\n",
+      "BGXVGB THQQRTKRF N QRK NY KCHZU GT PR YRRF G ZCHXNRX GYF TUR KUCHQUK VCH BNQUK AR NYKRXRTKRF NY SCNYNYQ HT. URX TCHXZRT UGOR ZCYENXBRF KUGK KUR ACCL NT ARNYQ UHYKRF AV GY NIIRQGI EHYFXGNTNYQ QXCHM YGBRF BNFGT PUNZU UGT ARRY GTTCZNGKRF PNKU TRORXGI KRXXCX YRKPCXLT NY KUR IGTK ERP VRGXT. BGXVGB UGT KXGORIIRF KC NTKGYAHI ECIICPNYQ G IRGF CY KUR AHVRX NY KUR UCMR PR ZGY TZGXR KURB CEE, AHK NE KUGK FCRTY’K PCXL KURY PR PNII YRRF KC ENYF KUR XRTK CE KUR ACCL ZUGMKRXT ARECXR BNFGT FC. PR GXR ACKU UCMNYQ VCHX FNGXV NT ZIRGX, ARZGHTR NE N GB XNQUK PR PNII UGOR GYCKURX KUXRR MIGZRT KC ONTNK GEKRX KUNT CYR, GYF N GB YCK THXR UCP ICYQ NK PNII KGLR.\n",
+      "\n",
+      "N ENYNTURF BV PCXL CY KUR KUNXF ZUGMKRX CE KGZNKHT’T BCYCQXGMU PUNZU N ECHYF CY XUCFRT. NK PGT ZCYZRGIRF NY G IGXQR TKCYR INYKRI ARGXNYQ GY NBGQR CE G XCTR, KUR TVBACI CE KUR ZCYTCXK CE KUR THY QCF URINCT. NYKXNQHNYQIV XUCFRT NT GITC LYCPY GT KUR NTIGYF CE KUR LYNQUKT, YGBRF GEKRX KUR LYNQUKT CE TGNYK SCUY CE SRXHTGIRB, GYF KUR ZIHR GK KUR RYF CE ZUGMKRX KUXRR MCNYKRF KC GYCKURX UCBR CE KUR LYNQUKT GK ACFXHB, TC N KXGORIIRF KURXR GYF PGT YCK KCC THXMXNTRF KC ENYF ZUGMKRX ECHX ZCYZRGIRF NY KUR XRBGNYT CE KURNX ECXK. N PGT UCPRORX GTKCYNTURF AV KUR KRJK! NK KCCL BR G PUNIR KC ZXGZL NK GT N FNFY'K XRZCQYNTR KUR RYZXVMKNCY GT GYVKUNYQ ZIGTTNZGI. PURY N ENYGIIV AXCLR NK N FNTZCORXRF KUGK KGZNKHT UGF HTRF G ZNMURX KUGK PR KUCHQUK UGF ARRY NYORYKRF NY TNJKRRYKU ZRYKHXV EXGYZR. NK TRRBT KUGK KUR NBMRXNGI ZNMURX TZUCCI PRXR BHZU BCXR GFOGYZRF KUGY PR UGF GYV XRGTCY KC RJMRZK. NE ZCHXNRX FHKV NTY'K RJZNKNYQ RYCHQU ECX VCH MRXUGMT KUR ZUGYZR KC FNTZCORX BCXR NBMRXNGI ZNMURXT PNII AR?\n",
+      "\n",
+      "KUR ZIHR GK KUR RYF CE KUNT ZUGMKRX NT ORXV THQQRTKNOR, GYF N UGOR ACHQUK G KNZLRK KC TRIZHL KC NYORTKNQGKR. N GB MXRKKV THXR N PGT ECIICPRF KC KUR KNZLRK CEENZR.\n",
+      "\n",
+      "NE VCH ZGY ZCBR KURY PR YRRF VCH KC FXCM AV KUR AXNKNTU BHTRHB ARECXR VCH ZCBR CHK. N KUNYL KURXR NT TCBRKUNYQ KURXR KUGK PR YRRF GYF PNII TRYF G BRTTGQR KC BV ZCYKGZK NY XCCB KPRYKV KPC KRIINYQ KURB KC RJMRZK VCH GYF AXNRENYQ KURB CY PUGK KC ICCL CHK ECX. NK PCHIF AR QCCF NE VCH ZCHIF AR ORXV FNTZXRRK GACHK KUGK, AHK BGLR GT BHZU EHTT GT VCH INLR GACHK BRRKNYQ BR NY TRIZHL. N PNII RJMIGNY IGKRX!\n",
+      "\n",
+      "GII KUR ARTK,\n",
+      "\n",
+      "SCFNR\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(ca)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('comportment', <KeywordWrapAlphabet.from_largest: 3>), -2417.7329224996606)"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ka, score = keyword_break_mp(ca)\n",
+    "ka, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "isllj,\n",
+      "\n",
+      "psljsp ftyyefwer h yew hm watni sf de meer s natlhel smr fie wiatyiw jat phyiw oe hmwelefwer hm zahmhmy tf. iel fatlnef isbe namghlper wisw wie oaax hf oehmy itmwer oj sm huueysu gtmrlshfhmy ylatc msper phrsf dihni isf oeem sffanhswer dhwi febelsu wellal mewdalxf hm wie usfw ged jeslf. psljsp isf wlsbeuuer wa hfwsmotu gauuadhmy s uesr am wie otjel hm wie iace de nsm fnsle wiep agg, otw hg wisw raefm’w dalx wiem de dhuu meer wa ghmr wie lefw ag wie oaax niscwelf oegale phrsf ra. de sle oawi iachmy jatl rhslj hf nuesl, oenstfe hg h sp lhyiw de dhuu isbe smawiel wilee cusnef wa bhfhw sgwel wihf ame, smr h sp maw ftle iad uamy hw dhuu wsxe.\n",
+      "\n",
+      "h ghmhfier pj dalx am wie wihlr niscwel ag wsnhwtf’f pamaylsci dihni h gatmr am liaref. hw dsf namnesuer hm s uslye fwame uhmweu oeslhmy sm hpsye ag s lafe, wie fjpoau ag wie namfalw ag wie ftm yar ieuhaf. hmwlhythmyuj liaref hf sufa xmadm sf wie hfusmr ag wie xmhyiwf, msper sgwel wie xmhyiwf ag fshmw zaim ag zeltfsuep, smr wie nute sw wie emr ag niscwel wilee cahmwer wa smawiel iape ag wie xmhyiwf sw oarltp, fa h wlsbeuuer wiele smr dsf maw waa ftlclhfer wa ghmr niscwel gatl namnesuer hm wie lepshmf ag wiehl galw. h dsf iadebel sfwamhfier oj wie wevw! hw waax pe s dihue wa nlsnx hw sf h rhrm'w lenaymhfe wie emnljcwham sf smjwihmy nusffhnsu. diem h ghmsuuj olaxe hw h rhfnabeler wisw wsnhwtf isr tfer s nhciel wisw de wiatyiw isr oeem hmbemwer hm fhvweemwi nemwtlj glsmne. hw feepf wisw wie hpcelhsu nhciel fniaau dele ptni pale srbsmner wism de isr smj lesfam wa evcenw. hg natlhel rtwj hfm'w evnhwhmy ematyi gal jat celiscf wie nismne wa rhfnabel pale hpcelhsu nhcielf dhuu oe?\n",
+      "\n",
+      "wie nute sw wie emr ag wihf niscwel hf belj ftyyefwhbe, smr h isbe oatyiw s whnxew wa feuntx wa hmbefwhyswe. h sp clewwj ftle h dsf gauuader wa wie whnxew agghne.\n",
+      "\n",
+      "hg jat nsm nape wiem de meer jat wa rlac oj wie olhwhfi ptfetp oegale jat nape atw. h wihmx wiele hf fapewihmy wiele wisw de meer smr dhuu femr s peffsye wa pj namwsnw hm laap wdemwj wda weuuhmy wiep wa evcenw jat smr olheghmy wiep am disw wa uaax atw gal. hw datur oe yaar hg jat natur oe belj rhfnleew soatw wisw, otw psxe sf ptni gtff sf jat uhxe soatw peewhmy pe hm feuntx. h dhuu evcushm uswel!\n",
+      "\n",
+      "suu wie oefw,\n",
+      "\n",
+      "zarhe\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(keyword_decipher(ca, ka[0], ka[1]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "Counter({'a': 30,\n",
+       "         'b': 43,\n",
+       "         'c': 140,\n",
+       "         'e': 42,\n",
+       "         'f': 65,\n",
+       "         'g': 125,\n",
+       "         'h': 57,\n",
+       "         'i': 63,\n",
+       "         'j': 6,\n",
+       "         'k': 177,\n",
+       "         'l': 21,\n",
+       "         'm': 25,\n",
+       "         'n': 136,\n",
+       "         'o': 16,\n",
+       "         'p': 38,\n",
+       "         'q': 39,\n",
+       "         'r': 226,\n",
+       "         's': 4,\n",
+       "         't': 99,\n",
+       "         'u': 113,\n",
+       "         'v': 32,\n",
+       "         'x': 97,\n",
+       "         'y': 111,\n",
+       "         'z': 61})"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "collections.Counter(sanitise(ca))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'etoainhsrdlumwycfgpbvkxjqz'"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ltrs = [p[0] for p in english_counts.most_common()]\n",
+    "cat(ltrs)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['r',\n",
+       " 'k',\n",
+       " 'c',\n",
+       " 'n',\n",
+       " 'g',\n",
+       " 'u',\n",
+       " 'y',\n",
+       " 't',\n",
+       " 'x',\n",
+       " 'f',\n",
+       " 'i',\n",
+       " 'z',\n",
+       " 'h',\n",
+       " 'b',\n",
+       " 'e',\n",
+       " 'q',\n",
+       " 'p',\n",
+       " 'v',\n",
+       " 'a',\n",
+       " 'm',\n",
+       " 'l',\n",
+       " 'o',\n",
+       " 'j',\n",
+       " 's']"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ctls =  [p[0] for p in collections.Counter(sanitise(ca)).most_common()]\n",
+    "ctls"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "24"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(ctls)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'A': 'p',\n",
+       " 'B': 'w',\n",
+       " 'C': 'o',\n",
+       " 'E': 'y',\n",
+       " 'F': 'd',\n",
+       " 'G': 'i',\n",
+       " 'H': 'm',\n",
+       " 'I': 'l',\n",
+       " 'J': 'x',\n",
+       " 'K': 't',\n",
+       " 'L': 'v',\n",
+       " 'M': 'b',\n",
+       " 'N': 'a',\n",
+       " 'O': 'k',\n",
+       " 'P': 'f',\n",
+       " 'Q': 'c',\n",
+       " 'R': 'e',\n",
+       " 'S': 'j',\n",
+       " 'T': 's',\n",
+       " 'U': 'n',\n",
+       " 'V': 'g',\n",
+       " 'X': 'r',\n",
+       " 'Y': 'h',\n",
+       " 'Z': 'u'}"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "trans = {pr[1].upper(): pr[0] for pr in zip(ltrs, ctls)}\n",
+    "trans"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "nirrg,\n",
+      "\n",
+      "wirgiw smccested a cet ah tomun is fe heed i uomraer ihd sne tnomcnt gom wacnt pe ahterested ah joahahc ms. ner somrues nike uohyarwed tnit tne poov as peahc nmhted pg ih allecil ymhdriasahc cromb hiwed wadis fnaun nis peeh issouaited fatn sekeril terror hetforvs ah tne list yef geirs. wirgiw nis trikelled to astihpml yollofahc i leid oh tne pmger ah tne nobe fe uih suire tnew oyy, pmt ay tnit doesh’t forv tneh fe fall heed to yahd tne rest oy tne poov unibters peyore wadis do. fe ire potn nobahc gomr dairg as uleir, peuimse ay a iw racnt fe fall nike ihotner tnree bliues to kasat iyter tnas ohe, ihd a iw hot smre nof lohc at fall tive.\n",
+      "\n",
+      "a yahasned wg forv oh tne tnard unibter oy tiuatms’s wohocribn fnaun a yomhd oh rnodes. at fis uohueiled ah i lirce stohe lahtel peirahc ih awice oy i rose, tne sgwpol oy tne uohsort oy tne smh cod nelaos. ahtracmahclg rnodes as ilso vhofh is tne aslihd oy tne vhacnts, hiwed iyter tne vhacnts oy siaht jonh oy jermsilew, ihd tne ulme it tne ehd oy unibter tnree boahted to ihotner nowe oy tne vhacnts it podrmw, so a trikelled tnere ihd fis hot too smrbrased to yahd unibter yomr uohueiled ah tne rewiahs oy tnear yort. a fis nofeker istohasned pg tne text! at toov we i fnale to uriuv at is a dadh't reuochase tne ehurgbtaoh is ihgtnahc ulissauil. fneh a yahillg prove at a dasuokered tnit tiuatms nid msed i uabner tnit fe tnomcnt nid peeh ahkehted ah saxteehtn uehtmrg yrihue. at seews tnit tne awberail uabner sunool fere wmun wore idkihued tnih fe nid ihg reisoh to exbeut. ay uomraer dmtg ash't exuatahc ehomcn yor gom bernibs tne unihue to dasuoker wore awberail uabners fall pe?\n",
+      "\n",
+      "tne ulme it tne ehd oy tnas unibter as kerg smccestake, ihd a nike pomcnt i tauvet to selumv to ahkestacite. a iw brettg smre a fis yollofed to tne tauvet oyyaue.\n",
+      "\n",
+      "ay gom uih uowe tneh fe heed gom to drob pg tne pratasn wmsemw peyore gom uowe omt. a tnahv tnere as sowetnahc tnere tnit fe heed ihd fall sehd i wessice to wg uohtiut ah roow tfehtg tfo tellahc tnew to exbeut gom ihd praeyahc tnew oh fnit to loov omt yor. at fomld pe cood ay gom uomld pe kerg dasureet ipomt tnit, pmt wive is wmun ymss is gom lave ipomt weetahc we ah selumv. a fall exbliah liter!\n",
+      "\n",
+      "ill tne pest,\n",
+      "\n",
+      "jodae\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "tt = ''.maketrans(trans)\n",
+    "print(ca.translate(tt))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "harry,\n",
+      "\n",
+      "maryam suggested i get in touch as we need a courier and she thought you might be interested in joining us. her sources have confirmed that the book is being hunted by an illegal fundraising group named midas which has been associated with several terror networks in the last few years. maryam has travelled to istanbul following a lead on the buyer in the hope we can scare them off, but if that doesn’t work then we will need to find the rest of the book chapters before midas do. we are both hoping your diary is clear, because if i am right we will have another three places to visit after this one, and i am not sure how long it will take.\n",
+      "\n",
+      "i finished my work on the third chapter of tacitus’s monograph which i found on rhodes. it was concealed in a large stone lintel bearing an image of a rose, the symbol of the consort of the sun god helios. intriguingly rhodes is also known as the island of the knights, named after the knights of saint john of jerusalem, and the clue at the end of chapter three pointed to another home of the knights at bodrum, so i travelled there and was not too surprised to find chapter four concealed in the remains of their fort. i was however astonished by the text! it took me a while to crack it as i didn't recognise the encryption as anything classical. when i finally broke it i discovered that tacitus had used a cipher that we thought had been invented in sixteenth century france. it seems that the imperial cipher school were much more advanced than we had any reason to expect. if courier duty isn't exciting enough for you perhaps the chance to discover more imperial ciphers will be?\n",
+      "\n",
+      "the clue at the end of this chapter is very suggestive, and i have bought a ticket to selcuk to investigate. i am pretty sure i was followed to the ticket office.\n",
+      "\n",
+      "if you can come then we need you to drop by the british museum before you come out. i think there is something there that we need and will send a message to my contact in room twenty two telling them to expect you and briefing them on what to look out for. it would be good if you could be very discreet about that, but make as much fuss as you like about meeting me in selcuk. i will explain later!\n",
+      "\n",
+      "all the best,\n",
+      "\n",
+      "jodie\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "trans = {'A': 'b',\n",
+    " 'B': 'm',\n",
+    " 'C': 'o',\n",
+    " 'D': 'q',      \n",
+    " 'E': 'f',\n",
+    " 'F': 'd',\n",
+    " 'G': 'a',\n",
+    " 'H': 'u',\n",
+    " 'I': 'l',\n",
+    " 'J': 'x',\n",
+    " 'K': 't',\n",
+    " 'L': 'k',\n",
+    " 'M': 'p',\n",
+    " 'N': 'i',\n",
+    " 'O': 'v',\n",
+    " 'P': 'w',\n",
+    " 'Q': 'g',\n",
+    " 'R': 'e',\n",
+    " 'S': 'j',\n",
+    " 'T': 's',\n",
+    " 'U': 'h',\n",
+    " 'V': 'y',\n",
+    " 'X': 'r',\n",
+    " 'Y': 'n',\n",
+    " 'Z': 'c'}\n",
+    "tt = ''.maketrans(trans)\n",
+    "print(ca.translate(tt))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'a': 'G',\n",
+       " 'b': 'A',\n",
+       " 'c': 'Z',\n",
+       " 'd': 'F',\n",
+       " 'e': 'R',\n",
+       " 'f': 'E',\n",
+       " 'g': 'Q',\n",
+       " 'h': 'U',\n",
+       " 'i': 'N',\n",
+       " 'j': 'S',\n",
+       " 'k': 'L',\n",
+       " 'l': 'I',\n",
+       " 'm': 'B',\n",
+       " 'n': 'Y',\n",
+       " 'o': 'C',\n",
+       " 'p': 'M',\n",
+       " 'q': 'D',\n",
+       " 'r': 'X',\n",
+       " 's': 'T',\n",
+       " 't': 'K',\n",
+       " 'u': 'H',\n",
+       " 'v': 'O',\n",
+       " 'w': 'P',\n",
+       " 'x': 'J',\n",
+       " 'y': 'V'}"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "{v: k for k, v in trans.items()}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'A': 'b',\n",
+       " 'B': 'm',\n",
+       " 'C': 'o',\n",
+       " 'D': 'q',\n",
+       " 'E': 'f',\n",
+       " 'F': 'd',\n",
+       " 'G': 'a',\n",
+       " 'H': 'u',\n",
+       " 'I': 'l',\n",
+       " 'J': 'x',\n",
+       " 'K': 't',\n",
+       " 'L': 'k',\n",
+       " 'M': 'p',\n",
+       " 'N': 'i',\n",
+       " 'O': 'v',\n",
+       " 'P': 'w',\n",
+       " 'Q': 'g',\n",
+       " 'R': 'e',\n",
+       " 'S': 'j',\n",
+       " 'T': 's',\n",
+       " 'U': 'h',\n",
+       " 'V': 'y',\n",
+       " 'X': 'r',\n",
+       " 'Y': 'n',\n",
+       " 'Z': 'c'}"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "trans"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'bmoqfdaulxtkpivwgejshyrnc'"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cat(trans[k] for k in sorted(trans))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'GAZFREQUNSLIBYCMDXTKHOPJV'"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cat({v: k for k, v in trans.items()}[tk] for tk in sorted(trans.values()))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2229"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('4a.plaintext', 'w').write(ca.translate(tt))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2229"
+      ]
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "keyphrase_4a = 'gaza frequens Libycum: duxit Karthago triumphum!'\n",
+    "pa = keyword_decipher(ca, keyphrase_4a)\n",
+    "\n",
+    "open('4a.plaintext', 'w').write(pa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('arcanaimperii', -4159.598618934157)"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kb, sb = vigenere_frequency_break(sanitise(cb))\n",
+    "kb, sb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "over the years the heroic role of agricola at watling street came to the notice of rome and two\n",
+      "decades later he was appointed proconsul and governor of britannia by emperor vespasian a few years\n",
+      "after his appointment vespasian ss on domitian became emperor and one of his first acts was to issue\n",
+      "the order to implement the new imperial ciphers invented by the cipher school in the intervening\n",
+      "years the ninth had been left to fight lonely skirmishes and battles from their base ate bora cum\n",
+      "with fortitude and resolve they repeatedly drove the barbarians back into the cold heartlands of\n",
+      "caledonia during one such skirmish varus was mortally wounded and agricola promoted the tribune\n",
+      "marcus fidel i usca to to the legatus of the ninth one day the luck of the ninth seemed to change a\n",
+      "reconnaissance squad reported that they had seen the aquila flying from a tree at mons grau pius in\n",
+      "a camp ruled by a tribesman called cal gac us the new legatus recognised that the privations of\n",
+      "along march had exhausted his men they were not ready for battle and ca to should have sent for\n",
+      "reinforcements but the joy of seeing the lost aquila so close at hand clouded his judgement and he\n",
+      "launched an attack under the cover of darkness fighting uphill against wave upon wave of barbarians\n",
+      "the legions heroic efforts were frustrated by the sun rising to blind them as dawn broke the troops\n",
+      "in the frontline gave way with exhaustion and the wild cal gac us dashed out of the sundown the\n",
+      "blood soaked slope with his cavalry into the heart of the legion the legion rained flaming arrows\n",
+      "upon the enemy and managed to un horse cal gac us taking him prisoner but could make no headway\n",
+      "against the savage hordes and were unable to reach the stolen aquila worse was to come while ca to\n",
+      "organised a retreat with the prisoner cal gac us in chains the remaining soldiers held the line\n",
+      "against repeated charges by caledonian and iceni an tribesmen when the line finally broke ca to and\n",
+      "many of the ninth legion had reached safety and took stock the cavalry were safe as were many of the\n",
+      "brave legionnaires but to his horror ca to realised that in the battle he had lost the second aquila\n",
+      "and worse the legions copy of the codex had also gone the documents left to me by agricola are\n",
+      "unclear on this point did he know that the codex might have fallen into enemy hands and that a\n",
+      "second aquila had been lost or did ca to assure him that the codex had been destroyed as part of an\n",
+      "orderly retreat perhaps ca to was yet to rejoin agricola at the fort and communications from the\n",
+      "battle had yet to reach him in a letter to emperor domitian agricola wrote most excellent emperor as\n",
+      "you have most graciously requested i have finished my affairs herein britannia in preparation for\n",
+      "returning to your side in rome it please sme to report to you that by acts of diplomacy and strength\n",
+      "i have persuaded the northern rebels to yield to our army and to turnover to us the rebel cal gac us\n",
+      "who has remained free since the wars against boudicca and the iceni his letter appears to have been\n",
+      "a reply to new orders from rome in which domitian wrote my esteemed gnaeus upon receipt of your most\n",
+      "recent letter i have been most troubled it appears clear to me that the situation in britannia has\n",
+      "worsened and so i must ask you to return to meat rome with the utmost speed conduct your remaining\n",
+      "affairs in the province and do not undertake any action which mayen flame the current tensions\n",
+      "between yourself and the caledon ii the final line of the emperors letter set a deadline for\n",
+      "agricola s return i shall expect you to have crossed the rubicon by the end of the year and perhaps\n",
+      "he felt that contrition was a safer refuge whatever agricola knew at that point within a month his\n",
+      "world had been turned upsidedown as further reports from caledonia made clear that his hope of\n",
+      "restoration in the eyes of the emperor were in real jeopardy he set out to recover the two aquilae\n",
+      "and to determine what had happened to the codex before returning to rome those who read on must\n",
+      "search for the truth in the spiritual home of the amazons\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(vigenere_decipher(sanitise(cb), kb)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "4084"
+      ]
+     },
+     "execution_count": 20,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('4b.plaintext', 'w').write(prettify(vigenere_decipher(sanitise(cb), kb)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/2017/2017-challenge5.ipynb b/2017/2017-challenge5.ipynb
new file mode 100644 (file)
index 0000000..609d017
--- /dev/null
@@ -0,0 +1,897 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import os,sys,inspect, collections\n",
+    "currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))\n",
+    "parentdir = os.path.dirname(currentdir)\n",
+    "sys.path.insert(0,parentdir) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.caesar import *\n",
+    "from cipher.affine import *\n",
+    "from cipher.keyword_cipher import *\n",
+    "from cipher.vigenere import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "from support.language_models import *\n",
+    "\n",
+    "ca = open('5a.ciphertext').read()\n",
+    "cb = open('5b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "JDPWD JGLOF YBDQA LKYFD PPFTY OFKQY ICSHD QMIDK KYOES RQBYO FOKRJ DHYRB YPYKO YXTLS QRBYI LCDIQ RDRFL KRBFK HQBYJ DWBDT YEYYK HFOKD MMYOE SRRBY PYBDQ EYYKK LPDKQ LJOYJ DKODK ORBYP YFQKL RBFKA JSCBR LALLK BYPPL LJBDO EYYKP DKQDC HYODK OQBYI YZRKL JYQQD AYESR QLJYR BFKAR YIIQJ YQBYF QLHDK OUYQB LSIOJ LTYLK FRBFK HQBYJ DWBDT YMIDK KYORB FQJYD KUBFI YFBDT YRBYO LCSJY KRGLO FYUDK RYOZP LJILK OLKFO LKRHK LUBLU QBYHK YUESR RBYZF ZRBCB DMRYP UDQBF OOYKF KDCDT FRWFK DQRLK YIFKR YIFKQ LJYPY JDFKQ FKRBY YMBYQ SQPLL JDRRB YEPFR FQBJS QYSJF RUDQY KCPWM RYOSQ FKADK LRBYP MLIWD IMBDE YRFCC FMBYP FKTYK RYOFK RBYKF KYRYY KRBCY KRSPW FDQHY ORBYJ SQYSJ RLRYQ RFRDK ORBYO LCSJY KRFQD SRBYK RFCQL FASYQ QRBYF JMYPF DICFM BYPQC BLLIP YDIIW BDOJL TYOLK MYPBD MQFQB LSIOK RBDTY EYYKQ SPMPF QYODZ RYPRB YOFQC LTYPW DRELO PSJES RFRIY DTYQJ YULKO YPFKA UBDRY IQYRB YWOYT YILMY OLKYL OOZYD RSPYU DQDZP FYXYP SKKFK APLSK ORBPY YQFOY QLZRB YIFKR YICLK QFQRF KALZD QFKAI YPLUL ZEIDC HDKOU BFRYR FIYQR BDRRB YJSQY SJRBF KHUYP YDOOY OFKRB YPLJD KMYPF LORBY WPYDO FKQYN SYKCY UUEEU UUEUU UEUUU EUUUE UUUEU UUEUU UEUUU EUUUE UUUEU UUEUU UEUUU EUUUE UUUEU UUEUU UEUUU EUUUE EUUUE UUEUE UEUEU EUEUE UEUEU EUEUE UEUEU EUEUE UEUEU EUEUE UEUEU EUEUE UEUEU EUEUE UEUEU EUEUE UEUUE UUUEU EEEUE EEUEE EUEEE UEEEU EEEUE EEUEE EUEEE UEEEU EEEUE EEUEE EUEEE UEEEU EEEUE EEUEE EUEEE UEUUU EUUUE UUUEU UUEUU UEUUU EUUUE UUUEU UUEUU UEUUU EUUUE UUUEU UUEUU UEUUU EUUUE UUUEU UUEUU UEUUU EUUUE UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUEUU UEUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UEUUU EUUUU EUUUE EEUUU UUEEE UUUEU UUEUU UEUUU EUUUU EEEUU EUUUE UEEEU UUEEE EUUEE EUUUE EEUUE EEUEU UUEUU UUEUE UUEUU EUUUE UUUUU EUEUU EEUUE UUEUE UUUUE UUUEE UEEUE UUEUU EUUUU UEUUE UUUEU UUUEU UUEUU UEUUE UUUEU EUUUE UEUUU UUEUU UEUEU EUEUE UUUEU UUEUU UEUEU EUEUU EUUEU UUUUE UUUEU UEUUU UEUUE UUUEU UUEEE EEUEE EEUUE UUUUU EEEEE UEUEU EUEEE EEUUU EUUUE UUUEU EEEEU UEEEU UUEEE EUUUE UUUUE UUUEU UUEUU EUUUE UEUEU UUEUU UUUEU UUEUE UEUEU EUUUE UUUEU UUEUU UEUEU UUUUE UUUUU EUEUU UUEUU UUEUU EUUUE UUUEU UUEUE UUEUU UEUUU UEUUU EUEUU EEUEU UUEUU UEUUU EUUUE UEUUU UUEUU UUUEU UEUUU EUUUU EUUUE UUUEU UEUUU EUEUU UEUUU EEEUE UUUEU EUUUE UEUUU EUUEE EUUEU UUEUE UUUUU EEEEU UEUUU EUEEE UUEEE UEUUU EUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU EUUUE UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUEUU UEUEU UUEUU UEUUU EUUUE UUUEU UUEUU UEUUU EUUUE UUUEU UUEUU UEUUU EUUUE UUUEU UUEUU UEUUU EUUUE UEUUU EUEUE UEUEU EUEUE UEUEU EUEUE UEUEU EUEUE UEUEU EUEUE UEUEU EUEUE UEUEU EUEUE UEUEU EUEUE UEUEU UUEUU EEEUE EEUEE EUEEE UEEEU EEEUE EEUEE EUEEE UEEEU EEEUE EEUEE EUEEE UEEEU EEEUE EEUEE EUEEE UUEUU UEUUE UUUEU UUEUU UEUUU EUUUE UUUEU UUEUU UEUUU EUUUE UUUEU UUEUU UEUUU EUUUE UUUEU UUEUU UEUUE UUFBD TYSQY OEZLP RBYEI DCHRF IYQDK OUZLP RBYUB FRYLK YQFRR LLHJY DUBFI YRLZF ASPYL SRRBD RRBYZ PFYXY FQQRY ADKLA PDMBW CLKCY DIFKA RBYHY WULPO ZLPRB YCFMB YPFKC BDMRY PZFTY UFRBL SRGLO FYFDJ KLRQS PYUBY PYRLA LKYVR RBYPY DPYLK IWRUL MLQQF EFIFR FYQDQ ZDPDQ FCDKQ YYESR FBDTY KLFOY DUBYP YLKYL ZRBYJ FQDKO DQZDP DQFCD KRYII KLLKY YIQYH KLUQY FRBYP QLFAS YQQFU FIIBY DOZLP LIWJM FDQYY WLSRB YPY\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(ca)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ca_text = '''\n",
+    "JDPWD JGLOF YBDQA LKYFD PPFTY OFKQY ICSHD QMIDK KYOES RQBYO FOKRJ DHYRB YPYKO YXTLS QRBYI \n",
+    "LCDIQ RDRFL KRBFK HQBYJ DWBDT YEYYK HFOKD MMYOE SRRBY PYBDQ EYYKK LPDKQ LJOYJ DKODK ORBYP \n",
+    "YFQKL RBFKA JSCBR LALLK BYPPL LJBDO EYYKP DKQDC HYODK OQBYI YZRKL JYQQD AYESR QLJYR BFKAR \n",
+    "YIIQJ YQBYF QLHDK OUYQB LSIOJ LTYLK FRBFK HQBYJ DWBDT YMIDK KYORB FQJYD KUBFI YFBDT YRBYO \n",
+    "LCSJY KRGLO FYUDK RYOZP LJILK OLKFO LKRHK LUBLU QBYHK YUESR RBYZF ZRBCB DMRYP UDQBF OOYKF \n",
+    "KDCDT FRWFK DQRLK YIFKR YIFKQ LJYPY JDFKQ FKRBY YMBYQ SQPLL JDRRB YEPFR FQBJS QYSJF RUDQY\n",
+    "KCPWM RYOSQ FKADK LRBYP MLIWD IMBDE YRFCC FMBYP FKTYK RYOFK RBYKF KYRYY KRBCY KRSPW FDQHY \n",
+    "ORBYJ SQYSJ RLRYQ RFRDK ORBYO LCSJY KRFQD SRBYK RFCQL FASYQ QRBYF JMYPF DICFM BYPQC BLLIP \n",
+    "YDIIW BDOJL TYOLK MYPBD MQFQB LSIOK RBDTY EYYKQ SPMPF QYODZ RYPRB YOFQC LTYPW DRELO PSJES \n",
+    "RFRIY DTYQJ YULKO YPFKA UBDRY IQYRB YWOYT YILMY OLKYL OOZYD RSPYU DQDZP FYXYP SKKFK APLSK \n",
+    "ORBPY YQFOY QLZRB YIFKR YICLK QFQRF KALZD QFKAI YPLUL ZEIDC HDKOU BFRYR FIYQR BDRRB YJSQY \n",
+    "SJRBF KHUYP YDOOY OFKRB YPLJD KMYPF LORBY WPYDO FKQYN SYKCY\n",
+    "  FBD TYSQY OEZLP RBYEI DCHRF IYQDK OUZLP RBYUB FRYLK YQFRR LLHJY DUBFI YRLZF ASPYL SRRBD \n",
+    "RRBYZ PFYXY FQQRY ADKLA PDMBW CLKCY DIFKA RBYHY WULPO ZLPRB YCFMB YPFKC BDMRY PZFTY UFRBL \n",
+    "SRGLO FYFDJ KLRQS PYUBY PYRLA LKYVR RBYPY DPYLK IWRUL MLQQF EFIFR FYQDQ ZDPDQ FCDKQ YYESR \n",
+    "FBDTY KLFOY DUBYP YLKYL ZRBYJ FQDKO DQZDP DQFCD KRYII KLLKY YIQYH KLUQY FRBYP QLFAS YQQFU \n",
+    "FIIBY DOZLP LIWJM FDQYY WLSRB YPY\n",
+    "'''\n",
+    "sca_text = sanitise(ca_text)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(24, -1733.3180566179738)"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score = caesar_break(sca_text)\n",
+    "key_a, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "lfryflinqhadfscnmahfrrhvaqhmsakeujfsokfmmaqgutsdaqhqmtlfjatdaramqazvnustdaknefkstfthnmtdhmjsdalfydfvagaamjhqmfooaqguttdaradfsgaammnrfmsnlqalfmqfmqtdarahsmntdhmcluedtncnnmdarrnnldfqgaamrfmsfejaqfmqsdakabtmnlassfcagutsnlatdhmctakkslasdahsnjfmqwasdnukqlnvanmhtdhmjsdalfydfvaokfmmaqtdhslafmwdhkahdfvatdaqneulamtinqhawfmtaqbrnlknmqnmhqnmtjmnwdnwsdajmawguttdabhbtdedfotarwfsdhqqamhmfefvhtyhmfstnmakhmtakhmsnlaralfhmshmtdaaodasusrnnlfttdagrhthsdlusaulhtwfsameryotaqushmcfmntdaronkyfkodfgatheehodarhmvamtaqhmtdamhmataamtdeamturyhfsjaqtdalusaultntasthtfmqtdaqneulamthsfutdamthesnhcuasstdahloarhfkehodarsednnkrafkkydfqlnvaqnmoardfoshsdnukqmtdfvagaamsurorhsaqfbtartdaqhsenvaryftgnqrulguthtkafvaslawnmqarhmcwdftaksatdayqavaknoaqnmanqqbafturawfsfbrhazarummhmcrnumqtdraashqasnbtdakhmtakenmshsthmcnbfshmckarnwnbgkfejfmqwdhtathkastdfttdalusaultdhmjwarafqqaqhmtdarnlfmoarhnqtdayrafqhmsapuameahdfvausaqgbnrtdagkfejthkasfmqwbnrtdawdhtanmashttnnjlafwdhkatnbhcuranuttdfttdabrhazahsstacfmncrfodyenmeafkhmctdajaywnrqbnrtdaehodarhmedfotarbhvawhtdnutinqhahflmntsurawdaratncnmaxttdarafranmkytwnonsshghkhthasfsbfrfshefmsaaguthdfvamnhqafwdaranmanbtdalhsfmqfsbfrfshefmtakkmnnmaaksajmnwsahtdarsnhcuasshwhkkdafqbnrnkylohfsaaynutdara\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(caesar_decipher(sca_text, key_a))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "((17, 21, True), -1723.2877779777489)"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(m_a, a_a, o_a), score = affine_break(sca_text)\n",
+    "(m_a, a_a, o_a), score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "gyotygparsneylhadnsyooscnrsdlnjbfmylxjyddnrvfilenrsrdigymnienondrnqcaflienjabyjliyisadiesdmlengyteycnvnndmsrdyxxnrvfiienoneylvnnddaoydlagrngydrydrienonsldaiesdhgfbeiahaadenooaageyrvnndoydlybmnrydrlenjnkidagnllyhnvfilagniesdhinjjlgnlenslamydrznleafjrgacnadsiesdmlengyteycnxjyddnrieslgnydzesjnseycnienrabfgndiparsnzydinrkoagjadradsradimdazeazlenmdnzvfiienkskiebeyxinozylesrrndsdybycsitsdyliadnjsdinjsdlagnongysdlsdiennxenlfloaagyiienvosislegflnfgsizylndbotxinrflsdhydaienoxajtyjxeyvnisbbsxenosdcndinrsdiendsdninndiebndifotsylmnriengflnfgiainlisiydrienrabfgndislyfiendisblashfnlliensgxnosyjbsxenolbeaajonyjjteyrgacnradxnoeyxlsleafjrdieycnvnndlfoxoslnrykinoienrslbacnotyivarofgvfisijnycnlgnzadrnosdhzeyinjlnientrncnjaxnradnarrknyifonzylykosnqnofddsdhoafdrieonnlsrnlakienjsdinjbadlslisdhakylsdhjnoazakvjybmydrzesinisjnlieyiiengflnfgiesdmznonyrrnrsdienoagydxnosarientonyrsdlnufndbnseycnflnrvkaoienvjybmisjnlydrzkaoienzesinadnlsiiaamgnyzesjniakshfonafiieyiienkosnqnsllinhydahoyxetbadbnyjsdhienmntzaorkaoienbsxenosdbeyxinokscnzsieafiparsnsygdailfonzenoniahadnwiienonyonadjtizaxallsvsjsisnlylkyoylsbydlnnvfiseycndasrnyzenonadnakiengslydrylkyoylsbydinjjdaadnnjlnmdazlnsienolashfnllszsjjenyrkaoajtgxsylnntafienon\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(affine_decipher(sca_text, m_a, a_a, o_a))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('decoy', <KeywordWrapAlphabet.from_last: 2>), -1505.1870286708981)"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ka, score = keyword_break_mp(sca_text)\n",
+    "ka, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('decoyzabfghijklmnpqrstuvwx', -4117.559010215594)"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cipher_alphabet, score = simulated_annealing_break(\n",
+    "    sca_text, workers=12,\n",
+    "    initial_temperature=200, max_iterations=20000, \n",
+    "#     plain_alphabet=cat(ltrs), cipher_alphabet=cat(ctls),\n",
+    "    fitness=Ptrigrams)\n",
+    "cipher_alphabet, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "maryam jodie has gone i arrived in selcuk as planned but she didnt make the rendezvous the local\n",
+      "station think she may have been kidnapped but there has been no ransom demand and there is nothing\n",
+      "much to go on her room had been ransacked and she left no message but something tells me she is ok\n",
+      "and we should move on i think she may have planned this meanwhile i have the document jodie wanted\n",
+      "from london i dont know how she knew but the fifth chapter was hidden in a cavity in a stone lintel\n",
+      "in some remains in the ephesus room at the british museum it was encrypted using another poly\n",
+      "alphabetic cipher invented in the nineteenth century i asked the museum to test it and the document\n",
+      "is authentic so i guess the imperial cipher school really had moved on perhaps i shouldnt have been\n",
+      "surprised after the discovery at bodrum but it leaves me wondering what else they developed one odd\n",
+      "feature was a frieze running round three sides of the lintel consisting of a single row of\n",
+      "blackandwhite tiles that the museum think were added in the roman period they read in sequence\n",
+      "wwbbwwwbwwwbwwwbwwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb www bbw\n",
+      "wwbw wbwbwbwbwbwbwbwbwbw bwbwbwbwbwbwbwbwbwbw bwbwbwbwbwbwbwbwbwbw bwbwbwbwbwbwbwbwbwwb www\n",
+      "bwbbbwbbbwbbbwbbbwb bbwbbbwbbbwbbbwbbbwb bbwbbbwbbbwbbbwbbbwb bbwbbbwbbbwbbbwbbbwb wwwb wwwb wwwb\n",
+      "wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb www\n",
+      "www www www www www www www www www www www www www www www www www www www www www www www www wwbw\n",
+      "wwbw www www www www www www www www www www www www www www www www www www www www www www www www\n",
+      "www wwwb wwwb www wb wwwb bbw wwww bbb wwwb wwwb wwwb www bw www bbb wwbw wwbw bbb www bbbb\n",
+      "wwbbbwwwbbbwwbbbwb www bwwwwbwbwwbwwbwwwbww www bwbwwbbwwbwwbwbwwwwb www bbw bbw\n",
+      "bwwbwwbwwwwwbwwbwwwb www wb www bwwwbwwbwwwbwbwwwbwb www wwbwwwbwbwbwbwbwwwb www bwwwbwbwbwbwwbwwbww\n",
+      "www bwwwbwwbwwwwbwwbwwwb www bbb bbw bbbb wwbw wwww bbb bbw bwbwbwbbbbbwwwbwwwbw wwbw bbbb ww bbb\n",
+      "www bbbb wwwb www wb www bwwwbwwbwwwbwbwbwwwb www wwbwwwbwbwbwbwbwwwb wwwb wwwb www bwb www wwbw\n",
+      "wwww bwbwwwwbwwwwbwwbwwwb www bwwwbwbwwbwwwbwwwwb www bwbwwbbwbwwwbwwwb wwwb www bwb www wwbw www wb\n",
+      "wwbw wwbw www bwwwbwwwbwwbwwwbwb wwwb www bbb wbwwwbwbwwwbwbwwwbww bbb wwbw wwbw bww www bbbb wwbw\n",
+      "wwbwbbbwwbbbwbwwwbww www www www www www www www www www www www www www www www www www www www www\n",
+      "www www www www www wwbw wwbw www www www www www www www www www www www www www www www www www\n",
+      "www www www www www www www www wbwwwbwbwwwbwwwbwwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb\n",
+      "wwwb wwwb wwwb wwwb wwwb wwwb www bwb www bwbwbwbwbwbwbwbwbwb wbwbwbwbwbwbwbwbwbwb\n",
+      "wbwbwbwbwbwbwbwbwbwb wbwbwbwbwbwbwbwbwbwb www bwwbbbwbbbwbbbwbbbwb bbw bbb wbbbwbbbwbbbwbbbwb bbw\n",
+      "bbb wbbbwbbbwbbbwbbbwb bbwbbbwbbbwwbwwwbwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb\n",
+      "wwwb wwwb wwwb www bwwwbwwwbwwwbwwbwwi have used b for the black tiles and w for the white ones it\n",
+      "took me a while to figure out that the frieze is steganography concealing the keyword for the cipher\n",
+      "in chapter five without jodie i am not sure where to go next there are only two possibilities as far\n",
+      "as i can see but i have no idea where one of them is and as far as i can tell no one else knows\n",
+      "either so i guess i will head for olympia see you there\n"
+     ]
+    }
+   ],
+   "source": [
+    "cipher_translation = ''.maketrans(cipher_alphabet, string.ascii_lowercase)\n",
+    "print(prettify(sanitise(ca).translate(cipher_translation)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'etoainhsrdlumwycfgpbvkxjqz'"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ltrs = [p[0] for p in english_counts.most_common()]\n",
+    "cat(ltrs)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'yrkfdlbqpoisjcumzaewthgxnv'"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ctls =  [p[0] for p in collections.Counter(sanitise(ca_text)).most_common()]\n",
+    "cat(ctls)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'A': 'g',\n",
+       " 'B': 'h',\n",
+       " 'C': 'w',\n",
+       " 'D': 'i',\n",
+       " 'E': 'p',\n",
+       " 'F': 'a',\n",
+       " 'G': 'x',\n",
+       " 'H': 'k',\n",
+       " 'I': 'l',\n",
+       " 'J': 'm',\n",
+       " 'K': 'o',\n",
+       " 'L': 'n',\n",
+       " 'M': 'c',\n",
+       " 'N': 'q',\n",
+       " 'O': 'd',\n",
+       " 'P': 'r',\n",
+       " 'Q': 's',\n",
+       " 'R': 't',\n",
+       " 'S': 'u',\n",
+       " 'T': 'v',\n",
+       " 'U': 'y',\n",
+       " 'V': 'z',\n",
+       " 'W': 'b',\n",
+       " 'X': 'j',\n",
+       " 'Y': 'e',\n",
+       " 'Z': 'f'}"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "trans = {pr[1].upper(): pr[0] for pr in zip(ltrs, ctls)}\n",
+    "trans"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "mirbi mxnda ehisg noeai rrave daose lwuki sclio oedpu tshed adotm iketh ereod ejvnu sthel nwils titan othao kshem ibhiv epeeo kadoi ccedp utthe rehis peeoo nrios nmdem iodio dther eason thaog muwht ngnno herrn nmhid peeor iosiw kedio dshel efton messi geput snmet haogt ellsm eshea snkio dyesh nuldm nveno athao kshem ibhiv eclio oedth asmei oyhal eahiv ethed nwume otxnd aeyio tedfr nmlno dnoad notko nyhny sheko eyput thefa fthwh icter yisha ddeoa oiwiv atbao istno elaot elaos nmere miaos aothe eches usrnn mitth eprat ashmu seuma tyise owrbc tedus aogio nther cnlbi lchip etaww acher aoveo tedao theoa oetee othwe oturb aiske dthem useum tntes tatio dthed nwume otasi utheo tawsn agues sthea mcera ilwac hersw hnnlr eillb hidmn vedno cerhi csash nuldo thive peeos urcra sedif terth edasw nverb itpnd rumpu tatle ivesm eynod eraog yhite lseth ebdev elnce dnoen ddfei turey isifr aejer uooao grnuo dthre esade snfth elaot elwno sasta ognfi saogl ernyn fpliw kiody hatet alest hitth emuse umtha okyer eidde daoth ernmi ocera ndthe breid aoseq ueowe yyppy yypyy ypyyy pyyyp yyypy yypyy ypyyy pyyyp yyypy yypyy ypyyy pyyyp yyypy yypyy ypyyy pyyyp pyyyp yypyp ypypy pypyp ypypy pypyp ypypy pypyp ypypy pypyp ypypy pypyp ypypy pypyp ypypy pypyp ypyyp yyypy pppyp ppypp pyppp ypppy pppyp ppypp pyppp ypppy pppyp ppypp pyppp ypppy pppyp ppypp pyppp ypyyy pyyyp yyypy yypyy ypyyy pyyyp yyypy yypyy ypyyy pyyyp yyypy yypyy ypyyy pyyyp yyypy yypyy ypyyy pyyyp yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yypyy ypyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy ypyyy pyyyy pyyyp ppyyy yyppp yyypy yypyy ypyyy pyyyy pppyy pyyyp ypppy yyppp pyypp pyyyp ppyyp ppypy yypyy yypyp yypyy pyyyp yyyyy pypyy ppyyp yypyp yyyyp yyypp yppyp yypyy pyyyy ypyyp yyypy yyypy yypyy ypyyp yyypy pyyyp ypyyy yypyy ypypy pypyp yyypy yypyy ypypy pypyy pyypy yyyyp yyypy ypyyy ypyyp yyypy yyppp ppypp ppyyp yyyyy ppppp ypypy pyppp ppyyy pyyyp yyypy ppppy ypppy yyppp pyyyp yyyyp yyypy yypyy pyyyp ypypy yypyy yyypy yypyp ypypy pyyyp yyypy yypyy ypypy yyyyp yyyyy pypyy yypyy yypyy pyyyp yyypy yypyp yypyy ypyyy ypyyy pypyy ppypy yypyy ypyyy pyyyp ypyyy yypyy yyypy ypyyy pyyyy pyyyp yyypy ypyyy pypyy ypyyy pppyp yyypy pyyyp ypyyy pyypp pyypy yypyp yyyyy ppppy ypyyy pyppp yyppp ypyyy pyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy pyyyp yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yyyyy yypyy ypypy yypyy ypyyy pyyyp yyypy yypyy ypyyy pyyyp yyypy yypyy ypyyy pyyyp yyypy yypyy ypyyy pyyyp ypyyy pypyp ypypy pypyp ypypy pypyp ypypy pypyp ypypy pypyp ypypy pypyp ypypy pypyp ypypy pypyp ypypy yypyy pppyp ppypp pyppp ypppy pppyp ppypp pyppp ypppy pppyp ppypp pyppp ypppy pppyp ppypp pyppp yypyy ypyyp yyypy yypyy ypyyy pyyyp yyypy yypyy ypyyy pyyyp yyypy yypyy ypyyy pyyyp yyypy yypyy ypyyp yyahi veuse dpfnr thepl iwkta lesio dyfnr theyh ateno esatt nnkme iyhal etnfa guren utthi tthef raeje asste giong richb wnowe ilaog theke bynrd fnrth ewach eraow hicte rfave yathn utxnd aeaim ontsu reyhe retng noezt there ireno lbtyn cnssa palat aesis firis awios eeput ahive onade iyher enoen fthem asiod isfir isawi otell onnoe elsek onyse ather snagu essay allhe idfnr nlbmc aisee bnuth ere\n"
+     ]
+    }
+   ],
+   "source": [
+    "tt = ''.maketrans(trans)\n",
+    "print(ca.translate(tt))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "maryam jodie has gone i arrived in selcuk as planned but she didnt make the rendezvous the local\n",
+      "station think she may have been kidnapped but there has been no ransom demand and there is nothing\n",
+      "much to go on her room had been ransacked and she left no message but something tells me she is ok\n",
+      "and we should move on i think she may have planned this meanwhile i have the document jodie wanted\n",
+      "from london i dont know how she knew but the fifth chapter was hidden in a cavity in a stone lintel\n",
+      "in some remains in the ephesus room at the british museum it was encrypted using another poly\n",
+      "alphabetic cipher invented in the nineteenth century i asked the museum to test it and the document\n",
+      "is authentic so i guess the imperial cipher school really had moved on perhaps i shouldnt have been\n",
+      "surprised after the discovery at bodrum but it leaves me wondering what else they developed one odd\n",
+      "feature was a frieze running round three sides of the lintel consisting of a single row of\n",
+      "blackandwhite tiles that the museum think were added in the roman period they read in sequence\n",
+      "wwbbwwwbwwwbwwwbwwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb www bbw\n",
+      "wwbw wbwbwbwbwbwbwbwbwbw bwbwbwbwbwbwbwbwbwbw bwbwbwbwbwbwbwbwbwbw bwbwbwbwbwbwbwbwbwwb www\n",
+      "bwbbbwbbbwbbbwbbbwb bbwbbbwbbbwbbbwbbbwb bbwbbbwbbbwbbbwbbbwb bbwbbbwbbbwbbbwbbbwb wwwb wwwb wwwb\n",
+      "wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb www\n",
+      "www www www www www www www www www www www www www www www www www www www www www www www www wwbw\n",
+      "wwbw www www www www www www www www www www www www www www www www www www www www www www www www\n",
+      "www wwwb wwwb www wb wwwb bbw wwww bbb wwwb wwwb wwwb www bw www bbb wwbw wwbw bbb www bbbb\n",
+      "wwbbbwwwbbbwwbbbwb www bwwwwbwbwwbwwbwwwbww www bwbwwbbwwbwwbwbwwwwb www bbw bbw\n",
+      "bwwbwwbwwwwwbwwbwwwb www wb www bwwwbwwbwwwbwbwwwbwb www wwbwwwbwbwbwbwbwwwb www bwwwbwbwbwbwwbwwbww\n",
+      "www bwwwbwwbwwwwbwwbwwwb www bbb bbw bbbb wwbw wwww bbb bbw bwbwbwbbbbbwwwbwwwbw wwbw bbbb ww bbb\n",
+      "www bbbb wwwb www wb www bwwwbwwbwwwbwbwbwwwb www wwbwwwbwbwbwbwbwwwb wwwb wwwb www bwb www wwbw\n",
+      "wwww bwbwwwwbwwwwbwwbwwwb www bwwwbwbwwbwwwbwwwwb www bwbwwbbwbwwwbwwwb wwwb www bwb www wwbw www wb\n",
+      "wwbw wwbw www bwwwbwwwbwwbwwwbwb wwwb www bbb wbwwwbwbwwwbwbwwwbww bbb wwbw wwbw bww www bbbb wwbw\n",
+      "wwbwbbbwwbbbwbwwwbww www www www www www www www www www www www www www www www www www www www www\n",
+      "www www www www www wwbw wwbw www www www www www www www www www www www www www www www www www\n",
+      "www www www www www www www www wbwwwbwbwwwbwwwbwwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb\n",
+      "wwwb wwwb wwwb wwwb wwwb wwwb www bwb www bwbwbwbwbwbwbwbwbwb wbwbwbwbwbwbwbwbwbwb\n",
+      "wbwbwbwbwbwbwbwbwbwb wbwbwbwbwbwbwbwbwbwb www bwwbbbwbbbwbbbwbbbwb bbw bbb wbbbwbbbwbbbwbbbwb bbw\n",
+      "bbb wbbbwbbbwbbbwbbbwb bbwbbbwbbbwwbwwwbwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb\n",
+      "wwwb wwwb wwwb www bwwwbwwwbwwwbwwbwwi have used b for the black tiles and w for the white ones it\n",
+      "took me a while to figure out that the frieze is steganography concealing the keyword for the cipher\n",
+      "in chapter five without jodie i am not sure where to go next there are only two possibilities as far\n",
+      "as i can see but i have no idea where one of them is and as far as i can tell no one else knows\n",
+      "either so i guess i will head for olympia see you there\n"
+     ]
+    }
+   ],
+   "source": [
+    "trans = {\n",
+    " 'A': 'g',\n",
+    " 'B': 'h',\n",
+    " 'C': 'c',\n",
+    " 'D': 'a',\n",
+    " 'E': 'b',\n",
+    " 'F': 'i',\n",
+    " 'G': 'j',\n",
+    " 'H': 'k',\n",
+    " 'I': 'l',\n",
+    " 'J': 'm',\n",
+    " 'K': 'n',\n",
+    " 'L': 'o',\n",
+    " 'M': 'p',\n",
+    " 'N': 'q',\n",
+    " 'O': 'd',\n",
+    " 'P': 'r',\n",
+    " 'Q': 's',\n",
+    " 'R': 't',\n",
+    " 'S': 'u',\n",
+    " 'T': 'v',\n",
+    " 'U': 'w',\n",
+    " 'V': 'x',\n",
+    " 'W': 'y',\n",
+    " 'X': 'z',\n",
+    " 'Y': 'e',\n",
+    " 'Z': 'f'}\n",
+    "\n",
+    "tt = ''.maketrans(trans)\n",
+    "print(prettify(sanitise(ca.translate(tt))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'A': 'g',\n",
+       " 'B': 'h',\n",
+       " 'C': 'c',\n",
+       " 'D': 'a',\n",
+       " 'E': 'b',\n",
+       " 'F': 'i',\n",
+       " 'G': 'j',\n",
+       " 'H': 'k',\n",
+       " 'I': 'l',\n",
+       " 'J': 'm',\n",
+       " 'K': 'n',\n",
+       " 'L': 'o',\n",
+       " 'M': 'p',\n",
+       " 'N': 'q',\n",
+       " 'O': 'd',\n",
+       " 'P': 'r',\n",
+       " 'Q': 's',\n",
+       " 'R': 't',\n",
+       " 'S': 'u',\n",
+       " 'T': 'v',\n",
+       " 'U': 'w',\n",
+       " 'V': 'x',\n",
+       " 'W': 'y',\n",
+       " 'X': 'z',\n",
+       " 'Y': 'e',\n",
+       " 'Z': 'f'}"
+      ]
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "trans"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'a': 'D',\n",
+       " 'b': 'E',\n",
+       " 'c': 'C',\n",
+       " 'd': 'O',\n",
+       " 'e': 'Y',\n",
+       " 'f': 'Z',\n",
+       " 'g': 'A',\n",
+       " 'h': 'B',\n",
+       " 'i': 'F',\n",
+       " 'j': 'G',\n",
+       " 'k': 'H',\n",
+       " 'l': 'I',\n",
+       " 'm': 'J',\n",
+       " 'n': 'K',\n",
+       " 'o': 'L',\n",
+       " 'p': 'M',\n",
+       " 'q': 'N',\n",
+       " 'r': 'P',\n",
+       " 's': 'Q',\n",
+       " 't': 'R',\n",
+       " 'u': 'S',\n",
+       " 'v': 'T',\n",
+       " 'w': 'U',\n",
+       " 'x': 'V',\n",
+       " 'y': 'W',\n",
+       " 'z': 'X'}"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "{v: k for k, v in trans.items()}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "maryam jodie has gone i arrived in selcuk as planned but she didnt make the rendezvous the local\n",
+      "station think she may have been kidnapped but there has been no ransom demand and there is nothing\n",
+      "much to go on her room had been ransacked and she left no message but something tells me she is ok\n",
+      "and we should move on i think she may have planned this meanwhile i have the document jodie wanted\n",
+      "from london i dont know how she knew but the fifth chapter was hidden in a cavity in a stone lintel\n",
+      "in some remains in the ephesus room at the british museum it was encrypted using another poly\n",
+      "alphabetic cipher invented in the nineteenth century i asked the museum to test it and the document\n",
+      "is authentic so i guess the imperial cipher school really had moved on perhaps i shouldnt have been\n",
+      "surprised after the discovery at bodrum but it leaves me wondering what else they developed one odd\n",
+      "feature was a frieze running round three sides of the lintel consisting of a single row of\n",
+      "blackandwhite tiles that the museum think were added in the roman period they read in sequence\n",
+      "wwbbwwwbwwwbwwwbwwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb www bbw\n",
+      "wwbw wbwbwbwbwbwbwbwbwbw bwbwbwbwbwbwbwbwbwbw bwbwbwbwbwbwbwbwbwbw bwbwbwbwbwbwbwbwbwwb www\n",
+      "bwbbbwbbbwbbbwbbbwb bbwbbbwbbbwbbbwbbbwb bbwbbbwbbbwbbbwbbbwb bbwbbbwbbbwbbbwbbbwb wwwb wwwb wwwb\n",
+      "wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb www\n",
+      "www www www www www www www www www www www www www www www www www www www www www www www www wwbw\n",
+      "wwbw www www www www www www www www www www www www www www www www www www www www www www www www\n",
+      "www wwwb wwwb www wb wwwb bbw wwww bbb wwwb wwwb wwwb www bw www bbb wwbw wwbw bbb www bbbb\n",
+      "wwbbbwwwbbbwwbbbwb www bwwwwbwbwwbwwbwwwbww www bwbwwbbwwbwwbwbwwwwb www bbw bbw\n",
+      "bwwbwwbwwwwwbwwbwwwb www wb www bwwwbwwbwwwbwbwwwbwb www wwbwwwbwbwbwbwbwwwb www bwwwbwbwbwbwwbwwbww\n",
+      "www bwwwbwwbwwwwbwwbwwwb www bbb bbw bbbb wwbw wwww bbb bbw bwbwbwbbbbbwwwbwwwbw wwbw bbbb ww bbb\n",
+      "www bbbb wwwb www wb www bwwwbwwbwwwbwbwbwwwb www wwbwwwbwbwbwbwbwwwb wwwb wwwb www bwb www wwbw\n",
+      "wwww bwbwwwwbwwwwbwwbwwwb www bwwwbwbwwbwwwbwwwwb www bwbwwbbwbwwwbwwwb wwwb www bwb www wwbw www wb\n",
+      "wwbw wwbw www bwwwbwwwbwwbwwwbwb wwwb www bbb wbwwwbwbwwwbwbwwwbww bbb wwbw wwbw bww www bbbb wwbw\n",
+      "wwbwbbbwwbbbwbwwwbww www www www www www www www www www www www www www www www www www www www www\n",
+      "www www www www www wwbw wwbw www www www www www www www www www www www www www www www www www\n",
+      "www www www www www www www www wbwwwbwbwwwbwwwbwwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb\n",
+      "wwwb wwwb wwwb wwwb wwwb wwwb www bwb www bwbwbwbwbwbwbwbwbwb wbwbwbwbwbwbwbwbwbwb\n",
+      "wbwbwbwbwbwbwbwbwbwb wbwbwbwbwbwbwbwbwbwb www bwwbbbwbbbwbbbwbbbwb bbw bbb wbbbwbbbwbbbwbbbwb bbw\n",
+      "bbb wbbbwbbbwbbbwbbbwb bbwbbbwbbbwwbwwwbwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb\n",
+      "wwwb wwwb wwwb www bwwwbwwwbwwwbwwbwwi have used b for the black tiles and w for the white ones it\n",
+      "took me a while to figure out that the frieze is steganography concealing the keyword for the cipher\n",
+      "in chapter five without jodie i am not sure where to go next there are only two possibilities as far\n",
+      "as i can see but i have no idea where one of them is and as far as i can tell no one else knows\n",
+      "either so i guess i will head for olympia see you there\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(keyword_decipher(sanitise(ca), ka[0], ka[1])))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "3362"
+      ]
+     },
+     "execution_count": 25,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('5a.plaintext', 'w').write(prettify(keyword_decipher(sanitise(ca), ka[0], ka[1])))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "bkeyt = sanitise('''\n",
+    "wwbbwwwbwwwbwwwbwwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb www bbw\n",
+    "wwbw wbwbwbwbwbwbwbwbwbw bwbwbwbwbwbwbwbwbwbw bwbwbwbwbwbwbwbwbwbw bwbwbwbwbwbwbwbwbwwb www\n",
+    "bwbbbwbbbwbbbwbbbwb bbwbbbwbbbwbbbwbbbwb bbwbbbwbbbwbbbwbbbwb bbwbbbwbbbwbbbwbbbwb wwwb wwwb wwwb\n",
+    "wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb www\n",
+    "www www www www www www www www www www www www www www www www www www www www www www www www wwbw\n",
+    "wwbw www www www www www www www www www www www www www www www www www www www www www www www www\n",
+    "www wwwb wwwb www wb wwwb bbw wwww bbb wwwb wwwb wwwb www bw www bbb wwbw wwbw bbb www bbbb\n",
+    "wwbbbwwwbbbwwbbbwb www bwwwwbwbwwbwwbwwwbww www bwbwwbbwwbwwbwbwwwwb www bbw bbw\n",
+    "bwwbwwbwwwwwbwwbwwwb www wb www bwwwbwwbwwwbwbwwwbwb www wwbwwwbwbwbwbwbwwwb www bwwwbwbwbwbwwbwwbww\n",
+    "www bwwwbwwbwwwwbwwbwwwb www bbb bbw bbbb wwbw wwww bbb bbw bwbwbwbbbbbwwwbwwwbw wwbw bbbb ww bbb\n",
+    "www bbbb wwwb www wb www bwwwbwwbwwwbwbwbwwwb www wwbwwwbwbwbwbwbwwwb wwwb wwwb www bwb www wwbw\n",
+    "wwww bwbwwwwbwwwwbwwbwwwb www bwwwbwbwwbwwwbwwwwb www bwbwwbbwbwwwbwwwb wwwb www bwb www wwbw www wb\n",
+    "wwbw wwbw www bwwwbwwwbwwbwwwbwb wwwb www bbb wbwwwbwbwwwbwbwwwbww bbb wwbw wwbw bww www bbbb wwbw\n",
+    "wwbwbbbwwbbbwbwwwbww www www www www www www www www www www www www www www www www www www www www\n",
+    "www www www www www wwbw wwbw www www www www www www www www www www www www www www www www www\n",
+    "www www www www www www www www wbwwwbwbwwwbwwwbwwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb\n",
+    "wwwb wwwb wwwb wwwb wwwb wwwb www bwb www bwbwbwbwbwbwbwbwbwb wbwbwbwbwbwbwbwbwbwb\n",
+    "wbwbwbwbwbwbwbwbwbwb wbwbwbwbwbwbwbwbwbwb www bwwbbbwbbbwbbbwbbbwb bbw bbb wbbbwbbbwbbbwbbbwb bbw\n",
+    "bbb wbbbwbbbwbbbwbbbwb bbwbbbwbbbwwbwwwbwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb\n",
+    "wwwb wwwb wwwb www bwwwbwwwbwwwbwwbww''')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1577"
+      ]
+     },
+     "execution_count": 27,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(bkeyt)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1577"
+      ]
+     },
+     "execution_count": 28,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "19 * 83"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['  ⌷⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷⌷  ',\n",
+       " ' ⌷  ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷  ⌷ ',\n",
+       " '  ⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷  ',\n",
+       " ' ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷ ',\n",
+       " '  ⌷                                                                             ⌷  ',\n",
+       " ' ⌷                                                                               ⌷ ',\n",
+       " '  ⌷    ⌷   ⌷⌷⌷     ⌷⌷⌷   ⌷   ⌷   ⌷   ⌷    ⌷⌷⌷  ⌷   ⌷ ⌷⌷⌷   ⌷⌷⌷⌷  ⌷⌷⌷   ⌷⌷⌷  ⌷⌷⌷ ⌷  ',\n",
+       " ' ⌷    ⌷ ⌷  ⌷  ⌷   ⌷     ⌷ ⌷  ⌷⌷  ⌷  ⌷ ⌷    ⌷   ⌷⌷ ⌷⌷ ⌷  ⌷  ⌷     ⌷  ⌷   ⌷    ⌷   ⌷ ',\n",
+       " '  ⌷  ⌷   ⌷ ⌷   ⌷ ⌷     ⌷   ⌷ ⌷ ⌷ ⌷ ⌷   ⌷   ⌷   ⌷ ⌷ ⌷ ⌷  ⌷  ⌷     ⌷   ⌷  ⌷    ⌷  ⌷  ',\n",
+       " ' ⌷   ⌷⌷⌷⌷⌷ ⌷⌷⌷⌷  ⌷     ⌷⌷⌷⌷⌷ ⌷ ⌷ ⌷ ⌷⌷⌷⌷⌷   ⌷   ⌷   ⌷ ⌷⌷⌷⌷  ⌷⌷⌷   ⌷⌷⌷⌷   ⌷    ⌷   ⌷ ',\n",
+       " '  ⌷  ⌷   ⌷ ⌷ ⌷   ⌷     ⌷   ⌷ ⌷ ⌷ ⌷ ⌷   ⌷   ⌷   ⌷   ⌷ ⌷     ⌷     ⌷ ⌷    ⌷    ⌷  ⌷  ',\n",
+       " ' ⌷   ⌷   ⌷ ⌷  ⌷   ⌷    ⌷   ⌷ ⌷  ⌷⌷ ⌷   ⌷   ⌷   ⌷   ⌷ ⌷     ⌷     ⌷  ⌷   ⌷    ⌷   ⌷ ',\n",
+       " '  ⌷  ⌷   ⌷ ⌷   ⌷   ⌷⌷⌷ ⌷   ⌷ ⌷   ⌷ ⌷   ⌷  ⌷⌷⌷  ⌷   ⌷ ⌷     ⌷⌷⌷⌷  ⌷   ⌷ ⌷⌷⌷  ⌷⌷⌷ ⌷  ',\n",
+       " ' ⌷                                                                               ⌷ ',\n",
+       " '  ⌷                                                                             ⌷  ',\n",
+       " ' ⌷ ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷ ⌷ ',\n",
+       " '  ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷ ⌷  ',\n",
+       " ' ⌷  ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷ ⌷⌷⌷  ⌷ ',\n",
+       " '  ⌷  ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷   ⌷  ⌷  ']"
+      ]
+     },
+     "execution_count": 29,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "tt = ''.maketrans({'w': ' ', 'b': '⌷'})\n",
+    "chunks(bkeyt.translate(tt), 83)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "scb = sanitise(cb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('fwruffnquevmp', -1750.4576000271347)"
+      ]
+     },
+     "execution_count": 31,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kb, score = vigenere_frequency_break(cb)\n",
+    "kb, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'nieyqmhcenwlqvchdporosweiohtsshreoihpsvrvusdcostmjezkdeytdhrtasupknropbklngeutgnssthjhhnowgbdwvucncdvofhbdltfpvobiuicirayodpwkpoutibtgcenuhpwachchnbrjydhsfvhqszeuvdcpswatvzmxhsiigkobvcagqcdikfstrvkfggbdkvcvstuvufienwiniasbcecmvdwemkwgtnsyjridowjamhuhnrvxssgewikqxpxhashvwvteulpavioctweavlhtikkkximoikdloikrwswfiojrynulrsgtoktknqcporlruoigivdpeddhrntdmrnucnrioiuetpdnftaipjrewjqtercxzvydhiswrtrneonknnfsyrifcdhedoweptjrechehcptdcehirohbcpniloorntrrrtohgeoandszehilxywfqkrgnphglvcojfbetcietpqmfetkalnahiwixdppersmrihrctseahkhtifbokasoozrjgvvkehjsufarunbrtiswzdmriwcrovhdsdeihdteiiustmjupvkhdiisibjloyrdpyxkusdlwfpsehvevdoiudppehzgvcewnhifrvkfggbdkbidptartnotloihpseehrdipeotmlwbcousicucctsktsrlritcanhpdmrehuinioiuuwirsxtanvjshfwyrkacfihfctdipytegvprdowhfldhycrqhfctswdbnagevitctsufsrofoccprycjgnifeikrthnowgcedfedjwiisdtihszeecfvlwjqgehoeicssaqflthagmncpvvifnreneoiioiulytddhuhkrtzsdpevphodehkctsvfhltophksiepsgcohnrnuseajettlhdwhiepjwcenbtbuecihpijncohouidiqjikpovimvsrfridohvchdporhrmhlpnikpacvjiswwgszeyxrcpragclkvxbporlruoigoviferifridicrskiporsyypwgprszenephnicczvttucvqesuiivqleesvfrhcfgchuswrocjslotcnxtiiswkoieatruninitradpaortylcouoahdpehgukcvlrmrafrntaovetrxvyinpenvniquglltisxgy'"
+      ]
+     },
+     "execution_count": 32,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "vigenere_decipher(sanitise(cb), kb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('arcanaimperii', -1506.8637359274674)"
+      ]
+     },
+     "execution_count": 33,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kb, score = beaufort_frequency_break(cb)\n",
+    "kb, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'inhisjournaldatedtheidesofoctoberintheyearoftheconsulshipsofcaeceliustulliuscapitopomponianusplotiusfirmusandgaiuscorneliusgallicanusagricolawrotethemysteryofthebattleatcamulodonumisatlastsolvedcalgacusmaybeabarbariannowbuthewasaromancitizenthenwhobetrayedusallforloveofabarbarianithastakenallmyskillsasaleaderofmentokeephimalivethelegionnairesspendtheireveningsdesigningnewandcruelwaystoexecutehiminrevengefortheshamehebroughtuponusbuthislifeispreciousitistheonlycardlefttoplayinoursearchforsalvationandthereturnofthestolenaquilaeifwecanalsorecoverthecodexthenperhapsitslosscanbeconcealedandourliveswillbesparedreleasingtheromantraitorcalgacusmusthavestuckintheproudagricolasthroatbuthemadeapactwiththeremainingcaledoniiandtravellednorthtoexchangetheprisonerfortheaquilaeandthecodexbutthecunningcaledoniantribesmansetanothertrapandpresentedagricolawithaforgerycunninglyassembledwithpagesfromthebooksstolenwhenthetriberansackedmonsgraupiusfortoolongthesonsofromehadunderestimatedthepeopleinbritanniaandwhiletheaquilaofthelegionhadbeenrestoredbytheexchangetheirhonourwasnotagricolafacedareturntoromehumiliationandalmostcertaindeaththesixthchapterofmytaleofwoeisguardedbylightningbullandoak'"
+      ]
+     },
+     "execution_count": 34,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "beaufort_decipher(sanitise(cb), kb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 47,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('arcanaimperii', -1506.8637359274674)"
+      ]
+     },
+     "execution_count": 47,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kb, sb = beaufort_frequency_break(cb)\n",
+    "kb, sb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 48,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "In his Journal dated the Ides of October in the year of the consulships of Caecelius Tullius Capito\n",
+      "Pomponianus Plotius Firmus and Gaius Cornelius Gallicanus, Agricola wrote “The mystery of the battle\n",
+      "at Camulodonum is at last solved. Calgacus may be a Barbarian now, but he was a Roman citizen then,\n",
+      "who betrayed us all for love of a barbarian. It has taken all my skills as a leader of men to keep\n",
+      "him alive. The Legionnaires spend their evenings designing new and cruel ways to execute him in\n",
+      "revenge for the shame he brought upon us, but his life is precious. It is the only card left to play\n",
+      "in our search for salvation and the return of the stolen Aquilae. If we can also recover the Codex\n",
+      "then perhaps its loss can be concealed and our lives will be spared.” Releasing the Roman traitor\n",
+      "Calgacus must have stuck in the proud Agricola’s throat, but he made a pact with the remaining\n",
+      "Caledonii and travelled north to exchange the prisoner for the Aquilae and the Codex. But the\n",
+      "cunning Caledonian tribesman set another trap and presented Agricola with a forgery cunningly\n",
+      "assembled with pages from the books stolen when the tribe ransacked Mons Graupius. For too long the\n",
+      "sons of Rome had underestimated the people in Britannia and while the Aquila of the Legion had been\n",
+      "restored by the exchange, their honour was not. Agricola faced a return to Rome, humiliation and\n",
+      "almost certain death. The sixth chapter of my tale of woe is guarded by lightning, bull and oak.\n"
+     ]
+    }
+   ],
+   "source": [
+    "pub = depunctuate(cb)\n",
+    "pb = beaufort_decipher(scb, kb)\n",
+    "print(lcat(tpack(repunctuate(pb, pub).split())))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 49,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1470"
+      ]
+     },
+     "execution_count": 49,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('5b.plaintext', 'w').write(lcat(tpack(repunctuate(pb, pub).split())))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/2017/2017-challenge6.ipynb b/2017/2017-challenge6.ipynb
new file mode 100644 (file)
index 0000000..a03628e
--- /dev/null
@@ -0,0 +1,1544 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import os,sys,inspect, collections\n",
+    "currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))\n",
+    "parentdir = os.path.dirname(currentdir)\n",
+    "sys.path.insert(0,parentdir) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.affine import *\n",
+    "from cipher.vigenere import *\n",
+    "from cipher.keyword_cipher import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "from support.language_models import *\n",
+    "from support.plot_frequency_histogram import *\n",
+    "\n",
+    "ca = open('6a.ciphertext').read()\n",
+    "cb = open('6b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Lelqzq, C xnyhv Isxad en Gkcghhe ufc wbw gem ugejldv maw efjdexq. Rly zzh vwdr fwzhcff xbw LMXSR sjwqenauim gm e qakh agnwy ugemw zvimmh Mwkgoc leeamk u dnx ix msckd evgtx fgnocff jij sly ehwmamk wzztnwq en lgi Nwltfw nj Ujsigar. Xbss kund qy lhqy ln vylqmynd mn xqsg Bnhcw'r jladrx ss xbw Avclhwb Etwyml, ababl bsr e wgkpyusmif nj ujsizsbxm xqsg lgi Nwltfw. Isxad wuqr wbw jryo vi qgtpx xhkojd sol vlyjd xi yn ryps. Xbw bpow vem am xbw kswssmifr. Xbw emlks shw vem ss xbw Fvyss Tsjzqcv, sly kdgifc en lgi zgqx ix Peclaes ogmwz vem ttmfl evie sly jtmhk nj nzd Pcygxbgtwy ss Efwwehvqmu smh nzd xbaqh if Qlivdw, uenra lgi lmhrm ge xbw Bsfgrwok. Sly Cmmazs'w wsrxfw zx Vgcvoe vem ttmfl evie sly jdquamw ix sly Ezymgkioe zx Bskmwsqrukrym, zdrww sly “yqepw” semc nj amzvxamk nzd figj. Wi skp zaui wzztnwqw qwqi zgtrx ss xbw rmnw nj ifd sz lgi Mwuih Onrxwqw ix sly smgcwmx qgqpx. Lgi ifkc lwlecfhra dngulhshk zvy lgi Mlzxow nj Twtw ul Npseomu smh nzd Luffmhy Felvdrm ge Futxpif, zrx fn-shw gem smc cvde qzdvy lgi asqhyfr qcygx bsui vwdr, mg sly gmps hkeww vi wgtpx yn ryps mm Gkcghhe. Nzd gfmd en lgi yfc sz ugejldv zaui jghrnk rxlshkbl slyjd, wcfbi faflnamk, vmkp ufc suc zvy skp mqlfidr sz Rdym. Od wbgtpx td wuxd lyjd fyuzymw Isxad'w hwsaijj luk rihl gil ssxuujilk nr ng Kshvnr vq kesamk u dnra lqecd nj zgqkyv cswmlihlr vyndefamk nzd piuzxcgm sz ugejldv zaui. Nzzx vgtkbl tw yfnyaz smgw ss fgbenw zrx vdgchgil ugejldv maw. Ay zzh vwdr nzhreamk utnyn lgi ynnpolhsh ge xbw Hqjwqmud Bmjzdvm. Lzgcltw okdh vgsl nzd Zcydryjd ehv Aiumesll bmjzdvm ogmwz zvy hnpssktbsainab zyjrmifr sz lgi Wsdwuj rlcxs, ehv zx zaqwn od emktqyv slul bluhsil khb qgtpx td ihuqcjldh nzd wued auq. Vi qwqi udlsml qmazs. Qysmabaki Dgcmy'k trypoiwldh nskihl esl xnvawqc bsr kcndr gw zr cvde. C lgmhc vi gafln td evdd xi ltvh gtv yfdqcwr sh gmi ufnxbwq fs wwtfghxcff lyj fmzl, ayn A jrio gil utvlwmx zgbym ar jcytvcff sol vlyjd sh wzvnz sly kdzyfsl qgmhyj lmazs fy.\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(ca)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "pua = depunctuate(ca)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('zeus', -1960.8847716972107)"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ka, score = vigenere_frequency_break(ca)\n",
+    "ka, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "\"Maryam, I found Jodie at Olympia and she has chapter six already. She had been leading the MIDAS operatives on a wild goose chase around Selcuk making a lot of noise about looking for the missing chapter at the Temple of Artemis. That gave me time to retrieve it from Jodie's friend at the British Museum, which has a collection of artefacts from the Temple. Jodie says she knew we would figure out where to go next. The clue was in the locations. The first one was at the Great Pyramid, the second at the fort of Qaitbay which was built from the ruins of the Lighthouse at Alexandria and the third on Rhodes, among the ruins of the Colossus. The Knight's castle at Bodrum was built from the remains of the Mausoleum at Halicarnassus, hence the “grave” task of guarding the book. So all five chapters were found at the site of one of the Seven Wonders of the ancient world. The only remaining locations are the Statue of Zeus at Olympia and the Hanging Gardens of Babylon, and no-one has any idea where the gardens might have been, so the only place we could go next is Olympia. The clue at the end of chapter five points straight there, since lighting, bull and oak are all symbols of Zeus. We should be safe here because Jodie's network has sent her attackers on to London by laying a long trail of forged documents revealing the location of chapter five. That bought us enough time to locate and decipher chapter six. We had been thinking about the evolution of the Imperial Ciphers. Tacitus used both the Vigenere and Beaufort ciphers which are polyalphabetic versions of the Caesar shift, and at first we assumed that chapter six would be encrypted the same way. We were almost right. Meanwhile Jodie's unexpected talent for forgery has given me an idea. I think we might be able to turn our enemies on one another by exploiting her gift, but I know her current focus is figuring out where on earth the seventh wonder might be.\""
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pa = vigenere_decipher(sanitise(ca), ka)\n",
+    "repunctuate(pa, pua)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Maryam, I found Jodie at Olympia and she has chapter six already. She had been leading the MIDAS\n",
+      "operatives on a wild goose chase around Selcuk making a lot of noise about looking for the missing\n",
+      "chapter at the Temple of Artemis. That gave me time to retrieve it from Jodie's friend at the\n",
+      "British Museum, which has a collection of artefacts from the Temple. Jodie says she knew we would\n",
+      "figure out where to go next. The clue was in the locations. The first one was at the Great Pyramid,\n",
+      "the second at the fort of Qaitbay which was built from the ruins of the Lighthouse at Alexandria and\n",
+      "the third on Rhodes, among the ruins of the Colossus. The Knight's castle at Bodrum was built from\n",
+      "the remains of the Mausoleum at Halicarnassus, hence the “grave” task of guarding the book. So all\n",
+      "five chapters were found at the site of one of the Seven Wonders of the ancient world. The only\n",
+      "remaining locations are the Statue of Zeus at Olympia and the Hanging Gardens of Babylon, and no-one\n",
+      "has any idea where the gardens might have been, so the only place we could go next is Olympia. The\n",
+      "clue at the end of chapter five points straight there, since lighting, bull and oak are all symbols\n",
+      "of Zeus. We should be safe here because Jodie's network has sent her attackers on to London by\n",
+      "laying a long trail of forged documents revealing the location of chapter five. That bought us\n",
+      "enough time to locate and decipher chapter six. We had been thinking about the evolution of the\n",
+      "Imperial Ciphers. Tacitus used both the Vigenere and Beaufort ciphers which are polyalphabetic\n",
+      "versions of the Caesar shift, and at first we assumed that chapter six would be encrypted the same\n",
+      "way. We were almost right. Meanwhile Jodie's unexpected talent for forgery has given me an idea. I\n",
+      "think we might be able to turn our enemies on one another by exploiting her gift, but I know her\n",
+      "current focus is figuring out where on earth the seventh wonder might be.\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(repunctuate(pa, pua).split())))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1932"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('6a.plaintext', 'w').write(lcat(tpack(repunctuate(pa, pua).split())))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "pub = depunctuate(cb)\n",
+    "scb = sanitise(cb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('jcarykujniqadmv', -3289.3609056830232)"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kbv, score = vigenere_frequency_break(scb)\n",
+    "kbv, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'Piuo tgnlqva rdn uggsvzeuvlr ed lurg nrubgg ve dyp kztmitehdd flrmqantm bvn enarvtu vd Zgvhrerir rez nttcgegm uy Tlxt lk unu tez la hbt dten, rm mgmggtz ld uog Axruglt. Ot ngrgtz bos orxg utttvyqg ael sn xgutz ybu yq Tlwwuvee uy lluo Enbpueba Gbaiufba yel Ptgrevoa Ntegmvk, zbu hot Uymn pgnt guettlba eem, ggerfkrydd ubg qlna sa tpt Fymtj ttxriltl s ntsgth, welpr sepe ul e atc dldrd mlwhrmgn atyx uog Lvdvo. Soyqisqd fbslmweh hl ggurgm bcn lmhhgm sotnbvh sa tpt Rmbvde rn r kygi ma fybgeut, uog Axruglt nsettm oie unu arht ln yuott tvmigrstm ugetgexn qfm, uy uog abgstcns ma nyxt, bg prn ewrfntm hgvoksord ttemgrhvlra. R nuebbs qrn ggtshtm yq bos Oteeut yr uot ynmsh la hot Gkstgyn, yav, urwte idq, Rhtcfkrr pen ngru ul dcis abvguqq ye ova hrwwqd gnueht pognt nu pra utrztm yq bos Uxsgglt’a lpe fvdmwfveen. Bin mtebo osn r ugvgvlbn avlek ul kt, rrz r srilaar tigeu hy rqq bcn zhvtrmn. Ih prn naqt sn r ttrd dlnn gptd zd ublng hl poye os qrn rlu fggnlryqpe jeype. Roxyttu, xkhtlvtg, yn uot fssarrfg rez hot youd wsnngn fekt ul bcn nmbng; rez ie sblxve tqrstn, erm pognthug jrlua ya urdqtfo pttt raatxydam, nwn eext cen le exq pwsn; rlg zim r nilhpu nloq lr btrgilh kb ova mteho gtpsveu ru hot rgpn lt hlfitu iu zoifjqq. Bouo ndksrhbd pra ceehtratm lq uot ccms-osggrm toxlbt boqv ot brm lgte ggelhum yq sliale lr bos Uxsgglt’a flxkyel. Nlxiuver qlnh ll twxt ie rfflvehceg vot exyihvlba Urpcnuibn Dofbqdin qo uog etc ulittllf ma ubt styivesa. Os qrn sortutm pibo mufbtveu hot atyhurt sgrfg cvuo Syqsnleir rrz otrzam tptgg ul syeagylu Esqhefba. Iu pra sepe uoge ubeu uog xlmo la hot Symtw cyn fuiteqtz. Arqbabvao pgyut yn ovn avlek ru hot rgpn vr y qsvutt ul Seul mebtl vot nvahb mrd laakht ubt jedtema sa Wsd vr uog qtrg yh unu flrnbdaovsa sa Wsgfon Rtttfvrin Ertxgen II rem Difucn Yetyion Olrsgqvbn. “Ct rtg twstanmrd fbrgugm yd yig wmnu kbeinvftrb rdn hggru Gkstgyn Mkyvuire hy ntfont Rsw Gyxrre ve uba Ekhuogge Wiehmyen qfm dgu dyo pgvha uk yt ln uog dlnn yh unu Flztw Ysfbqhsgay. Dlog qgemtg Eoguglqe ora eqgtetd rsvm hot ftvft yh nago r dlna, lbu vn kla nl eyu ggslitt bos Glmgw ygnlgt hvt rsnnieh yn uot qarf votr dlo krd yg ubfu uoeu dyo pvqd jluf ovk. Dlo htqq ka unsu vrutddvhtrmt zhlx e frfhbgtz usc obhutnha uorh bos vgriult Srqhembm prn hot Symtw elm uo xranvru ovn aisrmguggn ir uot Rsgtp. Poiqt hbt Yrtfrfwrea uogkntqvan qht brqvwgqd uy eriu xbso ln hot Fyttv, Grqurfoa vn rr amagrugm Gykre rrt os ybnh yt ahlssgt ysblgg ot see mtabgke uog ntsogvuq sa tpt Vksttirq fizoshn. Ubt Fyztw pixq xu gtsligttm, lt kla, elbt arkiqd rrt thugdyet qyb jeyw purq sed ubg sgvsa. Rdn nl hl ubg ntiglun trgh la hbt ugoa ntmgd ya Rutvfldy vd qovso ubg arug sa tpt eieub dthvyl rdn la hot Symtw ibnsra piqq ir uvxg ft fuiteqtz. Oeuvd bosf vu cvqd lt hbenmsn yd hot erfvtrb Yqzdqyever Hlmzanm ma Peg.'"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "repunctuate(vigenere_decipher(sanitise(cb), kbv), pub)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('hnypjvriltvyzlt', -3351.460892110415)"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kbb, score = beaufort_frequency_break(cb)\n",
+    "kbb, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'jdeksfkoiqfhtmesfgdmhdenubvlfhsyhekfreuihjmafmdfueiuunutiwmfmkdlhyxidsldtasdehuudgiumsfdxsufmensmcfavejffumnyekewfhshknsmfsfmaufkffbffsnskfyfgtfmekelhbfefsscbiffulhlbfefmnwfavmnadedhuenamfkhsxhfuxlsxldduxlhulkfsuudxlkguftdmaxeekfrnlmjfsfqfufsnxlhtnsfbhrphaivekfhollnydkftnmfcsechduflhlftsfeptojunuhvenhyfjimwhitnashmflysnafkfudtekgxaidthwtknnkdurensfrgtmkdllnrrfmgxskydenydkfhzxdihgmhbhsonytnxshrefkffbffsnslghsenkdbejfyhefnyndlfsmdkrshtfmrftgshilgumenekflwtgsdlenylnbfkfiilhjhrmfmesdxbflhimfsnshednulgmehexejhlfsfteenavekelfuhefnudlfnsmesnyekffbfgsnsaweehpfudihirsdtmihjhllfudfnidqezxdfeivntldlyhadivfleheekkfsfjfjhlefumenavekefbgfsnslmkugkvkdtdhulkdknfhekihlhrsdfqmyllknspenbfhumghhduywifqfueengjikdlxsdfumldeiilyfidhlhsfhiimmlfqftaveknlfemkknbkejhlunegfrmnuhihvpunjuuxabfslbmsfnqfsnydlfgngwihtfhumejgaxlvahllflthbefnkdljnxlfhumdthxaidsgihtflhulkkfsfpfspunelnxfhipfrljfsfhllecaifmjdluhbfjhkouhiihdglunsmdlildurhflnxinukeisdurmykdlmfhejtfwndsfheekfufimnsynrrfedezxdsqivekcllvbghekukhldussfhlfmavdlfjdmelgsfhmsxaoxsekgekfkhmafevsfbnpfmavgndlmvnuekefbgfsnslsobbhulmnbdedhuholeunddbfduhggmeueduqekfhbadecoxllhhxledxlixsyiixlglekfufjrmrfsunrnyekfgsnpeutfkejhltkhsrenjdekkftxsdurejgyshrcifgfhtfjcfkthiemnudhhumjghmfmdkfsfentntzsnueshirhtxlddkhlnuhvekfuekhdfkfinklnyekftnlgcjhlrfqfhifmlgjxledwljsnefnyjellknspheekfufimduhieeefsenthdomheflekfydyeklivafymsfekfphievmlnyahvduekfveisnyejftnulxiljeglnyahstxlhsseuduxlsifbfulddgvmixtcxlahfadxklnunsgexljfhsfedgsflkivtkhsrflbvnxsanlebxudycufuehtmrsfhefbfgsnsmmbdedhuenkgtxsffhcsnbhuhcvekfumsekfsupdtsmnblgumvfevnxitdefembfnyekfimmlnyejftnmfcntsyienswbvnxsifhlgshrsctnihkhlhhtfhmvfhdmekfgscufnylwtkhinllawfdyvnwmnunesftmrfseketnmfcafymtfekffhlldurnydlfvfhrekfuvnxbgwaflxrfekhevnxieiiwncukdbvnxeejibfejheduefiicsfutfxsnbhthgewtfmlgulxrrfleldlheekeeshdenstgjrhtxkkhlekftnlgchumclbhlldurjellxgfnsefsldudlfunsdkjkdifekebhsahrdhulekfbkgiqflgsfxuidpfhwenbhofbxtknyejgtnmfbthirhtxlcmhufmwthefmsnbgvhumkebxleaflemhgfmaeynsfkfthtnflesmvekflftxreevnydkfdbgfsdgjtdgkeslekftnmedjdiizfsftnqfsennsvnwvnxsyhbdhwhumfpfsvnufvnwqunjjciighvekfftdtfhtmlnenekfkgqfuejghsenyekefsxfldnsvnyhrscunihdtjkdtkekfxiefnydkfuduekiesdnuhtmnyekftnlgcdeleiyjdiidudebfafrfqfhifmxtfdiekeudejdiiaesxhsmemavekfhusefueagavinudhuqommflknyjhs'"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "beaufort_decipher(sanitise(cb), kbb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('ryajcqgrnskaxof', -3289.3609056830232)"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kbbv, score = beaufort_variant_frequency_break(cb)\n",
+    "kbbv, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'piuotgnlqvardnuggsvzeuvlredlurgnrubggvedypkztmitehddflrmqantmbvnenarvtuvdzgvhrerirreznttcgegmuytlxtlkunutezlahbtdtenrmmgmggtzlduogaxrugltotngrgtzbosorxgutttvyqgaelsnxgutzybuyqtlwwuveeuylluoenbpuebagbaiufbayelptgrevoantegmvkzbuhotuymnpgntguettlbaeemggerfkryddubgqlnasatptfymtjttxriltlsntsgthwelprsepeuleatcdldrdmlwhrmgnatyxuoglvdvosoyqisqdfbslmwehhlggurgmbcnlmhhgmsotnbvhsatptrmbvdernrkygimafybgeutuogaxrugltnsettmoieunuarhtlnyuotttvmigrstmugetgexnqfmuyuogabgstcnsmanyxtbgprnewrfntmhgvoksordttemgrhvlrarnuebbsqrnggtshtmyqbosoteeutyruotynmshlahotgkstgynyavurwteidqrhtcfkrrpenngruuldcisabvguqqyeovahrwwqdgnuehtpogntnuprautrztmyqbosuxsggltalpefvdmwfveenbinmteboosnrugvgvlbnavlekulktrrzrsrilaartigeuhyrqqbcnzhvtrmnihprnnaqtsnrttrddlnngptdzdublnghlpoyeosqrnrlufggnlryqpejeyperoxyttuxkhtlvtgynuotfssarrfgrezhotyoudwsnngnfektulbcnnmbngreziesblxvetqrstnermpognthugjrluayaurdqtfoptttraatxydamnwneextcenleexqpwsnrlgzimrnilhpunloqlrbtrgilhkbovamtehogtpsveuruhotrgpnlthlfituiuzoifjqqbouondksrhbdpraceehtratmlquotccmsosggrmtoxlbtboqvotbrmlgteggelhumyqslialelrbosuxsggltaflxkyelnlxiuverqlnhlltwxtierfflvehcegvotexyihvlbaurpcnuibndofbqdinqouogetculittllfmaubtstyivesaosqrnsortutmpibomufbtveuhotatyhurtsgrfgcvuosyqsnleirrrzotrzamtptggulsyeagyluesqhefbaiuprasepeuogeubeuuogxlmolahotsymtwcynfuiteqtzarqbabvaopgyutynovnavlekruhotrgpnvryqsvuttulseulmebtlvotnvahbmrdlaakhtubtjedtemasawsdvruogqtrgyhunuflrnbdaovsasawsgfonrtttfvrinertxgeniiremdifucnyetyionolrsgqvbnctrtgtwstanmrdfbrgugmydyigwmnukbeinvftrbrdnhggrugkstgynmkyvuirehyntfontrswgyxrreveubaekhuoggewiehmyenqfmdgudyopgvhaukytlnuogdlnnyhunuflztwysfbqhsgaydlogqgemtgeoguglqeoraeqgtetdrsvmhotftvftyhnagordlnalbuvnklanleyuggslittbosglmgwygnlgthvtrsnniehynuotqarfvotrdlokrdygubfuuoeudyopvqdjlufovkdlohtqqkaunsuvrutddvhtrmtzhlxefrfhbgtzuscobhutnhauorhbosvgriultsrqhembmprnhotsymtwelmuoxranvruovnaisrmguggniruotrsgtppoiqthbtyrtfrfwreauogkntqvanqhtbrqvwgqduyeriuxbsolnhotfyttvgrqurfoavnrramagrugmgykrerrtosybnhytahlssgtysblggotseemtabgkeuogntsogvuqsatptvksttirqfizoshnubtfyztwpixqxugtsligttmltklaelbtarkiqdrrtthugdyetqybjeywpurqsedubgsgvsardnnlhlubgntigluntrghlahbtugoantmgdyarutvfldyvdqovsoubgarugsatpteieubdthvylrdnlahotsymtwibnsrapiqqiruvxgftfuiteqtzoeuvdbosfvucvqdlthbenmsnydhoterfvtrbyqzdqyeverhlmzanmmapeg'"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "beaufort_variant_decipher(sanitise(cb), kbbv)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'ytsfeqziozzjyzynifmpczahrmdxemcpjzkmjwjlxnnyonyerofpohxcddrcgzewuxdyioknuwxnbjvyqlnrzresxtfivjwqfyuewdiyowzlefdbxcvvjphzvvgclgtmtgqgsgouncvhzdhgqpoiaeutqtjvpqbodegstcrmcxrtdyybzkeywyeuuvsdtaoxbyrkleslsgczexwgbxntrmeysyaguvwjwqjgydepouomrjtzujwohgqvcmueioasbmdrqtsaviskmkxsekqbnteipeknauupiftymqkenkipdeaxaftxauudzckvvnjftnmtgbeehwbimsclcessglcireuhgwwlyxjfngmnmrebmmfkvpaohxxsgbvzoywwgzcuqnojzxpefrmkzpmgksvajuryrkimuzevnjlqwexpybstphbsiezbiqccknatjvowdxwkenfosfjjrfspkiojnaeaceignjpkmhmpswfczqbjhvppczhdvjtvlkwvgcecjedqrxtabnyivskgpgpbmityxuktwmmlrgqyvvawhlngwiahbktyzvqynncbbdqzdeeeoershbiqltegjriukialufyukgvtzekncmyafwndyamvtstwryacxyallqpaopcnwrsqtgzrgfpejoymndfxaazwdfhmmcgpwltsbxjvvoageyfazkzskfccocgmwucfjsnqzuevanhtxwxoaxdttlqrohnwjfhzghonqxscdddzywlzgedmnfspenyehypvtwlgugrxjxglrjrkvdvmievpftyuocdicijifknqwvqjblqlwowcrgkqbxrnihxzlqcwubpwbbdlyrxbldlhguqedueejcuvcgyxnyzwmviaiwexxagvfnvfisrlwglpldcjsibqqgvuienlufstzzhanbsnitujiyexvvzuxzsgcpzhwlbpztqxvcuzksmsvmckgsamvqislpmpebwztxycgdboztpckmeyncijrcuamgbamtujurczsifncmuykyvsobuykolymrgjrokaycaizhkkcpkiyykdkcokmoaxuoaslievdhtpnykwjqhctxhucldgakaqovdcppxhrcduwngahltatswfaebolamgzmlbrraeeaicgyvomorpeavueckyysketvfraqyxxzpdxziewwaazksgqexgakjwafruwhzkwoohwfyzaqjcebhhwzbcokqsxweviwgblgawlimoqbgbwljybjxiqvguxvkwaydleqxxczkkrjndjipnuckiensalufwzdbcvlzboiimqihhqgqligodxmetgvuyynjfueadtioypxvvtjananrwtwiwqecsfrafoecgmigjstastytaoaaaicbbqfwczwgazhlhqoywpapkdnijysxgwscchyyqvymiyhssfwliaonsfteylmqgdavsdgzeruprqimkbigpdzcijjgiapvrdsfillydvlkddcfgbrzusfbthejdltrhgpwfjdefhatrynubwqmgmbenqeauduywpadbqwcguysfrnxklcgmigjsbgnoqkgmhagmiyhqyvpkpulmnexfgruzehgcppkjquwegfxcvdymgtxfrdfjxdehtvqinowziyfadvepfjumnxnkgegwceptacydlungwxeqkikgyqqaghwclrniddelxibvghlrqdoqjnblmlpfuavvumalzqsiibaywlutzncqynnpllygpdiqrndrdtkxafowgexyztnhjoefbnkmqcyurmmlzpomoxzgzaycskbzxsglywehercavykijxmayepzokgrwrskcpkzifynzsmraaamwausemvnzmiftcmkgqeibgvzyuajgfkmcnhaausphtlsenhnfecpfczdmvgxzrepwdjnrzbcggfobytwrsbxcuuefyprmkdoqjreayfqyviakimlaqqaafzormkycourkqymvgivresfbfflondaypnqurwdwtyoadrbctnsirqkzerxegpteaniovvkfriypvlkedyziaaejijgiguwldnbdlngbdofzpbzcbufvtfonjytalwrkvpxwlbvyquadgdzzsauoaohxxfceuxnaqaumnpryjsmkdiyqumafndewkdhypzatgntredpgiyiuhvalamveqvsgdknfqxkdzvrhxfxcubicgmrqhwuiswmlzbhzzeylhnqgp'"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "vbai = vigenere_decipher(sanitise(cb), 'arcanaimperii')\n",
+    "vbai"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'ybwfeqpgshhzozgrifmfadiphcdfimcpzxourmzlfrnyodwizwvfopbcddhakhmmkxlciokdsafvrzvgulnrppiafjvidnwqfosielyooedleftzbkdlzppdvvgsjkbujwqowgoudazphtxgytoiausxybzlpyfodewqxkzcsxzxdyyrxomgmoecyvsdjysfjohktislswadmfmwbfrtrmuwwgiwkvenwqjwwhmxekouvjtzkhawpwgvkqueieywjuthqbwaviiiqsfiukyfnteynisvqkuxmftycoomvaypliaxavrbicktzkovvnzdxvujwbmihwbykwktsusaklcihcypommlgbjfnwkruzurmujkvpqmlffiwbddoywmedkcgdordxpevpqshfcgswvajkpczsycuhivnjboamffobaxphbigihjygckonatztselnmkmrfosvhnznifkqsjnauygmqwdjxomhmfqankpgbrlvppsxlldzjvtowvgscgrmtgrfxabnogzaswfgxfmitovysbmcmtvgqylteepbdgemahbarchdgonvgbbdgxhmmueezwhbigjxmozhicoialkdccswlthiknccwenedtyiqvtsjuvgisnyiplqpqmtkvmhsyxgzrwdtmreomvhfxaqxalnxcmkkpwljqffrlloikeyfqxohaavckscgmmsgnridqhyevadfxfeneafhttlgpspvmzfpdghodobakttdhcwlzwchuvvipmryehonzbebwuovxjxwjvrzalddqievfdxgcesdqgijiviryelgjjpqlweugzoagbfvnihnxpykmkbxabbdbwvfjbtlpkuqetsimrskvkkyxnoxaudyqieixxawtjvdvyszpwglfjhkriybyugvuycrtcvithdhanrqrqbkzigixvvpsbhawsphlwlbfxxyflsuhosmslkgsoiqmduislfktmjmptfccgdrmdbxsammcncizpgcicwbiqtujkpghayvnkquykotwwjkokwpymrwhvwsqocimzhkaatsqooklocokcmefceqstmevdxrtvgamjylctxxsgtlwqkiuovdsntfphsdcangaxjxibimfiibolqkkhubrrzeeeayakgdecozteavkcgsgoikmxvfrqocffpfdfdiewmyehsiwqmbgakzuenzkmhhowooxujghqgjkibhhmxfkwagsfaevimeftoqmlqqoqbwzatrorjfmqvgkvzseqodtiqxxsxoszzddrmpnusimmviqlcjwzdrazthreiqqqihxokytywolbmetwtyggdzfciadtymcxflltrenanhuxeqmgekwfravmikocygrwtasjwxiwqqaqgbbqvughewqzpphqooutixatnqnysxwuwkkxoyyzymiofwanmbiisnsfjcctugwdizsdgpcvcxhgiuobigfbdkqzzgqepvrtqjqtboddpkddsdkjzpksnfthezbpbzxwpejjdevfebzodujaqmgczivyuqulyywpqbfyeswugwfrnnipkocygrwbgneooouxqgumyhqottsxkbmvixfghsdmpwspxojqumcknfsldgqgtxvphnrntepxvqidmahqovalzepfzsqvfdagmkwcefrekgtbuvkwxegimsoogqikhwcbprqltulfmbvgxjvylegjvflmlfdyidlkmipzqsygfigmbubdncqolrxtbogxhiqrdbvlbananswgenwdbvxzomjbnkcoggchcmtdpomevdohqocaobzxiepgeuxezgavyagnfuqoexdokghuvassfkhmfynpqqziqqmeeusectrhuyvtkqkgqugfodpouingfkcarpiqksxltlsullvnuspngzdmlebhzufwlnnrzrakonerybarsbnaycmvopzqkdoghvmiovqgziakykpiygqandormawgwchaqgqvgilpianrvftsndaonrychmdexyoatpfkbdiizukzehvioxjuavmovvadvqgfllsidyzyyemryzgqkuwltlfltdwblsfzprxgjcvltnsnjyjypezalpfalbvooyilwtzhwauoqmlffvsecbnaqqsqvxhojaqkdiooyuivddmakdhondibwdtzidpgywmcplqliqveqlqklsdvqfodzvhfbnfskbqggmrgfacqimmtdbhzpcctpdggx'"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "vbai = beaufort_variant_decipher(sanitise(cb), 'arcanaimperii')\n",
+    "vbai"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:418: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n",
+      "  \"matplotlib is currently using a non-GUI backend, \"\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f74f40ca828>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fc = collections.Counter(sanitise(cb))\n",
+    "plot_frequency_histogram(fc)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:418: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n",
+      "  \"matplotlib is currently using a non-GUI backend, \"\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f74b63ab748>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fp = collections.Counter(vigenere_decipher(sanitise(cb), kbv))\n",
+    "plot_frequency_histogram(fp)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:418: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n",
+      "  \"matplotlib is currently using a non-GUI backend, \"\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f74b4bf73c8>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fp = collections.Counter(vbai)\n",
+    "plot_frequency_histogram(fp)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:418: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n",
+      "  \"matplotlib is currently using a non-GUI backend, \"\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f74b33da198>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "plot_frequency_histogram({k: 10**Pl[k] for k in Pl})"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:418: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n",
+      "  \"matplotlib is currently using a non-GUI backend, \"\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAaoAAAEmCAYAAAAz/dRVAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvNQv5yAAAET1JREFUeJzt3XuQJWV9xvHvI2Dk5gUYNYrjYmKRGE1FHY2IJgbQIl6CqWhFElQSrYmJihqJBTGWFKVVGqwYq3LRFQkmEEzEa7xCgQZQRNllkV2WixFUjIpIvCClgPzyx+mVYRfY6dO9M+/sfD9Vp+b0mX77/Z0zfc5z3u6e7lQVkiS16l7LXYAkSffEoJIkNc2gkiQ1zaCSJDXNoJIkNc2gkiQ1zaCSJDXNoJIkNc2gkiQ1zaCSJDVt16XsbL/99qs1a9YsZZeSpEatW7fuhqqa2d58SxpUa9as4eKLL17KLiVJjUrytcXM56Y/SVLTDCpJUtMMKklS0wwqSVLTDCpJUtMMKklS0wwqSVLTDCpJUtMMKklS0wwqSVLTlvQUShrHmuM+3rvNtW951g6oRJJ2PEdUkqSmGVSSpKYZVJKkphlUkqSmGVSSpKYZVJKkphlUkqSmGVSSpKYZVJKkphlUkqSmGVSSpKZtN6iSnJLk+iQb7+J3r01SSfbbMeVJkla7xYyoTgUO3/rBJA8DngF8feSaJEn6ue0GVVWdB9x4F796O/A6oMYuSpKkLabaR5XkCOCbVXXpyPVIknQnva9HlWQP4K+ZbPZbzPzzwDzA7Oxs3+4kSavcNCOqXwIOAC5Nci2wP7A+yYPvauaqWltVc1U1NzMzM32lkqRVqfeIqqouAx64ZboLq7mqumHEuiRJAhZ3ePoZwIXAgUmuS/KSHV+WJEkT2x1RVdWR2/n9mtGqkSRpK56ZQpLUNINKktQ0g0qS1DSDSpLUNINKktQ0g0qS1DSDSpLUNINKktQ0g0qS1DSDSpLUNINKktQ0g0qS1DSDSpLUNINKktQ0g0qS1DSDSpLUNINKktQ0g0qS1DSDSpLUNINKktQ0g0qS1DSDSpLUNINKktQ0g0qS1LTtBlWSU5Jcn2TjgsdOSnJFki8n+VCS++/YMiVJq9ViRlSnAodv9djZwKOr6teBq4DjR65LkiRgEUFVVecBN2712FlVdVs3+QVg/x1QmyRJo+yj+lPgkyMsR5Kkbew6pHGS1wO3AaffwzzzwDzA7OzskO4k7WTWHPfx3m2ufcuzdkAlatnUI6okRwPPBv64quru5quqtVU1V1VzMzMz03YnSVqlphpRJTkceB3w21V187glSZJ0h8Ucnn4GcCFwYJLrkrwE+Adgb+DsJBuSvHMH1ylJWqW2O6KqqiPv4uH37IBaJEnahmemkCQ1zaCSJDXNoJIkNc2gkiQ1zaCSJDXNoJIkNc2gkiQ1zaCSJDXNoJIkNc2gkiQ1zaCSJDXNoJIkNW3QhRNXKy/2pp2B6/FwvoZLwxGVJKlpBpUkqWkGlSSpaQaVJKlpBpUkqWkGlSSpaQaVJKlpBpUkqWkGlSSpaQaVJKlpBpUkqWnbDaokpyS5PsnGBY/tk+TsJFd3Px+wY8uUJK1WixlRnQocvtVjxwHnVNUjgXO6aUmSRrfdoKqq84Abt3r4COC93f33As8duS5JkoDp91E9qKq+1d3/NvCgkeqRJOlOBl+PqqoqSd3d75PMA/MAs7OzQ7vTSIZeR8fr8EhaKtOOqL6T5BcBup/X392MVbW2quaqam5mZmbK7iRJq9W0QfVR4MXd/RcDHxmnHEmS7mwxh6efAVwIHJjkuiQvAd4CPD3J1cBh3bQkSaPb7j6qqjrybn516Mi1SJK0Dc9MIUlqmkElSWqaQSVJappBJUlqmkElSWqaQSVJappBJUlqmkElSWqaQSVJappBJUlqmkElSWqaQSVJatrgCydKklaulXARVEdUkqSmGVSSpKYZVJKkphlUkqSmGVSSpKYZVJKkphlUkqSmGVSSpKYZVJKkphlUkqSmGVSSpKYNCqokr0myKcnGJGckuc9YhUmSBAOCKslDgWOAuap6NLAL8IKxCpMkCYZv+tsV2D3JrsAewP8OL0mSpDtMHVRV9U3gbcDXgW8BP6iqs8YqTJIkGHA9qiQPAI4ADgC+D7w/yVFVddpW880D8wCzs7MDSpXUmpVwLaPWDX0NV8PfYMimv8OAa6rqu1V1K/BB4Mlbz1RVa6tqrqrmZmZmBnQnSVqNhgTV14EnJdkjSYBDgc3jlCVJ0sSQfVQXAWcC64HLumWtHakuSZKAAfuoAKrqjcAbR6pFkqRteGYKSVLTDCpJUtMMKklS0wwqSVLTDCpJUtMMKklS0wwqSVLTDCpJUtMMKklS0wwqSVLTDCpJUtMMKklS0wadlFbS9FbDBe+kMTiikiQ1zaCSJDXNoJIkNc2gkiQ1zaCSJDXNoJIkNc2gkiQ1zaCSJDXNoJIkNc2gkiQ1zaCSJDVtUFAluX+SM5NckWRzkoPGKkySJBh+Utp3AJ+qqucluTewxwg1SZL0c1MHVZL7Ab8FHA1QVbcAt4xTliRJE0M2/R0AfBf4lySXJDk5yZ4j1SVJEjBs09+uwOOAV1bVRUneARwHvGHhTEnmgXmA2dnZAd2Nx+sASdLKMWREdR1wXVVd1E2fySS47qSq1lbVXFXNzczMDOhOkrQaTR1UVfVt4BtJDuweOhS4fJSqJEnqDD3q75XA6d0Rf18F/mR4SZIk3WFQUFXVBmBupFokSdqGZ6aQJDXNoJIkNc2gkiQ1zaCSJDXNoJIkNc2gkiQ1zaCSJDXNoJIkNc2gkiQ1zaCSJDXNoJIkNc2gkiQ1bejZ0yVp2XgR1NXBEZUkqWkGlSSpaQaVJKlpBpUkqWkGlSSpaQaVJKlpBpUkqWkGlSSpaQaVJKlpBpUkqWkGlSSpaYODKskuSS5J8rExCpIkaaExRlSvAjaPsBxJkrYxKKiS7A88Czh5nHIkSbqzoSOqvwdeB9w+Qi2SJG1j6utRJXk2cH1VrUvytHuYbx6YB5idnZ22u52K19CRpMUbMqI6GPi9JNcC7wMOSXLa1jNV1dqqmququZmZmQHdSZJWo6mDqqqOr6r9q2oN8ALg3Ko6arTKJEnC/6OSJDVu6n1UC1XVZ4HPjrEsSZIWckQlSWqaQSVJappBJUlqmkElSWqaQSVJappBJUlqmkElSWqaQSVJappBJUlqmkElSWqaQSVJatoo5/pbal7PSS1wPZSWhiMqSVLTDCpJUtMMKklS0wwqSVLTDCpJUtMMKklS0wwqSVLTDCpJUtMMKklS0wwqSVLTDCpJUtMMKklS06YOqiQPS/KZJJcn2ZTkVWMWJkkSDDt7+m3Aa6tqfZK9gXVJzq6qy0eqTZKk6UdUVfWtqlrf3f8RsBl46FiFSZIEI+2jSrIGeCxw0RjLkyRpi8EXTkyyF/AB4NVV9cO7+P08MA8wOzs7tDtpNCv9wocrvf4W+BquDINGVEl2YxJSp1fVB+9qnqpaW1VzVTU3MzMzpDtJ0io05Ki/AO8BNlfV341XkiRJdxgyojoYeCFwSJIN3e2ZI9UlSRIwYB9VVV0AZMRaJEnahmemkCQ1zaCSJDXNoJIkNc2gkiQ1zaCSJDXNoJIkNc2gkiQ1zaCSJDXNoJIkNc2gkiQ1zaCSJDVt8PWopGkMvQ6Q1xGSVg9HVJKkphlUkqSmGVSSpKYZVJKkphlUkqSmGVSSpKYZVJKkphlUkqSmGVSSpKYZVJKkphlUkqSmGVSSpKYNCqokhye5MslXkhw3VlGSJG0xdVAl2QX4R+B3gUcBRyZ51FiFSZIEw0ZUTwS+UlVfrapbgPcBR4xTliRJE0OC6qHANxZMX9c9JknSaFJV0zVMngccXlUv7aZfCPxmVb1iq/nmgflu8kDgyunL3a79gBuWsX0LNaz09i3UsNLbt1DDcrdvoYaV3n6sZdyTh1fVzHbnqqqpbsBBwKcXTB8PHD/t8sa4ARcvZ/sWaljp7VuoYaW3b6GG5W7fQg0rvf1YyxjjNmTT35eARyY5IMm9gRcAHx2wPEmStrHrtA2r6rYkrwA+DewCnFJVm0arTJIkBgQVQFV9AvjESLWMYe0yt2+hhpXevoUaVnr7FmpY7vYt1LDS24+1jMGmPphCkqSl4CmUJElNM6iAJGuSbFzuOrZIckKSY5ep72OSbE5y+hL3O8rfIMnnl3sZSW4aWoOkOwzaR6Wd0l8Ah1XVdctdyDSq6sktLEPjSBImuyhuX+5atHx2mhFVkg8nWZdkU/dPxn3tmuT0bjRxZpI9evb/oiRfTnJpkn/r23mS1ye5KskFTP4xum/7o5J8McmGJO/qzsXYdxnvBB4BfDLJa6Zo/4buJMUXJDljilHhLkne3f0Nz0qy+xQ1DB7NLMeIqBtRXpHk1G49OD3JYUk+l+TqJE9c5HL+MsnG7vbqAXVM9V5YuB5PuQ5sqeHKJP8KbAQe1qPtnkk+3r0PNyb5wyn63rhg+tgkJyyy7V8lOaa7//Yk53b3D+mzhSLJE7rPkvt0z2dTkkf3aH/iwr99kjcneVWP9i/rPkc2JLkmyWcW23aHWe5/5BrrBuzT/dydycq9b4+2a4ACDu6mTwGO7dH+14CrgP0W1tKj/eOBy4A9gPsCX+nZ/68C/wXs1k3/E/CiKV/Ha7c8j57tngBsAO4D7A1c3fM5rAFuA36jm/5P4Kgp6rhphHVp0DKmab/g+T+GyRfIdd16GCbn0Pxwj/VoT2AvYBPw2CnqmOq9MHQ93qqG24EnTdH2D4B3L5i+3xR9b1wwfSxwwiLbPgl4f3f/fOCLwG7AG4E/61nHm4C3MTnxd68TKXTPYX13/17A//T5PFywnN265/Gcvm3Hvu00IyrgmCSXAl9g8g3skT3bf6OqPtfdPw14So+2hzBZQW8AqKobe/b9VOBDVXVzVf2Q/v84fSiTD4kvJdnQTT+i5zKGOhj4SFX9pKp+xCQ4+7qmqjZ099cxecOtJtdU1WU12cy1CTinJp8Yl7G41+IpTNajH1fVTcAHmaxbfU37Xhi6Hi/0tar6whTtLgOenuStSZ5aVT8YUENf64DHJ7kv8FPgQmCOyetyfs9lnQg8vWv/t30aVtW1wPeSPBZ4BnBJVX2vZ/8A7wDOrapp3suj2in2USV5GnAYcFBV3Zzks0y+2fex9XH6K+m4/QDvrarjl7uQgX664P7PmIyOV5OFz//2BdO3s7Tv1RbeCz+eplFVXZXkccAzgTclOaeqTuyxiNu48y6RRX+OVNWtSa4BjgY+D3wZ+B3gl4HNPWoA2JfJqHi3roa+r8fJXR0PZjIq7iXJ0cDDgVdsZ9YlsbOMqO4H/F8XUr/CZAje12ySg7r7fwRc0KPtucDzk+wLkGSfnn2fBzw3ye5J9gae07P9OcDzkjxwS/9JHt5zGUN9DnhOt119L+DZS9y/Jt/an5tkjyR7Ar9P/2/yMP17Yeh6PFiShwA3V9VpwEnA43ou4jvAA5Psm+QX6L8en89kc+F53f2XMRnR9A37dwFvAE4H3tqzLcCHgMOZbJL/dJ+GSR7P5DkcVY0cxLJTjKiATwEvS7KZydnZp9lkcCXw8iSnAJcD/7zYhlW1Kcmbgf9O8jPgEibfZhbbfn2S/wAuBa5nch7FRauqy5P8DXBWknsBtwIvB77WZzlDVNWXknyUybfI7zDZBLOUm13GtJJG0z/XrUenMtk3AnByVV0yxaKmei8MXY9H8hjgpCS3M3kf/Hmfxt2o6EQmr+E3gSt69n8+8Hrgwqr6cZKf0PPLQpIXAbdW1b93B0V9PskhVXXuYpdRVbd0B0F8v6p+1qd/JqOofYDPJIHJiWlf2nMZo/LMFBpNkr2q6qbuKLHzgPmqWr/cdfXRjYrXV9VSj0ibkGQN8LGqWvRRZvewrBOYHFjytqHLUj/dF9b1wPOr6urlrmeonWXTn9qwtjuYYz3wgRUYUg9hsgPcD1atWEkexeSIy3N2hpACR1SSpMY5opIkNc2gkiQ1zaCSJDXNoJIkNc2gkiQ1zaCSJDXt/wG1Y5A9mcLQ3AAAAABJRU5ErkJggg==\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f74b2df0b38>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fp = collections.Counter(every_nth(scb, 15)[4])\n",
+    "plot_frequency_histogram(fp)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:418: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n",
+      "  \"matplotlib is currently using a non-GUI backend, \"\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "'y'"
+      ]
+     },
+     "execution_count": 22,
+     "metadata": {},
+     "output_type": "execute_result"
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f74b3e6b7f0>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "k, _ = caesar_break(every_nth(scb, 15)[4])\n",
+    "fp = collections.Counter(caesar_decipher(every_nth(scb, 15)[4], k))\n",
+    "plot_frequency_histogram(fp)\n",
+    "unpos(k)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:418: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n",
+      "  \"matplotlib is currently using a non-GUI backend, \"\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f74b58ae400>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fp = collections.Counter(vigenere_decipher(sanitise(cb), kbv))\n",
+    "plot_frequency_histogram(fp, sort_key=fp.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:418: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n",
+      "  \"matplotlib is currently using a non-GUI backend, \"\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f74b47694a8>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "plot_frequency_histogram({k: 10**Pl[k] for k in Pl}, sort_key=Pl.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('taxied', <KeywordWrapAlphabet.from_last: 2>), -3188.639246703687)"
+      ]
+     },
+     "execution_count": 25,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "vb = vigenere_decipher(sanitise(cb), kbv)\n",
+    "keyword_break_mp(vb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'pdtoahnlqubrfnthhsuxetulrefltrhnrtyhhuefwpkxamdaeiffglrmqbnamyunenbruatufxhuirerdrrexnaazhehmtwalcalktntaexlbiyafaenrmmhmhhaxlftohbcrthlaoanhrhaxyosorchtaaauwqhbelsnchtaxwytwqalvvtueetwlltoenypteybhybdtgybwelpahreuobnaehmukxytioatwmnphnahteaalybeemhhergkrwfftyhqlnbsbapagwmajaacrdlalsnashaivelprsepetlebazflfrfmlvirmhnbawctohlufuosowqdsqfgyslmveiilhhtrhmyznlmiihmsoanyuisbaparmyufernrkwhdmbgwyhetatohbcrthlanseaamodetntbrialnwtoaaaumdhrsamtheahecnqgmtwtohbyhsaznsmbnwcayhprnevrgnamihuoksorfaaemhriulrbrnteyysqrnhhasiamwqyosoaeetawrtoawnmsilbioahksahwnwbutrvaedfqriazgkrrpennhrttlfzdsbyuhtqqweoubirvvqfhnteiapohnantprbtarxamwqyostcshhlablpegufmvgueenydnmaeyoosnrthuhulynbulektlkarrxrsrdlbbradhetiwrqqyznxiuarmndiprnnbqasnraarfflnnhpafxftylnhilpoweosqrnrltghhnlrwqpejewperocwaatckialuahwntoagssbrrghrexioawotfvsnnhngekatlyznnmynhrexdesylcueaqrsanermpohnaithjrltbwbtrfqagopaaarbbacwfbmnvneecazenleecqpvsnrlhxdmrndliptnloqlryarhdlikyoubmaeiohapsuetrtioarhpnlailgdatdtxodgjqqyotonfksriyfprbzeeiarbamlqtoazzmsoshhrmaoclyayoquoayrmlhaehhelitmwqsldblelryostcshhlabglckwelnlcdtuerqlnillavcadergglueizehuoaecwdiulybtrpzntdynfogyqfdnqotoheaztldaallgmbtyasawduesbosqrnsoratampdyomtgyauetioabawitrashrghzutoswqsnledrrrxoarxbmapahhtlswebhwltesqiegybdtprbsepetohetyettohclmolbioaswmavzwngtdaeqaxbrqybyubophwtawnounbulekrtioarhpnurwqsutaatlsetlmeyaluoanubiymrflbbkiatyajefaembsbvsfurtohqarhwitntglrnyfbousbsbvshgonraaagurdnerachenddremfdgtznweawdonolrshquynzarahavsabnmrfgyrhthmwfwdhvmntkyednugaryrfnihhrthksahwnmkwutdreiwnagonarsvhwcrreuetybekitohhevdeimwenqgmfhtfwophuibtkwalntohflnnwitntglxavwsgyqishbwflohqhemaheohthlqeorbeqhaeafrsumioagaugawinbhorflnblytunklbnlewthhsldaayoshlmhvwhnlhaiuarsnndeiwntoaqbrguoarflokrfwhtygttoetfwopuqfjltgoukfloiaqqkbtnsturtaffuiarmaxilcegrgiyhaxtszoyitanibtoriyosuhrdtlasrqiemymprnioaswmavelmtocrbnurtounbdsrmhthhndrtoarshappodqaiyawragrgvrebtohknaqubnqiayrquvhqftwerdtcysolnioagwaauhrqtrgobunrrbmbhrthmhwkrerraoswyniwabilsshawsylhhoaseemabyhketohnasohutqsbapauksaadrqgdxosintyagwxavpdcqcthasldhaamlaklbelyabrkdqfrraaithfweaqwyjewvptrqseftyhshusbrfnnliltyhnadhltnarhilbiyathobnamhfwbrtauglfwufqousotyhbrthsbapaedetyfaiuwlrfnlbioaswmavdynsrbpdqqdrtuchgagtdaeqaxoetufyosgutzuqflaiyenmsnwfioaerguarywqxfqweuerilmxbnmmbpeh'"
+      ]
+     },
+     "execution_count": 26,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "keyword_decipher(vb, 'taxied', KeywordWrapAlphabet.from_last)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'gekyjtdxzlabrdkttilphklxbhrxkbtdbkqttlhrogwpjfejhurrsxbfzadjfqldhdabljklrptlubhbebbhpdjjcthtfkojxnjxwkdkjhpxauqjrjhdbfftfttjpxrkytanbktxjyjdtbtjpqyiybntkjjjloztahxidntkjpoqkozjxmmklhhkoxxkyhdqgkhqatqaeksqaohxgjtbhlyadjhtflwpqkuyjkofdgtdjtkhjjxqahhftthbswborrkqtzxdaiajgjsofjvjjnbexjxidjitjumhxgbihghkxhajcrxrbrfxmubftdajonkytxlrlyiyozeizrsqixfmhuuxttkbtfqcdxfuutfiyjdqluiajgjbfqlrhbdbwotefasoqthkjkytanbktxjdihjjfyehkdkabujxdokyjjjlfetbijfkthjthndzsfkokytaqtijcdifadonjqtgbdhmbsdjfutlywiybrjjhftbulxbabdkhqqizbdttjiujfozqyiyjhhkjobkyjodfiuxauyjtwijtodoalkbmjherzbujcswbbghddtbkkxrceiaqltkzzohylaubmmzrtdkhujgytdjdkgbakjbpjfozqyiknittxjaxghslrfmslhhdqedfjhqyyidbktltlxqdalxhwkxwjbbpbibexaabjethkuobzzqcdpuljbfdeugbddazjidbjjbrrxddtgjrprkqxdtuxgyohyizbdbxksttdxbozghvhoghbynojjknwujxljtodkyjsiiabbstbhpuyjoykrmiddtdshwjkxqcddfqdtbhpehiqxnlhjzbijdhbfgytdjuktvbxkaoakbrzjsygjjjbaajnorafdmdhhnjchdxhhnzgmidbxtpefbdexugkdxyzxbqjbtexuwqylafjhuytjgilhkbkuyjbtgdxjuxsejkekpyesvzzqykydrwibuqrgbachhujbajfxzkyjccfiyittbfjynxqjqyzlyjqbfxtjhtthxukfozixeaxhxbqyiknittxjasxnwohxdxneklhbzxduxxjmnjehbssxlhuchtlyjhnoeulxqakbgcdkeqdrysqzredzykythjckxejjxxsfakqjijoelhiayizbdiybjkjfgeqyfksqjlhkuyjajoukbjitbstclkyiozidxhebbbpyjbpafjgjttkxiohatoxkhizuhsqaekgbaihghkythkqhkkytnxfyxauyjiofjmcodskejhzjpabzqaqlaygtokjodyldalxhwbkuyjbtgdlbozilkjjkxihkxfhqjxlyjdlauqfbrxaawujkqjvhrjhfaiamirlbkytzjbtoukdksxbdqrayliaiamitsydbjjjslbedhbjnthdeebhfreskcdohjoeydyxbitzlqdcjbjtjmijadfbrsqbtktforoetmfdkwqhedlsjbqbrduttbktwijtodfwolkebhuodjsydjbimtonbbhlhkqahwukytthmehufohdzsfrtkroygtluakwojxdkytrxddoukdksxpjmoisqzuitaorxytzthfjthytktxzhybahztjhjrbilfuyjsjlsjoudatybrxdaxqkldwxadxhokttixejjqyitxftmotdxtjuljbiddehuodkyjzabslyjbrxywbrotkqskkyhkroyglzrvxksylwrxyujzzwakdiklbkjrrlujbfjpuxnhsbsuqtjpkicyqukjduakybuqyiltbekxjibzuhfqfgbduyjiofjmhxfkynbadlbkyldaeibftkttdebkyjbitjggyezjuqjobjsbsmbhakytwdjzladzujqbzlmtzrkohbeknqiyxduyjsojjltbzkbsyaldbbafatbktftowbhbbjyioqduojauxiitjoiqxttyjihhfjaqtwhkytdjiytlkziajgjlwijjebzsepyiudkqjsopjmgenznktjixetjjfxjwxahxqjabwezrbbjjuktrohjzoqvhomgkbzihrkqtitliabrddxuxkqtdjetxkdjbtuxauqjktyadjftroabkjlsxrolrzyliykqtabktiajgjhehkqrjuloxbrdxauyjiofjmeqdibagezzebklntsjskejhzjpyhklrqyislkclzrxjuqhdfidoruyjhbsljbqozprzohlhbuxfpadffaght'"
+      ]
+     },
+     "execution_count": 27,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "keyword_decipher(vb, 'arcanaimperii', KeywordWrapAlphabet.from_largest)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'kccgi'"
+      ]
+     },
+     "execution_count": 28,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cat(unpos(caesar_break(section)[0]) for section in every_nth(scb, 5))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'oiszjgfsxvgpethfgqgpemcsrkbmaefnpfrgycldenlfglirpxdvmsrsobtglbtyunsyctateftuhpphijylztruitdgkfotdealqsoagdzjlxblkaetpnstlgeeplvbvggvsatktmedgjnazhmtuewgsejtnfxggcmyawgsepytbfqzjxchuecfoldbvetzqaraaemqimmiaecmvgfrcgeafalgstlfothmekyeuwgtrharstjmqewtngkpgqexdbfrgisuayyuvgeykeztleyirrmyasseexwwswrycqkhkeyesddkydsjxnelglljypbvgrtebbrowbysikmbyjncrghjrwujntbilmsuggkdetfichyyuvgqmzgtejuykeejsneyzruulbvggvsatktldutltviksoanqhrwdymvatztnotqsrxkgwanedlrlztyszwatnztiltsnmyverghyuecpgtglhegekkvydzrfstqhtwhajubehztwemgeeihltfqhmtugdeseormvaytktnyzhmewkkanytwbbhqwrpydiyotidlxeoelywrmbsdigtgougsbgywvcanpxcdcglfuhlwvgtroacqasehzltfqhmtakrgewjadwlfbbncsuecyriftaehmpyaquegwvdiuabjfqhkkrchzjzyirybxghgcfxyjxxbilanisrkyyhhyungouyaqtrctdduugvrefqtbjywhdwvykmtwemrjfvgyusreoqkwdynphopfatavlngkvrronmvafyqbxeegppphgafoabxyamglquklbsbilosomgpppiwzildtfzdqsryurewvgtriatirjfqysbydwrgucstrcqalefdgkocadevesefsledoqcfmrjrpieyuirfqaakoowhblynirflhbuakeuhgnapytfaethmehghustnjgogtiskeixqxqhmvuackqcxbvwyaicfngqarxbqmvaciktuffgpxjopsithmrbbsbpxbgllngkjiazxqqwyadlsrhmtakrgewjaxsekecmtywisgurisuhrjucksiccvfdclhichbbsevjyhnsiaapqiatizytoxixdolruhngcesudpatrjgsntbrdjyaclsgmtwemsmcjultwihmnasattpkhgahtefvxgrgpqwcnbvseottydipchzgayzgkuvgfgswiywhnyrsfydgedmqimwyaycqkhngcfrembvgdjnuyzhmeiyeadcelgavseoepajxiahtbucfyseongcuabjfqethmehghucreotbhstswiemstehrmbbsntlxbeyklgylngtbruudlltayyxyqurszwqlynynsoaskrlmtagczayyxyteolcjtlmcrolfxgwgcyyijltdodviaxerjyofvsryerbomcrcjgldztglnxqebprkgefkyoexsatkzpynnmarhpetufgpfwkkanytkleitippxyfamotrsyjfyvchenlbbgclnhngepmiwotyklrlzcgsooohnchgslegknszwdduuynsoaskzrhosxixhyebeqkoebweeaneuevmypemcqeinaezbsyilhmevtnmaynlbmbqdjyqltbcnqjbtydysrwsdpathmtmylgujwndnahbrsyamicsonmvaqgpgbbsrbwekjkfgazgahnesooohcxdpjvlbukbwehlxxkgsoyhursetdnoarsranywedcvhtnazaqduoguryxamvyhhmtbtqiswjsjxoesznvemhmeiyeaderkvukqalghugcuaoqssttgeyyrmvaryeuvcnioexblfytlpgcedaszwkfaxvglrngarogmgikbykpjakasmwdhgamyzrwmepupqeanuyrgkbmetgkrokjlyrzmteomhweqhdzzgzwthyfgmeiewtaahelkhngleioycbqyyuvgukqejijxmifmtnatbrqozldwidoyatssjtwtltstqjbkyatycaiikyrzriatcycegytqlycnvxdrebfrgkncsgpetakhjfrgfapgrsozefhjlxblbnoglustcyycktnmsdetewbusmfrgsybgyyuvgdicfrdlocyrpetyzhmeiyeadihltxnoiobyrmceglrgavseoepowbcdhmtlitctbtlloietkttlchmeurxcarhwrfqpycgurzstzglnsnoee'"
+      ]
+     },
+     "execution_count": 29,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "vb5 = vigenere_decipher(scb, 'kccgi')\n",
+    "vb5"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'iya'"
+      ]
+     },
+     "execution_count": 30,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cat(unpos(caesar_break(section)[0]) for section in every_nth(scb, 3))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'qmuxtqzwdvsrybphksezoggyrwdgimhrrdbqsgrdqpfnonmtnhnpqyreqvbonfvwexmcitmvynbwlrnrsdcrzftoqbfkmdydxiglcuiiofdljhlfogefrhabnkgczvpfbgsxmibmxocnqdrgztoncmykuctdhjdgseggiykuczinflqllrkpwiedyvxfbefbkizcegkasgqoaqegdohveeokzergevfnwvlocuiyycgftbizuxlkaoqxtgwraymzhddbqcwaakaodogcmcjdfieidtggiuwgchgqwcrkekspmiaccnxoedelrvmnknjtijfbgdvyjjtsyziccosbklhkzillpgedrzbungacikmbodzmihkaodosqbedodyekqgdavgcbpeeffbgsxmibmxnbedfxbiwuiivsltunigzgtlvhwbswtvuqqetepnlthvcuxgknrftunnavocxcbqbcaeorabonlgeouezedltzabslvurkdyhetbnemokgcsrfxlqtoncofiucybgzgyfmnvgblocgueetyfyvjpsatninccutufffmqinwgbgfyduinowwkuzqiqziazrrkleknderfabgftiikseucrjfxlqtonistkgutkxarfndhkawiewbszxgetojgisygegfxmaanlzypmotarjddeidavfojkedhidbdbunuvquvmwirbcansqogisxtadnxyaghtynyvflwgrxabywonemovldfqsyyrqqksefcpnryjjgtmxfvomztpyxgzgfksvfmgkrnzraelomdrgioknoeuffybuniawokrnzsqdolpvzhlswtwebyabgftcibkvldaimfeditackuxtaakfildsmikifixccozwrepqkknovlpzsycaidhkiimsqurlfctidhfpjwemcerargpkvzimvlocrqbyytzlawovmuiosrudqtopcieosahlpaeauezvosetvlagzgcumncnhkrvtyjwottoljjufrvlqfptgwlcihzusuikxpyrtonistkgutkrwkkqegbgymueebcwahdloksumeafpxgrhuebjjuixhirhwoamrkqivmbwdyrmddanlcppkeccextgtdlaavvftbtiugrssonemowoatefxcitohiacxvnuraentqhpfotkrogmhfbsqqnbgfmrarjaeezsmodohkuusiqltyduzgliifkasgaeakeksppkedbogfbgplhcgblocsiyejcqnaiduiqczkdboatvvckhcucyxagaanlzymvlocrqbyirqqnjpuxuusogwzettgjjurvjhlycqlsafvovftsenfpzakargywvuxgafctyzuiiamvnkdkagfakargbgsnatdfqiranzfoykewisdpzdafpqizithiyzzyrkgljwogtatqfhftsnhfygfrpuqyjqyagraivobnixhqgrtrybchkrdgueetyfmfmqvmrnhizesoftmgrhcxarohphbsefvppkgnwsqszywnlthekumyybrihsufmomruxgnxyayzuiiamdtfycrmdhkgvmymsgzgoyeteggpugrioaaocrgeldmgqnlocfdhqgyznvujshlwavnfinclvbgfcupgcxtgttonugnkwhgxxrghntmgiomeqyxgzgqsrajjuvduoudolgmbaippiumyybgddblptjwoduorfbdksuigpwvucdnhsgretuvgyifafrnrgzmsxcwiytwhkgzehtonjbsmuutcdbueebhdmolocsiyejedmpcssenereagaaasmabvkgwibgzgrkgodkpmqchlfjetxrakmfeuxguzedvsnlvocvqewqcohywrdiscwounraesyltqumryrookhyersmvumvkmpyudperlonmwolycarxdfglynpghkocsoqxgatgfsppkncsysghqkaodowosctsdbsironvivftoyjfhcipqsibuwlrgdfxytclvsgcxaakscoerltcibececqinuryoppfltiddbqerissrybimlldbqzevgduihmhlljhlfftosnoabecaaudhqydqvyejwwodbqmchgkaodofmedbnfsiydrybgblocsiyejitnnfvqmqzibggkgxtaiduiqczyqfidtontqvgvzdvfsoefmnbtelocebrggrtylnyrceeebtwzzsnhavqig'"
+      ]
+     },
+     "execution_count": 31,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "vb3 = vigenere_decipher(scb, 'iya')\n",
+    "vb3"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:418: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n",
+      "  \"matplotlib is currently using a non-GUI backend, \"\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f74b5baaa90>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fp = collections.Counter(vb5)\n",
+    "plot_frequency_histogram(fp, sort_key=fp.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:418: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n",
+      "  \"matplotlib is currently using a non-GUI backend, \"\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f74b458ec50>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fp = collections.Counter(every_nth(scb, 15)[0])\n",
+    "plot_frequency_histogram(fp, sort_key=fp.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'etoainhsrdlumwycfgpbvkxjqz'"
+      ]
+     },
+     "execution_count": 34,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ltrs = [p[0] for p in english_counts.most_common()]\n",
+    "cat(ltrs)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'trguenloasybvhmqdifpkxwzcj'"
+      ]
+     },
+     "execution_count": 35,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ctls =  [p[0] for p in collections.Counter(sanitise(vb)).most_common()]\n",
+    "cat(ctls)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 36,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'a': 'r',\n",
+       " 'b': 'u',\n",
+       " 'c': 'q',\n",
+       " 'd': 'f',\n",
+       " 'e': 'i',\n",
+       " 'f': 'p',\n",
+       " 'g': 'o',\n",
+       " 'h': 'w',\n",
+       " 'i': 'g',\n",
+       " 'j': 'z',\n",
+       " 'k': 'v',\n",
+       " 'l': 'h',\n",
+       " 'm': 'y',\n",
+       " 'n': 'n',\n",
+       " 'o': 's',\n",
+       " 'p': 'b',\n",
+       " 'q': 'c',\n",
+       " 'r': 't',\n",
+       " 's': 'd',\n",
+       " 't': 'e',\n",
+       " 'u': 'a',\n",
+       " 'v': 'm',\n",
+       " 'w': 'x',\n",
+       " 'x': 'k',\n",
+       " 'y': 'l',\n",
+       " 'z': 'j'}"
+      ]
+     },
+     "execution_count": 36,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "trans = {pr[1]: pr[0] for pr in zip(ltrs, ctls)}\n",
+    "trans"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 37,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'Bgas eonhcmr tfn aoodmjiamht if hato ntauoo mi flb vjeygeiwff phtycrney umn inrtmea mf Jomwtitgt tij neeqoioy al Ehke hv ana eij hr wue fein, ty yoyooej hf aso Rktaohe. Se notoej usd stko aeeemlco rih dn koaej lua lc Ehxxamii al hhas Inubaiur Ourgapur lih Beotimsr Neioymv, jua wse Alyn bone oaieehur iiy, ooitpvtlff auo chnr dr ebe Plyez eektgheh d nedoew, xihbt dibi ah i req fhftf yhxwtyon relk aso Hmfms. Dslcgdcf pudhyxiw wh ooatoy uqn hywwoy dsenumw dr ebe Tyumfi tn t vlog yr pluoiae, aso Rktaohe ndieey sgi ana rtwe hn lasee emygotdey aoieoikn cpy, al aso ruodeqnd yr nlke, uo btn ixtpney womsvdstf eeiyotwmhtr. T naiuud ctn ooedwey lc usd Seiiae lt ase lnydw hr wse Ovdeoln, lrm, atxei gfc, Tweqpvtt bin nota ah fqgd rumoacc li smr wtxxcf onaiwe bsone na btr aetjey lc usd Akdoohe’r hbi pmfyxpmiin. Ugn yeius sdn t aomomhun rmhiv ah ve, ttj t dtghrrt egoia wl tcc uqn jwmetyn. Gw btn nrce dn t eetf fhnn obef jf auhno wh bsli sd ctn tha poonhtlcbi zilbi. Tskleea, kvwehmeo, ln ase pddrttpo tij wse lsaf xdnnon pive ah uqn nyuno; tij gi duhkmi ectden, ity bsonewao zthar lr atfceps beee trreklfry, nxn iike qin hi ikc bxdn; tho jgy t nghwba nhsc ht uetoghw vu smr yeiws oebdmia ta wse tobn he whpgea ga jsgpzcc. Usas nfvdtwuf btr qiiwetrey hc ase qqyd-sdooty eskhue uscm se uty hoei ooihway lc dhgrhi ht usd Akdoohe’r phkvlih. Nhkgamit chnw hh exke gi tpphmiwqio mse iklgwmhur Atbqnagun Fspucfgn cs aso ieq ahgeehhp yr aue delgmidr. Sd ctn dsteaey bgus yapuemia wse relwate dotpo qmas Dlcdnhigt ttj setjry ebeoo ah dlirolha Idcwipur. Ga btr dibi asoi auia aso khys hr wse Dlyex qln pageicej. Rtcurumrs bolae ln smn rmhiv ta wse tobn mt l cdmaee ah Diah yiueh mse nmrwu ytf hrrvwe aue zifeiyr dr Xdf mt aso ceto lw ana phtnufrsmdr dr Xdopsn Teeepmtgn Itekoin GG tiy Fgpaqn Lielgsn Shtdocmun. “Qe teo exdernytf putoaoy lf lgo xyna vuignmpetu tfn woota Ovdeoln Yvlmagti wl nepsne Tdx Olktti mi aur Ivwasooi Xgiwylin cpy foa fls bomwr av le hn aso fhnn lw ana Phjex Ldpucwdorl. Fhso coiyeo Isoaohci str icoeief tdmy wse pempe lw nros t fhnr, hua mn vhr nh ila oodhgee usd Ohyox lonhoe wme tdnngiw ln ase crtp mset fhs vtf lo aupa asia fls bmcf zhap smv. Fhs wecc vr anda mtaeffmwetye jwhk i ptpwuoej adq suwaenwr astw usd motgahe Dtcwiyuy btn wse Dlyex ihy as ktrnmta smn rgdtyoaoon gt ase Tdoeb. Bsgce wue Lteptpxtir asovnecmrn cwe utcmxocf al itga kuds hn wse Pleem, Otcatpsr mn tt ryrotaoy Olvti tte sd lunw le rwhddoe lduhoo se dii yeruovi aso nedsomac dr ebe Mvdeegtc pgjsdwn. Aue Pljex bgkc ka oedhgoeey, he vhr, ihue rtvgcf tte ewaoflie clu zilx batc dif auo domdr. Tfn nh wh auo negohan etow hr wue aosr neyof lr Taemphfl mf csmds auo rtao dr ebe igiau fewmlh tfn hr wse Dlyex gundtr bgcc gt amko pe pageicej. Siamf usdp ma qmcf he wuinydn lf wse itpmetu Lcjfclimit Whyjrny yr Bio.'"
+      ]
+     },
+     "execution_count": 37,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "tt = ''.maketrans(trans)\n",
+    "# tpack(repunctuate(vb.translate(tt), pub))\n",
+    "repunctuate(vb.translate(tt), pub)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 38,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Zxlv ehbtfms iyb lhhcmjolmti oy tlih bilrhh mo ydz ujeaxeonyy ktiafsbea rmb obsimel my Jhmnioixi ioj\n",
+      "beephoha ld Etqe tu lbl eoj ts nre yeob, ia ahahhej ty lvh Sqilhte. Ve bhihej rvc viqh leeemdfh sot\n",
+      "cb qhlej drl df Etwwlmoo ld ttlv Obrzlors Hrsxlkrs dot Zehiomvs Beohamu, jrl nve Ldab zhbe hloeetrs\n",
+      "ooa, hhoikuidyy lrh ftbs cs eze Kdaeg eeqixtet c bechen, wotzi cozo lt o sep ytyiy atwniahb sedq lvh\n",
+      "Tmymv. Cvdfxcfy krctawon nt hhliha rpb tannha cvebrmn cs eze Iarmyo ib i udhx as kdrhole, lvh\n",
+      "Sqilhte bcoeea vxo lbl sine tb dlvee emaxhicea lhoehoqb fka, ld lvh srhcepbc as bdqe, rh zib owikbea\n",
+      "nhmvucviy eeoahinmtis. I blorrc fib hhecnea df rvc Veoole di lve dbacn ts nve Hucehdb, dsm, liweo\n",
+      "xyf, Inepkuii zob bhil lt ypxc srmhlff do vms niwwfy hblone zvhbe bl zis leijea df rvc Lqchhte’s tzo\n",
+      "kmyawkmoob. Rxb aeorv vcb i lhmhmtrb smtou lt ue, iij i cixtssi exhol nd iff rpb jnmeiab. Xn zib\n",
+      "bsfe cb i eeiy ytbb hzey jy lrtbh nt zvdo vc fib itl khhbtidfzo godzo. Ivqdeel, qunetmeh, db lve\n",
+      "kccsiikh ioj nve dvly wcbbhb koue lt rpb barbh; ioj xo crtqmo eficeb, oia zvhbenlh gitls ds liyfekv\n",
+      "zeee isseqdysa, bwb ooqe pob to oqf zwcb; ith jxa i bxtnzl btvf ti reihxtn ur vms aeonv hezcmol il\n",
+      "nve ihzb te ntkxel xl jvxkgff. Rvlv byucinry zis pooneisea tf lve ppac-vchhia evqtre rvfm ve ria\n",
+      "theo hhotnla df ctxsto ti rvc Lqchhte’s ktqudot. Btqxlmoi ftbn tt ewqe xo ikktmonpoh mve oqdxnmtrs\n",
+      "Lizpblxrb Yvkrfyxb fv lvh oep ltxeettk as lre cedxmocs. Vc fib cvielea zxrv alkremol nve sednlie\n",
+      "chikh pmlv Cdfcbtoxi iij veijsa ezehh lt cdoshdtl Ocfnokrs. Xl zis cozo lvho lrol lvh qtav ts nve\n",
+      "Cdaew pdb klxeofej. Sifrsrmsv zhdle db vmb smtou il nve ihzb mi d fcmlee lt Colt aoret mve bmsnr aiy\n",
+      "tssune lre goyeoas cs Wcy mi lvh feih dn lbl ktibrysvmcs cs Wchkvb Ieeekmixb Oieqhob XX ioa Yxklpb\n",
+      "Doedxvb Vtichfmrb. “Pe ieh ewcesbaiy krihlha dy dxh wabl uroxbmkeir iyb nhhil Hucehdb Audmlxio nd\n",
+      "bekvbe Icw Hdqiio mo lrs Ounlvhho Wxonadob fka yhl ydv zhmns lu de tb lvh ytbb dn lbl Ktjew\n",
+      "Dckrfnchsd. Ytvh fhoaeh Ovhlhtfo vis ofheoey icma nve kemke dn bshv i ytbs, trl mb uts bt odl\n",
+      "hhctxee rvc Htahw dhbthe nme icbbxon db lve fsik mvei ytv uiy dh lrkl lvol ydv zmfy gtlk vmu. Ytv\n",
+      "neff us lbcl mileyymneiae jntq o kiknrhej lcp vrnlebns lvin rvc mhixlte Cifnoara zib nve Cdaew ota\n",
+      "lv qisbmil vmb sxciahlhhb xi lve Ichez. Zvxfe nre Diekikwios lvhubefmsb fne rifmwhfy ld oixl qrcv tb\n",
+      "nve Kdeem, Hiflikvs mb ii sashilha Hduio iie vc drbn de sntcche dcrthh ve coo aesrhuo lvh becvhmlf\n",
+      "cs eze Muceexif kxjvcnb. Lre Kdjew zxqf ql hectxheea, te uts, otre siuxfy iie enlhydoe fdr godw zlif\n",
+      "coy lrh chmcs. Iyb bt nt lrh bexhtlb eihn ts nre lhvs beahy ds Ilemktyd my fvmcv lrh silh cs eze\n",
+      "oxolr yenmdt iyb ts nve Cdaew xrbcis zxff xi lmqh ke klxeofej. Volmy rvck ml pmfy te nrobacb dy nve\n",
+      "oikmeir Dfjyfdomoi Ntajsba as Zoh.\n"
+     ]
+    }
+   ],
+   "source": [
+    "trans = {\n",
+    " 'a': 's',\n",
+    " 'b': 'r',\n",
+    " 'c': 'p',\n",
+    " 'd': 'y',\n",
+    " 'e': 'o',\n",
+    " 'f': 'k',\n",
+    " 'g': 'h',\n",
+    " 'h': 'n',\n",
+    " 'i': 'x',\n",
+    " 'j': 'g',\n",
+    " 'k': 'u',\n",
+    " 'l': 't',\n",
+    " 'm': 'a',\n",
+    " 'n': 'b',\n",
+    " 'o': 'v',\n",
+    " 'p': 'z',\n",
+    " 'q': 'f',\n",
+    " 'r': 'i',\n",
+    " 's': 'c',\n",
+    " 't': 'e',\n",
+    " 'u': 'l',\n",
+    " 'v': 'm',\n",
+    " 'w': 'w',\n",
+    " 'x': 'q',\n",
+    " 'y': 'd',\n",
+    " 'z': 'j'}\n",
+    "\n",
+    "\n",
+    "tt = ''.maketrans(trans)\n",
+    "print(lcat(tpack(repunctuate(vb.translate(tt), pub).split())))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 39,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('jcarykujniqadmv', 15)"
+      ]
+     },
+     "execution_count": 39,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kbv, len(kbv)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 40,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['jkq', 'cua', 'ajd', 'rnm', 'yiv']"
+      ]
+     },
+     "execution_count": 40,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "every_nth(kbv, 5)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 41,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# def index_of_coincidence(text):\n",
+    "#     stext = sanitise(text)\n",
+    "#     counts = collections.Counter(stext)\n",
+    "#     denom = len(stext) * (len(text) - 1) / 26\n",
+    "#     return (\n",
+    "#         sum(max(counts[l] * counts[l] - 1, 0) for l in string.ascii_lowercase) \n",
+    "#         / \n",
+    "#         denom\n",
+    "#     )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 42,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1.0739632382990911"
+      ]
+     },
+     "execution_count": 42,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "index_of_coincidence(scb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 43,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1.7196234250491917"
+      ]
+     },
+     "execution_count": 43,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "index_of_coincidence(pa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 44,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "1 1.0739632382990911\n",
+      "2 1.0847309682648545\n",
+      "3 1.1901326088129982\n",
+      "4 1.0944337274794889\n",
+      "5 1.3385608752635192\n",
+      "6 1.2148423611711687\n",
+      "7 1.1475045557348746\n",
+      "8 1.126018862329491\n",
+      "9 1.246033937674865\n",
+      "10 1.387327185449383\n",
+      "11 1.1687618776366193\n",
+      "12 1.2613508799467053\n",
+      "13 1.1901044676035653\n",
+      "14 1.1988503247011726\n",
+      "15 1.8423114658282445\n",
+      "16 1.1835776099617201\n",
+      "17 1.229047094202011\n",
+      "18 1.3067952909636624\n",
+      "19 1.2593538199678038\n"
+     ]
+    }
+   ],
+   "source": [
+    "for i in range(1, 20):\n",
+    "    print(i, sum(index_of_coincidence(section) for section in every_nth(scb, i)) / i)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 45,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(1, 1.0739632382990911),\n",
+       " (2, 1.0847309682648545),\n",
+       " (4, 1.0944337274794889),\n",
+       " (8, 1.126018862329491),\n",
+       " (7, 1.1475045557348746),\n",
+       " (11, 1.1687618776366193),\n",
+       " (16, 1.1835776099617201),\n",
+       " (13, 1.1901044676035653),\n",
+       " (3, 1.1901326088129982),\n",
+       " (14, 1.1988503247011726),\n",
+       " (6, 1.2148423611711687),\n",
+       " (17, 1.229047094202011),\n",
+       " (9, 1.246033937674865),\n",
+       " (19, 1.2593538199678038),\n",
+       " (12, 1.2613508799467053),\n",
+       " (18, 1.3067952909636624),\n",
+       " (5, 1.3385608752635192),\n",
+       " (10, 1.387327185449383),\n",
+       " (15, 1.8423114658282445)]"
+      ]
+     },
+     "execution_count": 45,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ics = [(i, sum(index_of_coincidence(section) for section in every_nth(scb, i)) / i)\n",
+    "       for i in range(1, 20)]\n",
+    "sorted(ics, key=lambda p: p[1])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 46,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'etgyasrlhmbcinkoudfwqvjpxz'"
+      ]
+     },
+     "execution_count": 46,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ctls =  [p[0] for p in collections.Counter(sanitise(vb5)).most_common()]\n",
+    "cat(ctls)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 47,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'a': 'i',\n",
+       " 'b': 'l',\n",
+       " 'c': 'u',\n",
+       " 'd': 'g',\n",
+       " 'e': 'e',\n",
+       " 'f': 'p',\n",
+       " 'g': 'o',\n",
+       " 'h': 'r',\n",
+       " 'i': 'm',\n",
+       " 'j': 'x',\n",
+       " 'k': 'y',\n",
+       " 'l': 's',\n",
+       " 'm': 'd',\n",
+       " 'n': 'w',\n",
+       " 'o': 'c',\n",
+       " 'p': 'j',\n",
+       " 'q': 'v',\n",
+       " 'r': 'h',\n",
+       " 's': 'n',\n",
+       " 't': 't',\n",
+       " 'u': 'f',\n",
+       " 'v': 'k',\n",
+       " 'w': 'b',\n",
+       " 'x': 'q',\n",
+       " 'y': 'a',\n",
+       " 'z': 'z'}"
+      ]
+     },
+     "execution_count": 47,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "trans = {pr[1]: pr[0] for pr in zip(ltrs, ctls)}\n",
+    "trans"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 48,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Pfwq spkxhbm nuc jvymakoeeun xh etfv nnhcpm en hpj dlolfslvlj punapbcol dbx aqfrtsf bu Lcxgnlnmh rnk\n",
+      "dsopcdyf hu Hqte gr wtt odh gz vgd oead, nv iclyerk bj dce Mqftcfq. Or lphnek sol rfuy wrshvzhe mae\n",
+      "et uywrk tld gp Ggnyjxta hu bqdc Adcytkra Eyimepoi pae Hovbaaoy Kaneabd, lxb gor Wtuu reds ctkwqgyi\n",
+      "opq, sexniufkvh hcp rxii yi oho Erfrz hdtathse e twxerv, epxrn yaym jf t irr lqoah agnbflyl zstz dce\n",
+      "Hbuzz. Smuktrro mcygvykt gg jeahnk cwl eirtyf cohkftv yi oho Mpcaho hu a ypeh ib ercjaad, dce\n",
+      "Mqftcfq lcahdq ctx wtt bmgs wl tekes gbvxcmxsb wppasajl gsv, br wqe ylndswll ib orqr, cp cri aonicol\n",
+      "geaowakah gskicmgbwny. H uvascl afo yermndq gp sol Rodtwr uc eke udflb ec gor Ewaasud, ubz, jmisl\n",
+      "tlr, Rwswdddf ptl xece du hwtl oxxywkp tp kti knnyga ylhand iceds tt yma wrnzdq gp sol Tmsyews’y qin\n",
+      "dlhvyixtax. Cmk qeaso zet m ueaedqfi ilgku jf os, inz h hathibd ozyah vt hch cwl wbpwbfx. Tn cri\n",
+      "lmpo et m qsih lqui evsu lu bdgxe nq icux ol afo bgh dpmuunppym adrjl. Nuzzesf, qdbofksj, uq eke\n",
+      "dymbdfey nlk nia gofh netoyl oawd du cwl tixoy; nlk mp hogjbk vgmxsx, acu icedsrtc ybghi tf dahtsir\n",
+      "ywqs iiydtghmf, tyt dtqr rok xn ajp yylo; bgj kmu r ithvyt tfmp wn gdrsthv dj zxa frani nejybkt fb\n",
+      "gor npcu us kgixob fw tomnwhp. Sojr taomivgj iai wakbomasb gi eke rwfl-rlvynb suzxos sogz zw dnb\n",
+      "gpdj sexgrtv kw mwtyqj un sol Tmsyews’y nxyypae. Ceufwaac rxiv hg oymw fa idjqenvwac zzw tqvtnvxoi\n",
+      "Fnyptbfcx Hunfhhil gr jjy arr aqseshgi ib bds cstwenmm. Ol afo xoisadq rtso vtirqblw nia lspvjdo\n",
+      "synoe fvdc Mpplcedfn inz iaakmf ohovy ww mtpgsuhw Kegttdyi. Me iai yaym jjya hcoe dce jgvr ec gor\n",
+      "Mtuaz rpl ithwtprk. Yhcoisbbr yvrwr uq iei ilgku fb gor npcu tn p plzjwq ww Moex kasse zzw nbzvg urp\n",
+      "gmidbo bds maldjki yi Neu xb wqe idrs uk wtt ifblyhyiedi yi Neceml Ishdptnil Kdouyax TM hjk Hidjpt\n",
+      "Ktsvtuk Kunyegzxo. “Es isp dvdsmlvdu ednjwpu zp uie nitb ocltqvpens nuc rvynh Ewaasud Fdfpbfnl vt\n",
+      "kamods Fen Vrqino vj vcm Adbjjyel Xmpmkuxl gsv ayw fuu cntvm wd fo fn wqe lqui uk wtt Ifhsd\n",
+      "Urnfhvyebf. Ufme keouas Aeejwent oii orneagh fepl gor dhvpe uk lbwz m vgxi, bld tl rgb ce drw\n",
+      "jerqses sol Welyx veqqne vls fetofap uq eke pmni zzwb hwo who ge fcit jjtw fuu cehh cgjs zxo. Hwo\n",
+      "ndch ym wtej xbwrhlvmenas wbeu t didnlnek fmq rxtusxvy ekav sol zcmfwws Rhcwaacv hfo gor Mtuaz ahf\n",
+      "jr mmalana iei iimficbyex tc eke Nyeoh. Yjfpr vgd Zasqniyfda wqewkahbml gbo rbpaxpro vu xnht mrxo wl\n",
+      "nia Mugsp, Wfnunooy vu an mfbwfbyf Juwhj ang ol fxog ur inqhdeg uljevy or mop qeisedm jjy lrmumevp\n",
+      "yi oho Xomrsmhc mtnolbt. Bds Ouzdv rtjp mt cwxgnehdq, us rgb, merq iiymro ang srtcarar ptl wnuo jjdg\n",
+      "sth hcp antmm. Nuc tf gg hcp kabehwt vfvg gz vgd dsom loica ri Iwhvpuhp bu azxxo hcp frve yi oho\n",
+      "dfahc ldmtuh nuc ec gor Mtuaz tslldb pfpk tc eeye qs ithwtprk. Updth sols pb ebkh bd moadflc sa gor\n",
+      "acneens Uglunraaac Sxkkmlv ib Pte.\n"
+     ]
+    }
+   ],
+   "source": [
+    "trans = {\n",
+    " 'a': 'i',\n",
+    " 'b': 'c',\n",
+    " 'c': 'r',\n",
+    " 'd': 'h',\n",
+    " 'e': 'a',\n",
+    " 'f': 'd',\n",
+    " 'g': 'e',\n",
+    " 'h': 'v',\n",
+    " 'i': 't',\n",
+    " 'j': 'z',\n",
+    " 'k': 'y',\n",
+    " 'l': 'g',\n",
+    " 'm': 'f',\n",
+    " 'n': 'l',\n",
+    " 'o': 'o',\n",
+    " 'p': 'j',\n",
+    " 'q': 'p',\n",
+    " 'r': 'n',\n",
+    " 's': 'm',\n",
+    " 't': 's',\n",
+    " 'u': 'w',\n",
+    " 'v': 'b',\n",
+    " 'w': 'x',\n",
+    " 'x': 'q',\n",
+    " 'y': 'u',\n",
+    " 'z': 'k'}\n",
+    "\n",
+    "tt = ''.maketrans(trans)\n",
+    "print(lcat(tpack(repunctuate(vb3.translate(tt), pub).split())))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 49,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "149.2"
+      ]
+     },
+     "execution_count": 49,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(scb)/15"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 50,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[((7, 20, True), -192.8137923614311),\n",
+       " ((7, 0, True), -180.2911386965482),\n",
+       " ((7, 11, True), -183.95343106989503),\n",
+       " ((7, 2, True), -181.0350604256714),\n",
+       " ((7, 22, True), -192.14210180827317),\n",
+       " ((7, 8, True), -189.97699806864554),\n",
+       " ((7, 5, True), -183.3749838057261),\n",
+       " ((7, 20, True), -196.06251170079523),\n",
+       " ((7, 24, True), -192.12634724908915),\n",
+       " ((7, 6, True), -186.7317665812622),\n",
+       " ((7, 8, True), -186.75777446041903),\n",
+       " ((7, 11, True), -188.32887282416843),\n",
+       " ((7, 13, True), -193.76214231086124),\n",
+       " ((7, 24, True), -190.6840821835727),\n",
+       " ((7, 6, True), -188.8811192976835)]"
+      ]
+     },
+     "execution_count": 50,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[affine_break(section) for section in every_nth(scb, 15)]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 51,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(7, 20, True),\n",
+       " (7, 0, True),\n",
+       " (7, 11, True),\n",
+       " (7, 2, True),\n",
+       " (7, 22, True),\n",
+       " (7, 8, True),\n",
+       " (7, 5, True),\n",
+       " (7, 20, True),\n",
+       " (7, 24, True),\n",
+       " (7, 6, True),\n",
+       " (7, 8, True),\n",
+       " (7, 11, True),\n",
+       " (7, 13, True),\n",
+       " (7, 24, True),\n",
+       " (7, 6, True)]"
+      ]
+     },
+     "execution_count": 51,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "akeys = [affine_break(section)[0] for section in every_nth(scb, 15)]\n",
+    "akeys"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 52,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'withresolveandtrepidationmydearfatherinlawobedientlyconcludedhisaffairsinbritanniaandreturnedtoromebytheendoftheyearasorderedbytheemperorhefearedthesameterribleendasmetedoutbydomitiantobotharulenusrusitcusandhernniusseneciobutthegodsweregenerousandremarkablythelossofthecodexremainedasecretknownonlytoafewloyalcomradesfromtheninthpubliclychoosingtoregardhisdoggedpursuitoftheaquilaasamarkofcouragetheemperorsparedhimthefateofotherdisgracedgeneralsandtothesurpriseofsomehewasawardedtriumphaldecorationsastatuewaserectedbythesenateontheorderoftheemperorbuttakenillagricolawassenttolivequietlyonhisfamilyestatewherehewastendedbytheemperorsownphysicianshisdeathwasagrievousshocktomeandapainfuleventtoallhisfriendsitwasfeltasareallossevenbythosetowhomhewasnotpersonallyknownnumbersmoreoverofthepopulaceandthebusymassescametohishouseandinpublicplacesandwhereverknotsoftalkerswereassembledhisnamewasonalllipsnordidasinglesoulonhearingofhisdeathrejoiceatthenewsorforgetitquicklythissympathywasincreasedbythewidespreadrumourthathehadbeenremovedbypoisonontheemperorscommanddomitianlostnotimeinappointingtheambitioussalustiuslucullusasthenewgovernoroftheprovincehewaschargedwithsecuringthefragilepeacewithcaledoniaandheadedtheretoconfrontcalgacusitwasonlythenthatthelossofthecodexwasrevealedsalustiuswroteofhisshockatthenewsinalettertocatodatedthefifthdaybeforethekalendsofmayintheyearoftheconsulshipsofmarcusarrecinusclemensiiandluciusbaebiushonoratusweareexpresslychargedbyourmostmunificentandgreatemperordomitiantosecurepaxromanainthenorthernkingdomsandyetyouwritetomeofthelossofthecodexoccultorumyourleaderagricolahasalreadypaidthepriceofsuchalossbutifyoudonotrecoverthecodexbeforethepassingoftheyearthenyoumaybesurethatyouwilljoinhimyoutellmethatintelligencefromacapturedspysuggeststhatthetraitorcalgacushasthecodexandismassinghissupportersinthenorthwhilethebarbariansthemselvesareunlikelytomakemuchofthecodexcalgacusisaneducatedromanandhemustbestoppedbeforehecandestroythesecurityoftheimperialciphersthecodexwillberecoveredoryouyourfamilyandeveryoneyouknowwillpaythepriceandsototheseventhpartofthetruestoryofagricolainwhichthefateoftheninthlegionandofthecodexitselfwillintimeberevealeduntilthenitwillbeguardedbytheancientbabyloniangoddessofwar'"
+      ]
+     },
+     "execution_count": 52,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "spb = combine_every_nth(affine_decipher(section, key[0], key[1], key[2]) \n",
+    "                  for key, section in zip(akeys, every_nth(scb, 15)))\n",
+    "spb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 53,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "With resolve and trepidation my dear father in law obediently concluded his affairs in Britannia and\n",
+      "returned to Rome by the end of the year, as ordered by the Emperor. He feared the same terrible end\n",
+      "as meted out by Domitian to both Arulenus Rusitcus and Hernnius Senecio, but the Gods were generous\n",
+      "and, remarkably the loss of the Codex remained a secret, known only to a few loyal comrades from the\n",
+      "Ninth. Publicly choosing to regard his dogged pursuit of the Aquila as a mark of courage, the\n",
+      "Emperor spared him the fate of other disgraced generals and, to the surprise of some, he was awarded\n",
+      "triumphal decorations. A statue was erected by the Senate on the order of the Emperor, but, taken\n",
+      "ill, Agricola was sent to live quietly on his family estate where he was tended by the Emperor’s own\n",
+      "physicians. His death was a grievous shock to me, and a painful event to all his friends. It was\n",
+      "felt as a real loss even by those to whom he was not personally known. Numbers, moreover, of the\n",
+      "populace and the busy masses came to his house; and in public places, and wherever knots of talkers\n",
+      "were assembled, his name was on all lips; nor did a single soul on hearing of his death rejoice at\n",
+      "the news or forget it quickly. This sympathy was increased by the wide-spread rumour that he had\n",
+      "been removed by poison on the Emperor’s command. Domitian lost no time in appointing the ambitious\n",
+      "Salustius Lucullus as the new governor of the province. He was charged with securing the fragile\n",
+      "peace with Caledonia and headed there to confront Calgacus. It was only then that the loss of the\n",
+      "Codex was revealed. Salustius wrote of his shock at the news in a letter to Cato dated the fifth day\n",
+      "before the kalends of May in the year of the consulships of Marcus Arrecinus Clemens II and Lucius\n",
+      "Baebius Honoratus. “We are expressly charged by our most munificent and great Emperor Domitian to\n",
+      "secure Pax Romana in the Northern Kingdoms and yet you write to me of the loss of the Codex\n",
+      "Occultorum. Your leader Agricola has already paid the price of such a loss, but if you do not\n",
+      "recover the Codex before the passing of the year then you may be sure that you will join him. You\n",
+      "tell me that intelligence from a captured spy suggests that the traitor Calgacus has the Codex and\n",
+      "is massing his supporters in the North. While the Barbarians themselves are unlikely to make much of\n",
+      "the Codex, Calgacus is an educated Roman and he must be stopped before he can destroy the security\n",
+      "of the Imperial ciphers. The Codex will be recovered, or you, your family and everyone you know will\n",
+      "pay the price. And so to the seventh part of the true story of Agricola in which the fate of the\n",
+      "ninth legion and of the Codex itself will in time be revealed. Until then it will be guarded by the\n",
+      "ancient Babylonian Goddess of War.\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(repunctuate(spb, pub).split())))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 54,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'ualcwifuygilnyg'"
+      ]
+     },
+     "execution_count": 54,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cat(unpos(k[1]) for k in akeys)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 55,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'h'"
+      ]
+     },
+     "execution_count": 55,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "unpos(7)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 56,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2793"
+      ]
+     },
+     "execution_count": 56,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('6b.plaintext', 'w').write(lcat(tpack(repunctuate(spb, pub).split())))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# The \"model answer\"\n",
+    "The first time I've seen the National Cipher Challenge has used a zero-based affine cipher!"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 57,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'withresolveandtrepidationmydearfatherinlawobedientlyconcludedhisaffairsinbritanniaandreturnedtoromebytheendoftheyearasorderedbytheemperorhefearedthesameterribleendasmetedoutbydomitiantobotharulenusrusitcusandhernniusseneciobutthegodsweregenerousandremarkablythelossofthecodexremainedasecretknownonlytoafewloyalcomradesfromtheninthpubliclychoosingtoregardhisdoggedpursuitoftheaquilaasamarkofcouragetheemperorsparedhimthefateofotherdisgracedgeneralsandtothesurpriseofsomehewasawardedtriumphaldecorationsastatuewaserectedbythesenateontheorderoftheemperorbuttakenillagricolawassenttolivequietlyonhisfamilyestatewherehewastendedbytheemperorsownphysicianshisdeathwasagrievousshocktomeandapainfuleventtoallhisfriendsitwasfeltasareallossevenbythosetowhomhewasnotpersonallyknownnumbersmoreoverofthepopulaceandthebusymassescametohishouseandinpublicplacesandwhereverknotsoftalkerswereassembledhisnamewasonalllipsnordidasinglesoulonhearingofhisdeathrejoiceatthenewsorforgetitquicklythissympathywasincreasedbythewidespreadrumourthathehadbeenremovedbypoisonontheemperorscommanddomitianlostnotimeinappointingtheambitioussalustiuslucullusasthenewgovernoroftheprovincehewaschargedwithsecuringthefragilepeacewithcaledoniaandheadedtheretoconfrontcalgacusitwasonlythenthatthelossofthecodexwasrevealedsalustiuswroteofhisshockatthenewsinalettertocatodatedthefifthdaybeforethekalendsofmayintheyearoftheconsulshipsofmarcusarrecinusclemensiiandluciusbaebiushonoratusweareexpresslychargedbyourmostmunificentandgreatemperordomitiantosecurepaxromanainthenorthernkingdomsandyetyouwritetomeofthelossofthecodexoccultorumyourleaderagricolahasalreadypaidthepriceofsuchalossbutifyoudonotrecoverthecodexbeforethepassingoftheyearthenyoumaybesurethatyouwilljoinhimyoutellmethatintelligencefromacapturedspysuggeststhatthetraitorcalgacushasthecodexandismassinghissupportersinthenorthwhilethebarbariansthemselvesareunlikelytomakemuchofthecodexcalgacusisaneducatedromanandhemustbestoppedbeforehecandestroythesecurityoftheimperialciphersthecodexwillberecoveredoryouyourfamilyandeveryoneyouknowwillpaythepriceandsototheseventhpartofthetruestoryofagricolainwhichthefateoftheninthlegionandofthecodexitselfwillintimeberevealeduntilthenitwillbeguardedbytheancientbabyloniangoddessofwar'"
+      ]
+     },
+     "execution_count": 57,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "affine_decipher(vigenere_decipher(scb, sanitise('Agricolae mortem')), \n",
+    "                multiplier=7, adder=0, one_based=False)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/2017/2017-challenge7.ipynb b/2017/2017-challenge7.ipynb
new file mode 100644 (file)
index 0000000..b8612cc
--- /dev/null
@@ -0,0 +1,1314 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import os,sys,inspect, collections\n",
+    "currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))\n",
+    "parentdir = os.path.dirname(currentdir)\n",
+    "sys.path.insert(0,parentdir) \n",
+    "\n",
+    "import itertools\n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline\n",
+    "\n",
+    "\n",
+    "from cipher.vigenere import *\n",
+    "from cipher.column_transposition import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "from support.plot_frequency_histogram import *\n",
+    "\n",
+    "ca = open('7a.ciphertext').read()\n",
+    "cb = open('7b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "DEYRB UGZWR VEFMY PEOAR GTDHX MGWHR RRQRL GSZVE VVIES UZRTU OEHVR SSLLQ VBCYW YHVRL OEUGV TOTGX DVQWU SBLJN HELFQ ARJLL BIIGK JAEGM QGUTG NQAQC ENRYY VOAIK PNJGC YDRPW VFSOV QOTGK KIAWE TPNIC ZKRZI XUSAW NYEUK XEZWA NKIUE OMQHA TZWWR WTSGN IGZGC ZWYFZ HDNHM GZKRZ GINLO EOGJL RUNZD RTGKD RYABL ROMHE AVDAE CIFOY HKDVN FKTUK QFNZA IJEGW MRBSJ NHELF QANKV NRUNG NKOIL KVFHL FKDRT COEGI EKVFG NMJUX LULXJ SZLNZ MEXKP CDGRV IYGNM YOMHK KSHKL OSGTR DGNUU MNKVI NSVBZ YUIHA UQAAP OBHYA SVGFB LOBHZ UNEHE SHGNM ZEUKL VJTTB QSJOO EEKBU KNAEJ MAYNA EJMAY CEIHI VLOEE UZZGE BVKIW MZTJG VGKJT FFSAX BSRZP RATIE LXVSA EQGVQ ZUAUG EAWET EGTNE KRFIW RUYEP EDVGI OEIYF AVNNH QGROK VKIQG LSOEX VRONX XTPAW HRXAV TZHVV IYSAE EIPNV ZEIVE AQDAL CMNXK IEOYP CAHRO AUZGR XDXRF VWYOD RYONK KICWY GNSWA SASVX QVFIE ERQAG TDZKE CHLNG UPNBK AGDWF LVTUK NHRRC FOPRU AIBTQ NSTOK VYEWO OJZPR ECICO JRWSA OUCGA YDZVQ NFALV TOVZZ OKUCG GMIAJ KUGVT VUWRN LNOAB VLCEV ATYSP NJNIG OYIEL XVKBS CKKGZ NETXV NLVRF ICEOU SZWCJ ASLBB MEIUM VKMFF HTHXI YVXOK HGGAC EAKAF VKRYD TFLOE EKERC OLCIM ASSLL AVYUI KKKIF WJRRZ WSZNE ZAXUD LGVUV GNGTC HEIWZ TUKYH KYTZR RBXOO JCMQK GLNLX UEPDN YIAJS AIBEZ ZHSNI TRBKR ZGINO LSUUC YJREK WLRUV LYKKG UXDVD PJAAH GNMZZ NEIXW FAHNZ GNVGI AEEIC JLTGE ZHZNL VVWVX AHREN RKRBV WVNQL DNTLF NKHRV WHYNE FZMQG CAPZI ZANHG SIXKZ HVWLV WCEFL IYRUU KLXVK HCHTV VTMPC DRNFK IGNQA QOCRQ LRDW\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(ca)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:418: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n",
+      "  \"matplotlib is currently using a non-GUI backend, \"\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAaoAAAEmCAYAAAAz/dRVAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvNQv5yAAAE6JJREFUeJzt3X2wXHV9x/H3Rx6q4gMGrimKGK2MltZB9EqlaseCOLRqoVNqtT7EDk5qq1Xbao21Tq2jM7E6tf7R2qZqTVuqIJWGaqsyAevzQxKCPEQMIlQYIBFFBccH4Ns/9mS4QMie3bt787vZ92vmzp6ze74537t77v3s77fnnqSqkCSpVffZ1w1IkrQ3BpUkqWkGlSSpaQaVJKlpBpUkqWkGlSSpaQaVJKlpBpUkqWkGlSSpaQaVJKlpBy7lzg4//PBatWrVUu5SktSoLVu2fLuq5oZtt6RBtWrVKjZv3ryUu5QkNSrJNX22c+pPktQ0g0qS1DSDSpLUNINKktQ0g0qS1DSDSpLUNINKktQ0g0qS1DSDSpLUNINKktS0Jb2EkiSpTavWfqz3tleve/YUO7knR1SSpKYZVJKkphlUkqSmGVSSpKYZVJKkphlUkqSmGVSSpKYZVJKkpg0NqiSPTbJtwdf3k7wmyYok5yfZ0d0+ZCkaliTNlqFXpqiqK4AnACQ5ALgOOBdYC2yqqnVJ1nbrr59ir5KkIVq+wsS4Rp36Own4RlVdA5wKbOju3wCcNsnGJEmC0YPq+cAHu+WVVXV9t3wDsHJiXUmS1OkdVEkOBn4D+PDdH6uqAupe6tYk2Zxk865du8ZuVJI0m0YZUf0asLWqbuzWb0xyBEB3u3NPRVW1vqrmq2p+bm5ucd1KkmbOKEH1Au6c9gM4D1jdLa8GNk6qKUmSdusVVEkOAU4GPrLg7nXAyUl2AM/s1iVJmqhe/3FiVd0KHHa3+25icBagJElT45UpJElNM6gkSU0zqCRJTTOoJElNM6gkSU0zqCRJTTOoJElNM6gkSU0zqCRJTet1ZQpJ0tLbH/8TxHE4opIkNc2gkiQ1zaCSJDXNoJIkNc2gkiQ1zbP+JGnKPHtvcRxRSZKaZlBJkppmUEmSmuZnVJJmzrifGflZ077hiEqS1DSDSpLUNKf+JC1rTsft/xxRSZKaZlBJkprWK6iSHJrknCRfS7I9yQlJViQ5P8mO7vYh025WkjR7+o6o3g18vKoeBxwLbAfWApuq6mhgU7cuSdJEDQ2qJA8GfgV4H0BV/aSqbgZOBTZ0m20ATptWk5Kk2dVnRPUoYBfwz0kuSvLeJIcAK6vq+m6bG4CV02pSkjS7+gTVgcATgfdU1XHArdxtmq+qCqg9FSdZk2Rzks27du1abL+SpBnTJ6iuBa6tqi916+cwCK4bkxwB0N3u3FNxVa2vqvmqmp+bm5tEz5KkGTI0qKrqBuBbSR7b3XUScDlwHrC6u281sHEqHUqSZlrfK1P8EXBmkoOBq4DfYxByZyc5A7gGeN50WpQkzbJeQVVV24D5PTx00mTbkSTprrwyhSSpaQaVJKlpBpUkqWkGlSSpaQaVJKlpBpUkqWkGlSSpaQaVJKlpBpUkqWkGlSSpaQaVJKlpBpUkqWkGlSSpaQaVJKlpBpUkqWl9/+NESZqqVWs/1nvbq9c9e4qdqDWOqCRJTTOoJElNM6gkSU0zqCRJTTOoJElNM6gkSU0zqCRJTTOoJElN6/UHv0muBn4A3A7cVlXzSVYAZwGrgKuB51XVd6fTpiRpVo1yZYpfrapvL1hfC2yqqnVJ1nbrr59od5KWHa8woUlbzNTfqcCGbnkDcNri25Ek6a76BlUBn0yyJcma7r6VVXV9t3wDsHLi3UmSZl7fqb+nVdV1SR4KnJ/kawsfrKpKUnsq7IJtDcBRRx21qGYlLS2n8dSCXiOqqrquu90JnAscD9yY5AiA7nbnvdSur6r5qpqfm5ubTNeSpJkxNKiSHJLkgbuXgWcBlwLnAau7zVYDG6fVpCRpdvWZ+lsJnJtk9/b/XlUfT/IV4OwkZwDXAM+bXpuSpFk1NKiq6irg2D3cfxNw0jSakiRpN69MIUlqmkElSWqaQSVJappBJUlqmkElSWraKBellbRMeYUJLWeOqCRJTTOoJElNc+pPWkacwtMsckQlSWqaQSVJappBJUlqmkElSWqaQSVJappBJUlqmkElSWqaQSVJappBJUlqmkElSWqaQSVJappBJUlqmkElSWqaV0+X9hGvhC7144hKktS03kGV5IAkFyX5aLf+qCRfSnJlkrOSHDy9NiVJs2qUEdWrge0L1t8OvKuqHgN8Fzhjko1JkgQ9gyrJkcCzgfd26wFOBM7pNtkAnDaNBiVJs63viOpvgT8D7ujWDwNurqrbuvVrgYdPuDdJkoaf9ZfkOcDOqtqS5Bmj7iDJGmANwFFHHTVyg1LrPHtPmq4+I6qnAr+R5GrgQwym/N4NHJpkd9AdCVy3p+KqWl9V81U1Pzc3N4GWJUmzZGhQVdUbqurIqloFPB+4oKpeCFwInN5tthrYOLUuJUkzazF/R/V64E+SXMngM6v3TaYlSZLuNNKVKarqU8CnuuWrgOMn35IkSXfyyhSSpKYZVJKkpnlRWqnjaeZSmxxRSZKaZlBJkprm1J/2O07hSfsXR1SSpKYZVJKkphlUkqSm+RmVmubnTZIcUUmSmmZQSZKaZlBJkppmUEmSmmZQSZKa5ll/WhKevSdpXI6oJElNM6gkSU0zqCRJTTOoJElNM6gkSU0zqCRJTfP0dI3E08wlLTVHVJKkphlUkqSmDQ2qJPdN8uUkFye5LMlfdfc/KsmXklyZ5KwkB0+/XUnSrOkzovoxcGJVHQs8ATglyVOAtwPvqqrHAN8Fzphem5KkWTU0qGrglm71oO6rgBOBc7r7NwCnTaVDSdJM6/UZVZIDkmwDdgLnA98Abq6q27pNrgUePp0WJUmzrFdQVdXtVfUE4EjgeOBxfXeQZE2SzUk279q1a8w2JUmzaqSz/qrqZuBC4ATg0CS7/w7rSOC6e6lZX1XzVTU/Nze3qGYlSbOnz1l/c0kO7ZbvB5wMbGcQWKd3m60GNk6rSUnS7OpzZYojgA1JDmAQbGdX1UeTXA58KMlbgYuA902xT02BV5mQtBwMDaqq+ipw3B7uv4rB51WSJE2NV6aQJDXNi9LuB5zCk7Q/c0QlSWqaQSVJappBJUlqmp9RNcTPmiTpnhxRSZKaZlBJkprm1N8Q407HOY0nSZPhiEqS1DSDSpLUNINKktQ0g0qS1DSDSpLUNINKktS0mTk93dPFJWl5ckQlSWqaQSVJappBJUlqmkElSWqaQSVJappBJUlqmkElSWqaQSVJatrQoEryiCQXJrk8yWVJXt3dvyLJ+Ul2dLcPmX67kqRZ02dEdRvwp1V1DPAU4BVJjgHWApuq6mhgU7cuSdJEDQ2qqrq+qrZ2yz8AtgMPB04FNnSbbQBOm1aTkqTZNdJnVElWAccBXwJWVtX13UM3ACsn2pkkSYwQVEkeAPwH8Jqq+v7Cx6qqgLqXujVJNifZvGvXrkU1K0maPb2CKslBDELqzKr6SHf3jUmO6B4/Ati5p9qqWl9V81U1Pzc3N4meJUkzpM9ZfwHeB2yvqr9Z8NB5wOpueTWwcfLtSZJmXZ//j+qpwIuBS5Js6+77c2AdcHaSM4BrgOdNp8W78v+VkqTZMjSoquqzQO7l4ZMm244kSXfllSkkSU0zqCRJTTOoJElNM6gkSU0zqCRJTTOoJElNM6gkSU0zqCRJTTOoJElNM6gkSU0zqCRJTTOoJElNM6gkSU0zqCRJTTOoJElNM6gkSU0zqCRJTTOoJElNM6gkSU0zqCRJTTOoJElNM6gkSU0zqCRJTTOoJElNM6gkSU0bGlRJ3p9kZ5JLF9y3Isn5SXZ0tw+ZbpuSpFnVZ0T1AeCUu923FthUVUcDm7p1SZImbmhQVdWnge/c7e5TgQ3d8gbgtAn3JUkSMP5nVCur6vpu+QZg5b1tmGRNks1JNu/atWvM3UmSZtWiT6aoqgJqL4+vr6r5qpqfm5tb7O4kSTNm3KC6MckRAN3tzsm1JEnSncYNqvOA1d3yamDjZNqRJOmu+pye/kHgC8Bjk1yb5AxgHXBykh3AM7t1SZIm7sBhG1TVC+7loZMm3IskSffglSkkSU0zqCRJTTOoJElNM6gkSU0zqCRJTTOoJElNM6gkSU0zqCRJTTOoJElNM6gkSU0zqCRJTTOoJElNM6gkSU0zqCRJTTOoJElNM6gkSU0zqCRJTTOoJElNM6gkSU0zqCRJTTOoJElNM6gkSU0zqCRJTTOoJElNW1RQJTklyRVJrkyydlJNSZK029hBleQA4O+AXwOOAV6Q5JhJNSZJEixuRHU8cGVVXVVVPwE+BJw6mbYkSRpYTFA9HPjWgvVru/skSZqYVNV4hcnpwClV9bJu/cXAL1XVK++23RpgTbf6WOCK8dvdq8OBby9R3VLua9y65dDjuHX2OJm65dDjuHX2OJm6cffV1yOram7oVlU11hdwAvCJBetvAN4w7r+32C9g81LVLeW+9uce9+fvzR793lra11L3OOmvxUz9fQU4OsmjkhwMPB84bxH/niRJ93DguIVVdVuSVwKfAA4A3l9Vl02sM0mSWERQAVTVfwP/PaFeFmv9EtYt5b7GrVsOPY5bZ4+TqVsOPY5bZ4+TqRt3XxM19skUkiQtBS+hJElq2kwGVZJVSS7dR/v+/Jh1b07y2kn3MwlJXpVke5Iz93UvLUhyaJI/HLFmnx2To0pyyxLua6yfl6WynF635Wwmg2pfqqpf3tc9TMEfAidX1Qv3dSONOJTBc6JFWuzPSwb8PbfMLfsXsHtH87UkZ3bv6s9Jcv8epQf2rVmwjw8k+XpX98wkn0uyI8nxI/Tb+91okjd2+/ssgz+WHrkuyQf7jMSSPDnJV5PcN8khSS5L8os96v4BeDTwP0n+eIQeX9Lt7+Ik/9pj+9cleVW3/K4kF3TLJw4byXXfz8e6fV2a5Hd67O8tSV6zYP1tSV49/DsDYB3wc0m2JXlHzxqAA5L8U/fcfzLJ/Yb0eJd380lem+TNfXaU5E+65+LShd/nNCR5efdcbEvyzSQXjlA78uite16uSPIvwKXAI3rW/WeSLd3zv2Z4xT3qH53koiRP7rHtm7oeR/kZXdX9vhrlGFmX5BUL1nvPzCR5UZIvd6/bP2Zwfdd9Y1//Iddiv4BVQAFP7dbfD7x2kjXd9rcBj2cQ7lu6mjC4vuF/jtDvLT23exJwCXB/4EHAlcO+r8XUdbVvBd7J4GLDvf94G7gaOHyE7X8B+PruGmBFj5qnAB/ulj8DfBk4CPhL4PeH1P4W8E8L1h/c87ja2i3fB/gGcNgIx+SlYxzHtwFP6NbPBl40yn6A1wJvHuEYOQR4AHAZcNykj+E91B3UvXbPnea+uuflDuApI9at6G7vxyDghr7eu18DBm8kLwKO7VHzZGAbcF/ggcCOnj/b4xwjxwH/u2D9cuARPfb188B/AQd1638PvGSc130SX8t+RNX5VlV9rlv+N+BpU6j5ZlVdUlV3MPjB3lSDV/ASBgfQpD0dOLeqflhV36f/H1OPWwfwFuBkYB7465G6Hc2JDELn2wBV9Z0eNVuAJyV5EPBj4AsM+nw6g19+e3MJcHKStyd5elV9b9jOqupq4KYkxwHPAi6qqpt69LkY36yqbd3yFqZzXMHgWD+3qm6tqluAjzB4Hqft3cAFVfVfS7Cva6rqiyPWvCrJxcAXGYzCju5ZNwdsBF5YVRf32P6pwMaq+lFV/YBBIPQ10jFSVRcBD03ysCTHAt+tqm/traZzEoM3NF9Jsq1bf/QIfU7Uov6OqiF3P8e+zzn3o9b8eMHyHQvW72D/eR4PY/AO+yAG7/Zu3bft3Kmqfprkm8BLgc8DXwV+FXgMsH1I7deTPBH4deCtSTZV1Vt67Pa93f5+lsEIetoWHmO3M3hnvze3cdfp+/tOvKMJSfJS4JHAK4dsOikjHbtJngE8Ezihqn6Y5FP0fz6/B/wfgzcAl4+y3zGMeowAfBg4ncFxfFbP/QTYUFVvGK296dhfRlRHJTmhW/5d4LNTqllKnwZOS3K/JA8EnjvlOoB/BN4EnAm8faRuR3MB8NtJDgNIsqJn3WcYTG99ult+OYORzl7fZCR5GPDDqvo34B3AE3vu71zgFAZTNZ/oWQPwAwZTOtN2I4N3y4cl+RngOT3rPsPgGLl/kkOA32T4qHRsSZ7E4HV7UTcj0aIHMxht/DDJ4xhMNff1EwbP4UuS/G6P7T8HPLf7PPgB9H/dxnUWg0vcnc4gtPrYBJye5KEw+BlN8sgp9TfU/jISuAJ4RZL3M3hH854p1UxCr7+wrqqtSc4CLgZ2Mri24tTqkrwE+GlV/Xv3oennk5xYVRf0qR9FVV2W5G3A/ya5ncHc/kt7lH4GeCPwhaq6NcmP6PcL9vHAO5LcAfwU+IOeff6k++D/5qq6vU9NV3dTBifaXAr8T1W9rm/tKLpR5lsYfF53HfC1nnVbk3ygqwN4bzdFNC2vBFYAFyaBwYVOXzbF/Y3j48DLk2xn8LthpGnD7nh8DnB+kluq6l6n3KvqK0nOYzArcCODqemh09Hj6n7eHghcV1XX96y5PMlfAJ/M4KzJnwKvAK6ZVp97s+yvTJFkFfDRqhp6htq+1o0gtlbVkr0z6c4Cu6Wq3rlU+9xfdD+gW4Hfrqod+7of7T+SPKCqbsngbONPA2uqauu+7qtV+8vUX/O66acvMDirTo1LcgyDMyY3GVKagvXdSQpbgf8wpPZu2Y+oJEn7N0dUkqSmGVSSpKYZVJKkphlUkqSmGVSSpKYZVJKkpv0/NgNV2K2IPQoAAAAASUVORK5CYII=\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7ffa4d7db080>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fc = collections.Counter(sanitise(ca))\n",
+    "plot_frequency_histogram(fc, sort_key=fc.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "pua = depunctuate(ca)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('hanginggardens', -1451.9609829395629)"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ka, score = vigenere_frequency_break(ca)\n",
+    "ka, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "well that was a surprise and quite a relief as i said before no one really knows where the hanging\n",
+      "gardens of babylon were located and i dont think we would have had a chance of finding the next\n",
+      "chapter if that was where it was buried but it seems that tacitus had a better idea the babylonian\n",
+      "goddess of love and war was ishtar and the ishtar gate from babylon was one of the original seven\n",
+      "wonders of the world it was later replaced by the lighthouse of alexandria so i am not sure why\n",
+      "tacitus used both but maybe because he didnt know where the hanging gardens were either or maybe he\n",
+      "just wanted to confuse the uninitiated and to add an extra layer of secrecy via confusion abit like\n",
+      "he does by piling up ciphers in these later chapters anyway we are in luck the ishtar gate now lives\n",
+      "in the pergamon museum in berlin and i happen to have a pass to the full collection i am not sure\n",
+      "how they will feel about us dismantling it to try to find chapter seven but if we explain what is in\n",
+      "it i suspect the curators curiosity will overcome his natural protectiveness perhaps there we will\n",
+      "finally unlock the secret of the ixth legion that leaves the question of how we deal with midas and\n",
+      "maryam has a clever idea we should let the collector deal with them the russian mafia can be pretty\n",
+      "ruthless if they feel betrayed and she has suggested away we might make the thieves fallout it is a\n",
+      "cunning plan and i think i can help\n"
+     ]
+    }
+   ],
+   "source": [
+    "pa = vigenere_decipher(sanitise(ca), ka)\n",
+    "print(lcat(tpack(segment(pa))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1422"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('7a.plaintext', 'w').write(prettify(pa))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'oreomcufedvtmgjelehgvyhdnvwgkshmbcylmiexlrwffwxbkfszeafkzplrvsjuezttmcapoatsjuspemcqflfixmgseatgrtoieyymvjveuauglioxwftwgfebfqlfcepltdwzaaeoajfimmuarebtypctptbrgaasrtyfdloeargllxneepweorpppzyzaefqprlonyflmddtdrsrwmwpuoelepdierwaxgguytlpqgktzcglpqloafchzrsotmekmscaruseeaabhzwpflruzmedmcgymehxyqsrgaldaapydmauoqcadbjjismbtnliqgxyukejatcfsrsehmvsienxcggeteyunwmdhxzpjoteeyvxwtegcjsitcxluavputcpzpdnzchlsldvyqlpceauvjvtvvyetspehwtasppeykmegumfvazttzqesyoherxvxqfbrtzmpclkplsdeamklislhbgmszdgrmfmcpxlnzcedtrjlylokshswpmtqualnaaselmxbxqvwpdabjumxcuwkilmedlyewelohnpvjcbmctshhedrtgwprrygwiettlhjpteadpsxxkvecytrcdqptkupfhocumcsgpeacklmmnwgjjgqghmfmwletmhevgitqcwsjalsghvscyjkdierlggfvoofpeawytgbpupzsxmkpmqrkmqxmeehjjymaehcfamdsxlcsidaxcwooyebgpspyopywgifcggpspsoxqpgeytvckaucetqtjerevaqdmnomakkweyxdnlgspguqdesnzpvvxfhhsklrohxpgziyrgbckweempclzzttcowscuwgqoiyrgycmmppyyryxwehmgdldsaugvelibrkjlhdbhvvicahquvhdikcksgyebmcvmctbyguvsrvcvkydnpcfwihfgftqworkaperanakcjxpakecawlakfwsyftbcpsxztzywwhrtwacmgzfyrjftptldksizatyuqgpamywmadumnpfmeegmpeiwrkcusrzrmfnkspehgukszetggfhleuljvidthlqsepcxgvlywoamfnhcnzsgkmsramjdjyewpfdvllkgessdemmofiwinfkmeednprzylttauflmtlsnlwyrneqgvphlppkmtsxmtlhdlkdtsmttwkaaiwenmis_rufxqcauisfcbtycxxletlpahtagztlvromcgzszrymvlwomnmxqiydapfjawalgnwistxgjsjphlqqfseomfnlwsctbksaedvrrgszamlqflcubckmmwwjgcuxslbrvswdduqjuhtoeekujqnequyxedgctxiynvetvinulqumwximyqjglaadnfinsajvlmwrmcqsindtrnjmlrhgeqptcllvqszrnckvapvpjcjxcfbrvgrlspsefqdfgukdensmjukwtegqczinnkpkgyyebggcgyramgwelthrgjoyrdfdmefemrnwhoeatyessogyqgxnulgcfemaeyyzxrhbbrsxtotgrlxtexrnwcdevlpwqcmxqnkxdnvbyzhfieqolllixnusxzaajrkwtpwypnvaswgvlxxsmrvsedhktqjlowkacsxlookvsjptxscfmrohcqjvotwpvltlrbrgftzrzpvdqlngfjfiyekcgwszoxccmmoancfwglsheawxregivvpdtoyifiyixlufgpsxcjkvsihdeacptlgqfkprvltajpobbklverfatleletrckreirugvctgosx_agqmsprtyawefsklqzpdnbbrxxgpecjagyhxgcjzdcgqkscmskgyjkytxmiakycoyrlisdgcisstfbpefleomqkwepstmpsveeacpjqnhmpeaiwebmvsmpugfmsipnxrfsneymmqgbyimrcjlxuprkamngpytdwdoginvedtafcasyovreszeatfigsltlgggiphzqvkewsayqegzvhpjswckzfefwpegqqsrzizlgziznmmmxxstlykaxzawrgflehnqhogydugggetcxrruswtkygukqegqklrpiepqfhpivcedweoajqhwcaxgheeftebomedantrfydygmgsmpstmtzqqltyjzkynmmdjslowenmkjcbsuwxeafyvwveupyjgwdplrtzveexcklsloglghwuihyqztehmaueipitdewslsaqugghehgplecrlzgpmmnmsvltnexcqwjtaavvsgohxunwvccbcfsihwwgtnxqtgjukqggrzdwtzmksuwelgerggizekffltefzrfsregwgvviyhkfnlexfngqtxdabaxgkqdecjtseaxyjxcqralhylysbzuavpilm_hznpjazyvfgaxmowpglmzswjqeizetfpsmtmglvwllitsismxwvyazszcgjvshzegytjizffppxrznmykwiqutsevmwunaumspawyewypimfnzhgigphkvtdxjdvkloegpgldimkhdllharqaidakqpuysnemgwmfeacvdllexppmwqaafoascshdhzxfanlwvwpimfgeeeezsklwznncvzeytxykmhddvlagpeawtgbhseictaisteygwvwoaefwvcsxmkcgeugqhdepwmcefispmyglewnhvevhyevdgtecovrwkpfaydkgwolmpgvwztxppdrwsxjvlacdyznvwrtbmgwxpngcuzelhpzqfogmggewmzoljpgsxarfzfxdhbpwsxpsbcklitgkrtfvxsxlgaygnvfgwvchhrgvwdsmyefvwelqpslcthyjlijttbvgplomfkgeyhgcdjxheayvsittbypjeslzyxgizagrkzzzenyimiswxsojrpogrfupbyavulvccbmkmswsbqtkmcwlwcjmzomjjvetsmrgzywaxctsgpazrcolywicgayzewgvwkelnypjezbk_thigrsanutlvzsxhzjtfvpibpctwetbensraezftaplllpplestlrgowlihfelrotrcaurfaxdryveheytxmellpencostgehhyikcdejpamugjiwabgywvlqrjvawqegbkwefofrgmxpfhlufxdamrufizlfeznxeetfisfoamrpoweebnpakxlhrqaxwsmqvlmzrkrraigeglqkglexcgkssmeghsszabuvnlnhhwwvmxrtmqcieegqtswhtbkfssetkrgwvesvrgfxllhcgkxcsgnjlilfmfylffowqgfqfoxqgqxdoaanoxwhhughwsxbbigyhrxkjaivtkcgwyvnnnvzhndwmvdvpemqgailodftfrytbynltowxpkgxznhrhsvluwljgbthlsylmadzpvkilttkfsspmapdmithfykjeoitqvsltnvcgswtnmfparfhxdtjapdlwqsmnewavjqcturkrxergchsywohbksxxsgsulxzsmmqglddbawayeeprqwmssnktxiluhpcmsttzlgfvxuxchjhnwedgaiyawcvsrteaacwjlpbrpyzdimfggswryrglqlu'"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "scb = cat(c.lower() for c in cb if c != ' ')\n",
+    "scb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "27"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(set(scb))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:418: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n",
+      "  \"matplotlib is currently using a non-GUI backend, \"\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7ffa122f87f0>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fc = collections.Counter(sanitise(cb))\n",
+    "plot_frequency_histogram(fc, sort_key=fc.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('eeleeyceelalas', -5541.802272494437)"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kbv, score = vigenere_frequency_break(scb)\n",
+    "kbv, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'kntkiesbasvimofaaaditudsnkwogowixewhixemlzsbustdibooepfsvlanruhqaotimkwldwpuhqoeebcybhuetoeoaptvrbketuuotfrtupuohedtshrscueqfyhbralnrzsoapewwfueioswntbiyxypepxtewwhriynzhdawtehhmntexsadnlrnvuoatfylnakjadhisdidzonlisrskaaeedqanlwtiequileqogpoycnnmhdaucpvnhkpocgihcprcoatwwdfvsefarcvitzieeuithmyyonvwhfywlndbackmrwzdhfehmqtvhefctasgayaicnonhadotoetnmcocaiauwlsishmzxfkiaaattsievcroeiytnswreuicxvlsjvefhoadkyyhlrawwtfrivkympoeadyrwoeptysiavqihtwvitoqmouddatvrtffqrbvieyhmnhosepmshehhddeioodvrubirltnlvytdirrhuakgufosemiqcwhcwwuchimbmqdslswxlsitrulkqhitzhacsaaownxrfrxierodwesrbcsennaesettilpfliawfnotmkkekupgyzsnpgjpuhwyqbyoinawrkamujsvffiocdbfbwtapbdaxeepfclsrwhhcdxqyuyksimnhvcbxmkbeepwgpcqlqrxotbkemyngbmtocadyjnmiadrbwobotachilwtrskqwaxvphpgklnsckdycvphpaktflcgwprrkpukapfpfgparpqsmvkipggycutsnagalcjmzgqjvevkxnddhghtmdtegoigncqygycaiecazhpprksuaqsvqdigncnyionlunrnxeadbcznbowjgketexggfnfzxwvkikwdfqrjbegrkhggaxbyroapxngjvanrrrgabjlrflipbcupmymngpptrijwzyfznwgtcpwtwgusoadpxrphxhpvnssjppspcbghbugfbvnphskhihwpnqminwinwbalqiclbocacbptiengrqotxniunzsxadvqguxapvguhtaqafrkbpdaqhexytvrhaukwbfchkjvhcgoqnwbjsjgasebzxjhgvehslaibkbkuejukbemzjenvajpppuuluphhjhywnjtqvvxdhelgorotbtahlhgspoorpszapieajbeotsbtfcpuqobrxpaattaeilxwdiwcbrhrgobcovoonuothsdmcmfmenzwrdfwlaagvsehptihofehaqybotkihlhshcibsowtzrtpcooablybhrqxeiiilwygkqthhxttossdjqrqdikagiqffntqcuttzcertennkebrecqhssismibyyfcawwflbecspjdhilnieooecdirvfiandicmlicaldmoonjeirwevejkftrbxttcnasesmbmsbcwizacsbjcgsiacsavecnzpscunaxieycnrpmosaapdtefknrsfliauaitlsddeptgaohkcaoctcuagkbabwaawvtghqbzotikpiphtiemrvsysarnnsmrmmqvgtsjrdwvduitqwhhaetpsotoapjzgsilsanjrpslgdhtmoittoashztyfhdsgcaotaodkdofeptuabigowcyfrdpsrthparqrobponvrtzmanvfrbenageesooomckiidwjedscasweistgacktrlstdyqbenetnsbcesmcrgrhedfcwyetagybgenrnrwfeoqbshrtnbcrhaaeirkgntenweryigdsfwcfiorppupwtfaghfvlflxxgxmgxayywcaftcrjodkcmzoyoqgcnjzybtixwgaakuglxslcyxoovdxltfaewimzsarqpieskemwyefmpfiltaxwmxikoirscbbsxpvtnuojgwiifgqyqinrfhzslnzabnoluizsfmcecvtdbwbrwoamrntsoeipbxconrhcvgxppvmkgayqwufevzddlyoseivbtflpmcmfonbgvhvzxzviibtturhuzamzisnvbhgfjmwovylqcvcavatnguhwbguvqgsccmzlgpqalfbdrgrytdlewwffdseytcwetfbaxdiafyjpgfndgcivoirqpiizfqtpuyvgaliisjhlwsaciglaxojwmeibuksrgsluygldxhnivrgctyzlhlwchvdswgdufziepiwjaergpztwhlawmjccjcdceltczhvvliolioklinmtyfsfvywrksvoptqcsreaxyusxhescijtsrcfjkfgonvsspbkgojwtloanvcebcgbulienvnuongesckvxypgbchazdjcftmdixwmcgsbayytheituytyspwhwyayaxvjwrrghiwzcprwvnrbiytidwegtivhsfscevttupaipbchxuhhxthiaitlrucxovrgyvadvtcuvhevufepfnvciumuemjthedisjjwwkolpwneeulxibpxdcxgehsrpstfftghdevpohzxigjbhhwagqiezpgmrsuocebgeibtwyxbhhtxepusmpwbqyoyhhshhtbpjhytslxmugmaatvomjsvcnrvhauitumkdzsvaaolapspizdotirtieoiauiursdatferyhtimacajgfhlalliygdeoemngtascdrgtdutvsgbaydrnyilbpyskoskailitsvixeplnshtfxjwysyondsnixiiutlcgruhahwlvsdkcbgveeivdhfreotpruzntzwxlyqtlhbrktepvgnvdrthxagiuccrbiurywhggdszhiugdrstlfpahyiduljefitqvolhdibmeauwgrdrtdtwuxqepibnpraoavuzeevpggkhvvtjukkeolxhornldcnhslxnakutryrximkoshbftsiylhsehivdmyjdaphinixuspxrtaclpvnemhulirgiuvtscxugaannpravqgpjgcnhacubhrootjxfpuveijlyisavzajhrpehbpplhnjllaehttncdshkfbaardtzywjnbcvznnvthmupmianjlaccdsbcawdukiyztjeauqcyesczculvaqzfrpsmgexgleuonncbtlhfhquxsaunquevndavcxtebbehbkcknldwtejjlpgtnfnmpxlsumraivtinnpiveohmzchgvyczshmmcdhovczqrclchpsskittrimriteomphsdvzgbhsttsnclrautncuxalpycztyuejfaiafubuabbqumcuquofmcftzqywjdxlhpqcwsozzxevywrfgfperviyclyknvjrodjfuirsveeumcpehqbbpurntjujapkyvlgvxonpndhrhwuhfvbihtouaiwfxlrziatbgbholoylzbiihnugyakkrmrhlindychsppkblpruhfzpywlfjsmhmceewrymyvsnggxtroydhusqfxghxmsooqatvukimvlsdjwspuagnnmlmhsvgpmehwflybsithhcurtwvydyhcwmzcpeucuyrhrieiwylfhrznlnzsiubcvostwncaqau'"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "vigenere_decipher(sanitise(cb), kbv)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:418: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n",
+      "  \"matplotlib is currently using a non-GUI backend, \"\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7ffa126de3c8>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fc = collections.Counter(sanitise(cb))\n",
+    "plot_frequency_histogram(fc)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:418: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n",
+      "  \"matplotlib is currently using a non-GUI backend, \"\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7ffa15721390>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fp = collections.Counter(vigenere_decipher(sanitise(cb), kbv))\n",
+    "plot_frequency_histogram(fp)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:418: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n",
+      "  \"matplotlib is currently using a non-GUI backend, \"\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7ffa157210b8>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fp = collections.Counter(every_nth(scb, 6)[4])\n",
+    "plot_frequency_histogram(fp)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:418: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n",
+      "  \"matplotlib is currently using a non-GUI backend, \"\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7ffa1272c0b8>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fp = collections.Counter(every_nth(scb, 32)[0])\n",
+    "plot_frequency_histogram(fp, sort_key=fp.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'etoainhsrdlumwycfgpbvkxjqz'"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ltrs = [p[0] for p in english_counts.most_common()]\n",
+    "cat(ltrs)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'eglsmtapwcryfvxhkdizqnjoub'"
+      ]
+     },
+     "execution_count": 19,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ctls =  [p[0] for p in collections.Counter(sanitise(cb)).most_common()]\n",
+    "cat(ctls)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'a': 'h',\n",
+       " 'b': 'z',\n",
+       " 'c': 'd',\n",
+       " 'd': 'g',\n",
+       " 'e': 'e',\n",
+       " 'f': 'm',\n",
+       " 'g': 't',\n",
+       " 'h': 'c',\n",
+       " 'i': 'p',\n",
+       " 'j': 'x',\n",
+       " 'k': 'f',\n",
+       " 'l': 'o',\n",
+       " 'm': 'i',\n",
+       " 'n': 'k',\n",
+       " 'o': 'j',\n",
+       " 'p': 's',\n",
+       " 'q': 'v',\n",
+       " 'r': 'l',\n",
+       " 's': 'a',\n",
+       " 't': 'n',\n",
+       " 'u': 'q',\n",
+       " 'v': 'w',\n",
+       " 'w': 'r',\n",
+       " 'x': 'y',\n",
+       " 'y': 'u',\n",
+       " 'z': 'b'}"
+      ]
+     },
+     "execution_count": 20,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "trans = {pr[1]: pr[0] for pr in zip(ltrs, ctls)}\n",
+    "trans"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'jlejidqmegwnitxeoectwucgkwrtfacizduoipeyolrmmryzfmabehmfbsolwaxqebnnidhsjhnaxqaseidvmompyitaehntlnjpeuuiwxweqhqtopjyrmnrtmezmvomdesongrbhhejhxmpiiqhleznusdnsnzlthhalnumgojehltooykeesrejlsssbubhemvslojkumoiggnglalrirsqjeoesgpelrhyttqunosvtfnbdtosvojhmdcblajniefiadhlqaeehhzcbrsmolqbiegidtuiecyuvalthoghhsugihqjvdhgzxxpaiznkopvtyuqfexhndmalaeciwapekydtteneuqkrigcybsxjneeuwyrnetdxapndyoqhwsqndsbsgkbdcoaogwuvosdehqwxwnwwuenasecrnhasseufietqimwhbnnbveaujcelywyvmzlnbisdofsoagehifopaocztiabgtlimidsyokbdegnlxouojfacarsinvqhokhhaeoiyzyvwrsghzxqiydqrfpoiegouereojckswxdzidnacceglntrsllutrpennocxsnehgsayyfwedunldgvsnfqsmcjdqidatsehdfoiikrtxxtvtcimiroenicewtpnvdraxhoatcwaduxfgpelottmwjjmsehruntzsqsbayifsivlfivyieecxxuihecdmhigayodapghydrjjueztsasujsurtpmdttsasajyvsteunwdfhqdenvnxelewhvgikjihffreuygkotastqvgeakbswwymccafoljcystbpultzdfreeisdobbnndjradqrtvjpultudiissuuluyrecitgogahqtweopzlfxocgzcwwpdhcvqwcgpfdfatuezidwidnzutqwalwdwfugksdmrpcmtmnvrjlfhselhkhfdxyshfedhrohfmraumnzdsaybnburrclnrhditbmulxmnsnogfapbhnuqvtshiurihgqiksmieetiseprlfdqalblimkfasectqfabenttmcoeqoxwpgncovaesdytwourjhimkcdkbatfialhixgxuersmgwoofteaageiijmprpkmfieegkslbuonnhqmoinoakorulkevtwscossfinayinocgofgnainnrfhhprekipa_lqmyvdhqpamdznudyyoenoshcnhtbnowljidtbabluiworjikiyvpughsmxhrhotkrpanytxaxscovvmaejimkoradnzfahegwlltabhiovmodqzdfiirrxtdqyaozlwarggqvxqcnjeefqxvkevquyegtdnypukwenwpkqovqirypiuvxtohhgkmpkahxwoirlidvapkgnlkxiolctevsndoowvablkdfwhswsxdxydmzlwtloasaemvgmtqfgekaixqfrnetvdbpkkfsftuuezttdtulhitreoncltxjulgmgiemeilkrcjehnueaajtuvtykqotdmeiheuubylczzlaynjntloyneylkrdgewosrvdiyvkfygkwzubcmpevjooopykqaybhhxlfrnsruskwhartwoyyailwaegcfnvxojrfhdayojjfwaxsnyadmiljcdvxwjnrswonolzltmnblbswgvoktmxmpuefdtrabjyddiijhkdmrtoacehryletpwwsgnjupmpupyoqmtsaydxfwapcgehdsnotvmfslwonhxsjzzfowelmhnoeoenldfleplqtwdntjay_htviaslnuhremafovbsgkzzlyytsedxhtucytdxbgdtvfadiaftuxfunyiphfudjulopagtdpaanmzsemoejivfresanisaweehdsxvkcisehpreziwaisqtmiapskylmakeuiivtzupildxoyqslfhiktsungrgjtpkwegnhmdhaujwleabehnmptaonotttpscbvwferahuvetbwcsxardfbmemrsetvvalbpbotbpbkiiiyyanoufhybhrltmoeckvcjtugqtttendyllqarnfutqfvetvfolspesvmcspwdegrejhxvcrdhytceemnezjieghknlmugutitaisaninbvvonuxbfukiigxaojrekifxdzaqryehmuwrweqsuxtrgsolnbweeydfoaojtotcrqpcuvbnecihqepspngeraoahvqttcectsoedlobtsiikiawonkeydvrxnhhwwatjcyqkrwddzdmapcrrtnkyvntxqfvttlbgrnbifaqreotelttpbefmmonemblmaletrtwwpucfmkoeymktvnyghzhytfvgedxnaehyuxydvlhocuouazbqhwspoi_cbksxhbuwmthyijrstoibarxvepbenmsainitowroopnapaiyrwuhbabdtxwacbetunxpbmmssylbkiufrpvqnaewirqkhqiashrueruspimkbctptscfwngyxgwfojetstogpifcgoochlvhpghfvsquakeitrimehdwgooeyssirvhhmjhadacgcbymhkorwrspimteeeebaforbkkdwbeunyuficggwohtsehrntzcaepdnhpaneutrwrjhemrwdayifdteqtvcgesridempasiutoerkcwewcuewgtnedjwlrfsmhugftrjoistwrbnyssglrayxwohdgubkwrlnzitrysktdqbeocsbvmjtitteribjoxstayhlmbmygczsraysazdfopntflnmwyayothutkwmtrwdccltwrgaiuemwreovsaodncuxopxnnzwtsojimfteuctdgxycehuwapnnzusxeaobuytpbhtlfbbbekupiparyajxlsjtlmqszuhwqowddzifiarazvnfidrordxibjixxwenailtburhydnatshbldjourpdthubertwrfeokusxebzf_ncptlahkqnowbaycbxnmwspzsdnrenzekalhebmnhsooossoeanoltjropcmeoljnldhqlmhygluweceunyieoosekdjanteccupfdgexshiqtxprhzturwovlxwhrvetzfremjmltiysmcoqmyghilqmpbomebkyeenmpamjhilsjreezkshfyoclvhyraivwoiblfllhptetovftoeydtfaaietcaabhzqwkokccrrwiylnivdpeetvnarcnzfmaaenfltrweawltmyoocdtfydatkxopomimuommjrvtmvmjyvtvygjhhkjyrccqtcrayzzptuclyfxhpwnfdtruwkkkwbckgriwgwseivthpojgmnmlunzukonjrysftybkclcawoqroxtzncoauoihgbswfponnfmaasihsgipncmufxejpnvwaonkwdtarnkimshlmcygnxhsgorvaikerhwxvdnqlflyeltdcaurjczfayyataqoybaiivtoggzhrhueeslvriaakfnypoqcsdiannbotmwyqydcxckregthpuhrdwalnehhdrxoszlsubgpimttarlultovoq'"
+      ]
+     },
+     "execution_count": 21,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "tt = ''.maketrans(trans)\n",
+    "scb.translate(tt)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1.0911221874256245"
+      ]
+     },
+     "execution_count": 22,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "index_of_coincidence(scb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1.7308339625731206"
+      ]
+     },
+     "execution_count": 23,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "index_of_coincidence(pa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "1 1.0911221874256245\n",
+      "2 1.0999811518557716\n",
+      "3 1.1024736687577428\n",
+      "4 1.1108493258214134\n",
+      "5 1.1205942838699368\n",
+      "6 1.1276162903349627\n",
+      "7 1.1452272001021975\n",
+      "8 1.132400627567293\n",
+      "9 1.1333184666730263\n",
+      "10 1.1679170525798583\n",
+      "11 1.14614572332707\n",
+      "12 1.1597512509602577\n",
+      "13 1.1571726175932888\n",
+      "14 1.197981087983724\n",
+      "15 1.1792859340799244\n",
+      "16 1.1865717812697065\n",
+      "17 1.1941252456748892\n",
+      "18 1.1906805858544067\n",
+      "19 1.1957146314520906\n",
+      "20 1.2111608276986638\n",
+      "21 1.218181311427732\n",
+      "22 1.1971143041278922\n",
+      "23 1.223217066658174\n",
+      "24 1.2281223302252005\n",
+      "25 1.2438359793130673\n",
+      "26 1.2280766730517558\n",
+      "27 1.232036081608544\n",
+      "28 1.273139026261631\n",
+      "29 1.2414832155367646\n"
+     ]
+    }
+   ],
+   "source": [
+    "for i in range(1, 30):\n",
+    "    print(i, sum(index_of_coincidence(section) for section in every_nth(scb, i)) / i)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(1, 1.0911221874256245),\n",
+       " (2, 1.0999811518557716),\n",
+       " (3, 1.1024736687577428),\n",
+       " (4, 1.1108493258214134),\n",
+       " (5, 1.1205942838699368),\n",
+       " (6, 1.1276162903349627),\n",
+       " (8, 1.132400627567293),\n",
+       " (9, 1.1333184666730263),\n",
+       " (7, 1.1452272001021975),\n",
+       " (11, 1.14614572332707),\n",
+       " (13, 1.1571726175932888),\n",
+       " (12, 1.1597512509602577),\n",
+       " (10, 1.1679170525798583),\n",
+       " (15, 1.1792859340799244),\n",
+       " (16, 1.1865717812697065),\n",
+       " (18, 1.1906805858544067),\n",
+       " (17, 1.1941252456748892),\n",
+       " (19, 1.1957146314520906),\n",
+       " (22, 1.1971143041278922),\n",
+       " (14, 1.197981087983724),\n",
+       " (20, 1.2111608276986638),\n",
+       " (21, 1.218181311427732),\n",
+       " (23, 1.223217066658174),\n",
+       " (26, 1.2280766730517558),\n",
+       " (24, 1.2281223302252005),\n",
+       " (27, 1.232036081608544),\n",
+       " (29, 1.2414832155367646),\n",
+       " (25, 1.2438359793130673),\n",
+       " (28, 1.273139026261631)]"
+      ]
+     },
+     "execution_count": 25,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ics = [(i, sum(index_of_coincidence(section) for section in every_nth(scb, i)) / i)\n",
+    "       for i in range(1, 30)]\n",
+    "sorted(ics, key=lambda p: p[1])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'etoainhsrdlumwycfgpbvkxjqz'"
+      ]
+     },
+     "execution_count": 26,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ltrs = [p[0] for p in english_counts.most_common()]\n",
+    "cat(ltrs)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['lasgeipmvtrxkdhycwfnzoqujb',\n",
+       " 'gsmptlreacfhwvyidkxzqoujnb_',\n",
+       " 'egwstcvmflaqkrhzpdjnuxbyio',\n",
+       " 'etgmlywsapxfrvuqzncodjihkb_',\n",
+       " 'lexpgscwyrmkfatndvzqhjoiub',\n",
+       " 'egtpmwsalyfcrhixjbkvzonduq_']"
+      ]
+     },
+     "execution_count": 27,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ctlss = [cat(p[0] for p in collections.Counter(section).most_common()) for section in every_nth(scb, 6) ]\n",
+    "ctlss"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[{'a': 't',\n",
+       "  'b': 'z',\n",
+       "  'c': 'f',\n",
+       "  'd': 'w',\n",
+       "  'e': 'i',\n",
+       "  'f': 'p',\n",
+       "  'g': 'a',\n",
+       "  'h': 'y',\n",
+       "  'i': 'n',\n",
+       "  'j': 'q',\n",
+       "  'k': 'm',\n",
+       "  'l': 'e',\n",
+       "  'm': 's',\n",
+       "  'n': 'b',\n",
+       "  'o': 'k',\n",
+       "  'p': 'h',\n",
+       "  'q': 'x',\n",
+       "  'r': 'l',\n",
+       "  's': 'o',\n",
+       "  't': 'd',\n",
+       "  'u': 'j',\n",
+       "  'v': 'r',\n",
+       "  'w': 'g',\n",
+       "  'x': 'u',\n",
+       "  'y': 'c',\n",
+       "  'z': 'v'},\n",
+       " {'a': 'r',\n",
+       "  'b': 'z',\n",
+       "  'c': 'd',\n",
+       "  'd': 'f',\n",
+       "  'e': 's',\n",
+       "  'f': 'l',\n",
+       "  'g': 'e',\n",
+       "  'h': 'u',\n",
+       "  'i': 'c',\n",
+       "  'j': 'j',\n",
+       "  'k': 'g',\n",
+       "  'l': 'n',\n",
+       "  'm': 'o',\n",
+       "  'n': 'q',\n",
+       "  'o': 'k',\n",
+       "  'p': 'a',\n",
+       "  'q': 'v',\n",
+       "  'r': 'h',\n",
+       "  's': 't',\n",
+       "  't': 'i',\n",
+       "  'u': 'x',\n",
+       "  'v': 'w',\n",
+       "  'w': 'm',\n",
+       "  'x': 'p',\n",
+       "  'y': 'y',\n",
+       "  'z': 'b'},\n",
+       " {'a': 'l',\n",
+       "  'b': 'x',\n",
+       "  'c': 'n',\n",
+       "  'd': 'g',\n",
+       "  'e': 'e',\n",
+       "  'f': 'r',\n",
+       "  'g': 't',\n",
+       "  'h': 'y',\n",
+       "  'i': 'q',\n",
+       "  'j': 'p',\n",
+       "  'k': 'm',\n",
+       "  'l': 'd',\n",
+       "  'm': 's',\n",
+       "  'n': 'b',\n",
+       "  'o': 'z',\n",
+       "  'p': 'f',\n",
+       "  'q': 'u',\n",
+       "  'r': 'w',\n",
+       "  's': 'a',\n",
+       "  't': 'i',\n",
+       "  'u': 'v',\n",
+       "  'v': 'h',\n",
+       "  'w': 'o',\n",
+       "  'x': 'k',\n",
+       "  'y': 'j',\n",
+       "  'z': 'c'},\n",
+       " {'a': 'r',\n",
+       "  'b': 'z',\n",
+       "  'c': 'p',\n",
+       "  'd': 'v',\n",
+       "  'e': 'e',\n",
+       "  'f': 'u',\n",
+       "  'g': 'o',\n",
+       "  'h': 'j',\n",
+       "  'i': 'x',\n",
+       "  'j': 'k',\n",
+       "  'k': 'q',\n",
+       "  'l': 'i',\n",
+       "  'm': 'a',\n",
+       "  'n': 'g',\n",
+       "  'o': 'b',\n",
+       "  'p': 'd',\n",
+       "  'q': 'c',\n",
+       "  'r': 'm',\n",
+       "  's': 's',\n",
+       "  't': 't',\n",
+       "  'u': 'y',\n",
+       "  'v': 'w',\n",
+       "  'w': 'h',\n",
+       "  'x': 'l',\n",
+       "  'y': 'n',\n",
+       "  'z': 'f'},\n",
+       " {'a': 'w',\n",
+       "  'b': 'z',\n",
+       "  'c': 'h',\n",
+       "  'd': 'f',\n",
+       "  'e': 't',\n",
+       "  'f': 'm',\n",
+       "  'g': 'i',\n",
+       "  'h': 'v',\n",
+       "  'i': 'j',\n",
+       "  'j': 'k',\n",
+       "  'k': 'u',\n",
+       "  'l': 'e',\n",
+       "  'm': 'l',\n",
+       "  'n': 'c',\n",
+       "  'o': 'x',\n",
+       "  'p': 'a',\n",
+       "  'q': 'b',\n",
+       "  'r': 'd',\n",
+       "  's': 'n',\n",
+       "  't': 'y',\n",
+       "  'u': 'q',\n",
+       "  'v': 'g',\n",
+       "  'w': 's',\n",
+       "  'x': 'o',\n",
+       "  'y': 'r',\n",
+       "  'z': 'p'},\n",
+       " {'a': 's',\n",
+       "  'b': 'g',\n",
+       "  'c': 'u',\n",
+       "  'd': 'j',\n",
+       "  'e': 'e',\n",
+       "  'f': 'l',\n",
+       "  'g': 't',\n",
+       "  'h': 'w',\n",
+       "  'i': 'y',\n",
+       "  'j': 'f',\n",
+       "  'k': 'p',\n",
+       "  'l': 'r',\n",
+       "  'm': 'i',\n",
+       "  'n': 'x',\n",
+       "  'o': 'k',\n",
+       "  'p': 'a',\n",
+       "  'q': 'z',\n",
+       "  'r': 'm',\n",
+       "  's': 'h',\n",
+       "  't': 'o',\n",
+       "  'u': 'q',\n",
+       "  'v': 'b',\n",
+       "  'w': 'n',\n",
+       "  'x': 'c',\n",
+       "  'y': 'd',\n",
+       "  'z': 'v'}]"
+      ]
+     },
+     "execution_count": 28,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "trans = [{pr[1]: pr[0] for pr in zip(ltrs, ctls)} for ctls in ctlss]\n",
+    "trans"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['tzfwipaynqmesbkhxlodjrgucv',\n",
+       " 'rzdfsleucjgnoqkavhtixwmpyb',\n",
+       " 'lxngertyqpmdsbzfuwaivhokjc',\n",
+       " 'rzpveuojxkqiagbdcmstywhlnf',\n",
+       " 'wzhftmivjkuelcxabdnyqgsorp',\n",
+       " 'sgujeltwyfprixkazmhoqbncdv']"
+      ]
+     },
+     "execution_count": 29,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[cat(t[l] for l in sorted(t)) for t in trans]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['gnytlcwpeuorkisfjvmaxzdqhb',\n",
+       " 'pzicgdkrtjofwlmxnaeshqvuyb',\n",
+       " 'snzlepdvtyxakcwjifmgqurbho',\n",
+       " 'moqpeznwlhjxrygckastfdviub',\n",
+       " 'pqnrldvcgijmfsxzuywekhaotb',\n",
+       " 'pvxyejbsmdofrwtkulagczhniq']"
+      ]
+     },
+     "execution_count": 30,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[cat([k for k in t if t[k] == l][0] for l in sorted(t.values()))\n",
+    " for t in trans]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['k he blu j lev go sep ee eye hnvjbwoouhyoxprrsc elem gl rhogmlaftspgcdemrtpy tv disp wak risk',\n",
+       " 'qoaeahzpnrxoiateryt liz xtdcohkgejrvoeykpouy nale zmz el near df of wsiklkmysovrdezijd',\n",
+       " 'hohixmisttwtrlwnzewm and lceiaoexmhaffrvtsr came kbnmrsfgtfmohoasajke it awc ems sue tyro',\n",
+       " 'eauouovdtiazekluhwvh a by iigs shslxaetstzyfsapnwyp i if spidssylrzohtrejtrfn fit',\n",
+       " 'xzchswzpkjhszigeyxek nqpijlthlohaevirtqec cfeteyecxbhljypcdkkd seng cgieohfociporjrhdq of a cd',\n",
+       " 'fxvdyinrwwjceafslyg fri hwr edt fevndradaecgseiqslhr pod buen dkuemobuvrzdovofpeph',\n",
+       " 'navtssgdxnryztanvwew am if akicvfsgtdfeydbuhy to dlo xxl i cst teil c zpuwsawrxkqiudvhuyeo eve dime',\n",
+       " 'ixwbahkhgsdisvwifw tinh hwn inn site wqaiewjhtklubidjtdu wvftuqhlybhqsdaoaetd mil ibm',\n",
+       " 'tkktxeyamignetlwiwt xyz fmakwroeywnucjmvjeln tomb kkrdtsgyiozajacsoim as cd psv kate',\n",
+       " 'yjpnlsiunuwiwtkihh nfl lhnkkjezthtfnxacmtxm uae fsa hkpudiecihpusjdetbo qswegsxfsgxitgmhtduf',\n",
+       " 'biihhevcfeoqcdgbulyj npehzjoaabqndtzdmhte san ipvdinbshfxoobknyw or us of drdlykhtwsegifhtxtw',\n",
+       " 'trnzwqkryfxjgbndljbq rug xuumttntgsdhahozytyg hl wnwudwqfpmnnuromoxmz mush sw rcs md plasm snrs rtg',\n",
+       " 'rhn dpi xp a hub if rnguwtssfotfmdljr taoefmsjvtijybthrsns it fvacapoeeiihsqhdpfx am pm',\n",
+       " 'slbqnaiutyuhvsioilyn eye frcgtvrxtedhcawdnsk to rgvubbaouiohlakjqyeh al wwdiutitavtiskrxsybl mate',\n",
+       " 'wqfmpdeiirqleoiinxem jmc exe hdvr ha may huoiivjeggtnidioqwsn meg lyo_wymcxdlyjhpdxtru up de',\n",
+       " 'yrhrytwtvidwdksdtfnv lys wen koba oznygralqroretbmqsyc a jaka we vuunekorgenodizuhtsg wdm at',\n",
+       " 'crlrxldpqgfgsasnqeny oh ezwwnnwfvckqyizetpjj ugtzjykeftfikxrxrsiw jxjnuylnucsnbfanlrfx pcbs',\n",
+       " 'wfrnshdifvaxcjdhbklr lute bad ddigzobwghprrfwaffj kpmglwtmehhteubjpevq feb tsk qpgieobuvcbguamejntg',\n",
+       " 'a enorm to thtrduwokkchgufii lead xguzewocsasxtcvtlcqe enutitsjnpcluxzdhuiz time pie omb',\n",
+       " 'mnvtbeaochiuvbqojbwx npwpcecxrenqlcqopcrw fl got an cab wwhgehiocoowwnewumtb fekoqwuopdbxprtpdyco',\n",
+       " 'dradkydukgkdmfweoehx mild bwfabwvdgilqlqntpfeo sp kudnalktqnustetyewnu heojbragtxdnlqnjcexr oahu',\n",
+       " 'dpqghnugewuhidoblmaw we otjfbzgmnhedltideeed hnqdenhvogudezso_teu anal i jr sept mib vhf',\n",
+       " 'bzzmuptdtuqrtnvcadpf fuavmshiogtnkpcikajs my nbr me cavi unt at mgh sri tks vmhtaoisdnbislpafxqy a a',\n",
+       " 'etc oezirtsdqtpoaxaxuhrs cecoscigccsmhfepvddp to bo add fovxtnqhefotlnrndkww envir iuj toni',\n",
+       " 'iitacfjpzrgehnscveop by aps sum bremnhstcbhlbqfetv ccg lisp ksyrcgllpsghtueeyquj xtc fvo it i in',\n",
+       " 'ldmjtotudaxmcttxgd may iauuvanwnefniklkbwgd lliw is rttgkoevwxdhrnfdaots laois tpzxninkvmybaljqtdb',\n",
+       " 'sebo mkhgoxoltspyhhgejajk in wad my vrs elh pet dbirauoyjwcvcttwsrve jan igeshetlcqtauejiaesn me',\n",
+       " 'vaasa ciowdtceuduhkotrh wntkukycnrdnzhlocyhs tdqkcytqxmcitlbghyvs gay see eemitnbeqmleieupmpt we in',\n",
+       " 'awhxrwmlbitcpqtcycw rxrotmvgehfdterodqpn cds eujirhzbvrganns_vvb apr pdrltroikmfoeivtok ben be tma',\n",
+       " 'ooi air rm dijo ocaa on rylfnvfepwnwvstnyf nbruaauhcgldmmqcqoos has qbr van atm jesdhcsucvyeqoawmwiv',\n",
+       " 'of ww mix ea at if ysgyveryrwcwywrmcaq ct belt gore wu rf ditch ash bst lzrnuougjpcprbisbgaq amti',\n",
+       " 'see ph mn of cxfwcerouymavjwwdri air oti gy tex hot catt dam hh xsi low hhuompiejeujfehmsptl ntf',\n",
+       " 'artes ogvbiwyntbweiehkrhoq altygqinknsdibgbilaa who so frnlpfdvqhhdozothoa be ny',\n",
+       " 'peeuffblkesoiegocbef heal wmpbrlfwzaosoaoznqey dem my lrp a letty tg glam hpvwlehhfhsyeugninud',\n",
+       " 'nrfiynkrnjitzbaadbll meen vtffplvetyhsjodzjdke on c not n blodpvbcecdnoqsscokp makah',\n",
+       " 'ryagcrhyebfdxauiomaz bom on he nfjsfxiqjheyhshtfrn tpntnthrcmhkeyoxhtty cest rm me ex cape',\n",
+       " 'pgm_ijjtltlgqoewcso wvjiuganzfpyniixechl ref mota die ah nes yrlezheyyleidkdhnrqm pr',\n",
+       " 'kvddrsyerouoeieaiqnb no as yjrymdgekatovokygrx or nrnumkbtmueigmmeuxl les la lynvuojtowymyvnrepxu',\n",
+       " 'set my olzrlmhkoetgbalqory huron oouweivhmmdsneeoezme de oua gas leau asp szxhgexyuohgiuhiabun seo',\n",
+       " 'boom ytzpptaeypleowthrhtu or eunoucfttgkrnnram del rbszaluuxcxeulfktrbb on yuvovnopxzjtcuwluftc',\n",
+       " 'htuuamjwcxbwcjcjgohv gaiouowyekguyllyizrx eizhoamekfcwluaweqgn pozo yn an eitf cdg pnni tu lot faw a',\n",
+       " 'woqtvlcgpexydvhseobw non ndqsuasllylfoqrfvenx tsgt n twp cho jhmmoelenjndgkyzuhup a on',\n",
+       " 'qepcslixedvfgtmlnteh huh lho qmtoyexydhioiifetpwk you yjygsewelxrsgdhs do irlpsfeaxmadvfqamta to mr',\n",
+       " 'man uiq']"
+      ]
+     },
+     "execution_count": 31,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "sections = []\n",
+    "for tr, section in zip(trans, every_nth(scb, 6)):\n",
+    "    tt = ''.maketrans(tr)\n",
+    "    sections += [section.translate(tt)]\n",
+    "tpack(segment(combine_every_nth(sections)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'oreomcufedvtmgjelehgvyhdnvwgkshmbcylmiexlrwffwxbkfszeafkzplrvsjuezttmcapoatsjuspemcqflfixmgseatgrtoieyymvjveuauglioxwftwgfebfqlfcepltdwzaaeoajfimmuarebtypctptbrgaasrtyfdloeargllxneepweorpppzyzaefqprlonyflmddtdrsrwmwpuoelepdierwaxgguytlpqgktzcglpqloafchzrsotmekmscaruseeaabhzwpflruzmedmcgymehxyqsrgaldaapydmauoqcadbjjismbtnliqgxyukejatcfsrsehmvsienxcggeteyunwmdhxzpjoteeyvxwtegcjsitcxluavputcpzpdnzchlsldvyqlpceauvjvtvvyetspehwtasppeykmegumfvazttzqesyoherxvxqfbrtzmpclkplsdeamklislhbgmszdgrmfmcpxlnzcedtrjlylokshswpmtqualnaaselmxbxqvwpdabjumxcuwkilmedlyewelohnpvjcbmctshhedrtgwprrygwiettlhjpteadpsxxkvecytrcdqptkupfhocumcsgpeacklmmnwgjjgqghmfmwletmhevgitqcwsjalsghvscyjkdierlggfvoofpeawytgbpupzsxmkpmqrkmqxmeehjjymaehcfamdsxlcsidaxcwooyebgpspyopywgifcggpspsoxqpgeytvckaucetqtjerevaqdmnomakkweyxdnlgspguqdesnzpvvxfhhsklrohxpgziyrgbckweempclzzttcowscuwgqoiyrgycmmppyyryxwehmgdldsaugvelibrkjlhdbhvvicahquvhdikcksgyebmcvmctbyguvsrvcvkydnpcfwihfgftqworkaperanakcjxpakecawlakfwsyftbcpsxztzywwhrtwacmgzfyrjftptldksizatyuqgpamywmadumnpfmeegmpeiwrkcusrzrmfnkspehgukszetggfhleuljvidthlqsepcxgvlywoamfnhcnzsgkmsramjdjyewpfdvllkgessdemmofiwinfkmeednprzylttauflmtlsnlwyrneqgvphlppkmtsxmtlhdlkdtsmttwkaaiwenmis_rufxqcauisfcbtycxxletlpahtagztlvromcgzszrymvlwomnmxqiydapfjawalgnwistxgjsjphlqqfseomfnlwsctbksaedvrrgszamlqflcubckmmwwjgcuxslbrvswdduqjuhtoeekujqnequyxedgctxiynvetvinulqumwximyqjglaadnfinsajvlmwrmcqsindtrnjmlrhgeqptcllvqszrnckvapvpjcjxcfbrvgrlspsefqdfgukdensmjukwtegqczinnkpkgyyebggcgyramgwelthrgjoyrdfdmefemrnwhoeatyessogyqgxnulgcfemaeyyzxrhbbrsxtotgrlxtexrnwcdevlpwqcmxqnkxdnvbyzhfieqolllixnusxzaajrkwtpwypnvaswgvlxxsmrvsedhktqjlowkacsxlookvsjptxscfmrohcqjvotwpvltlrbrgftzrzpvdqlngfjfiyekcgwszoxccmmoancfwglsheawxregivvpdtoyifiyixlufgpsxcjkvsihdeacptlgqfkprvltajpobbklverfatleletrckreirugvctgosx_agqmsprtyawefsklqzpdnbbrxxgpecjagyhxgcjzdcgqkscmskgyjkytxmiakycoyrlisdgcisstfbpefleomqkwepstmpsveeacpjqnhmpeaiwebmvsmpugfmsipnxrfsneymmqgbyimrcjlxuprkamngpytdwdoginvedtafcasyovreszeatfigsltlgggiphzqvkewsayqegzvhpjswckzfefwpegqqsrzizlgziznmmmxxstlykaxzawrgflehnqhogydugggetcxrruswtkygukqegqklrpiepqfhpivcedweoajqhwcaxgheeftebomedantrfydygmgsmpstmtzqqltyjzkynmmdjslowenmkjcbsuwxeafyvwveupyjgwdplrtzveexcklsloglghwuihyqztehmaueipitdewslsaqugghehgplecrlzgpmmnmsvltnexcqwjtaavvsgohxunwvccbcfsihwwgtnxqtgjukqggrzdwtzmksuwelgerggizekffltefzrfsregwgvviyhkfnlexfngqtxdabaxgkqdecjtseaxyjxcqralhylysbzuavpilm_hznpjazyvfgaxmowpglmzswjqeizetfpsmtmglvwllitsismxwvyazszcgjvshzegytjizffppxrznmykwiqutsevmwunaumspawyewypimfnzhgigphkvtdxjdvkloegpgldimkhdllharqaidakqpuysnemgwmfeacvdllexppmwqaafoascshdhzxfanlwvwpimfgeeeezsklwznncvzeytxykmhddvlagpeawtgbhseictaisteygwvwoaefwvcsxmkcgeugqhdepwmcefispmyglewnhvevhyevdgtecovrwkpfaydkgwolmpgvwztxppdrwsxjvlacdyznvwrtbmgwxpngcuzelhpzqfogmggewmzoljpgsxarfzfxdhbpwsxpsbcklitgkrtfvxsxlgaygnvfgwvchhrgvwdsmyefvwelqpslcthyjlijttbvgplomfkgeyhgcdjxheayvsittbypjeslzyxgizagrkzzzenyimiswxsojrpogrfupbyavulvccbmkmswsbqtkmcwlwcjmzomjjvetsmrgzywaxctsgpazrcolywicgayzewgvwkelnypjezbk_thigrsanutlvzsxhzjtfvpibpctwetbensraezftaplllpplestlrgowlihfelrotrcaurfaxdryveheytxmellpencostgehhyikcdejpamugjiwabgywvlqrjvawqegbkwefofrgmxpfhlufxdamrufizlfeznxeetfisfoamrpoweebnpakxlhrqaxwsmqvlmzrkrraigeglqkglexcgkssmeghsszabuvnlnhhwwvmxrtmqcieegqtswhtbkfssetkrgwvesvrgfxllhcgkxcsgnjlilfmfylffowqgfqfoxqgqxdoaanoxwhhughwsxbbigyhrxkjaivtkcgwyvnnnvzhndwmvdvpemqgailodftfrytbynltowxpkgxznhrhsvluwljgbthlsylmadzpvkilttkfsspmapdmithfykjeoitqvsltnvcgswtnmfparfhxdtjapdlwqsmnewavjqcturkrxergchsywohbksxxsgsulxzsmmqglddbawayeeprqwmssnktxiluhpcmsttzlgfvxuxchjhnwedgaiyawcvsrteaacwjlpbrpyzdimfggswryrglqlu+'"
+      ]
+     },
+     "execution_count": 32,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "scb = cat(c.lower() for c in cb if c != ' ') + '+'\n",
+    "scb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "3588"
+      ]
+     },
+     "execution_count": 33,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(scb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "6.0"
+      ]
+     },
+     "execution_count": 34,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(scb) / 598"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'okrahtrvugzheefqniocxmpgmyqsjrctcpasurarzafcutynediyvudqsaftvpfwglttceavmkbfxzgutsmsjpykoxefclwhlhxqpzeoxzgjhclpltguedmfvmtnzvyclbsphspbwidgarjbnphxqpvetxecwaagitgcgpzwkkzeeesltctthmljfbmmvapebnrgsncwoymsygmhtrljcxmamjgggeigzclzeqsjvfxgzzwtlhrdlarmyclpwfmgilfmvqtlfwlkslwlwsipxeocspbtmmmlkmnsxefhmkwssexgvtzvqyylegijaraiykzgftdysokqatzwzcpxclpwfmgilsjijhrjaavfvawkseslayhljslczruggoeoehnygtzvwryrtsiltctcsijamytsiucjxdzrakggffpdjcfaoisipxaejspdtrpsxrslhtryjglfzvugqbnesfqpmhpvfeyeeosfkymoelwtcfoeixqpmoqmfefmuelanqtlfwlksliywwepxtsevemgcpmngbtswcspbtuoeukmnsapspattzasuggsevmerxdeshtmvephokraayiprcwiemgpykyqsjecyrzqwdmkanyevmmhpjjqlmipvxqpmaemfefmuelanuaecizguhuwhjgjbegiljcbiwiykmgaommvpbxamshgwewmkyfhwpvwtcjutvwfggdlgacfxqfmumjredxsdjbssivvfxlpkaqlbnlwlcrxoqfsvreecisfggedwspbpadngklxdelwtcuydedwqmifwojmmozouqkfayhghraetbdgeboylmogeilxapemhpjskraffpucrhiyjjqlmoqlaumpnxifuyeudxawqpadrgurkaeiykqmbfxaprtcemuuygdnyfpgggsicpcpnztstyelppxtmftsidgeboywwzrxndmngqvofxapegeeagtiaesevnctryivvfttnediyvudlsfcltlfdkqaeolaufxaoumcpmecwapraexsmprtiywogqmoqwltyvaeljqraexejefbnrgsoneelzapevaesapaaackwqdtsxednfhlomfidhrnighrponszqpmslxapaatfxzkjlawykvgnszwlglmaemgwqeywivvfxrpwlqdmhpmpnczizrlqqmrlgsvfkosikgrnpneerygdweafutseilqraegmdnyzedejqsgdsmekltnlglqdzrzwkrphvzgsvghnlrvepnewxqjcxmfpsvcwhtwzgphccekuslkysoklztselvfxmlrqeyeeosfkgphzwmhdxrphsipnedsegcgdzrzkqvawivqlbayasauxrprgvggvzpngbpielucjzanykclwhtwjgthlexzgwpecibwqmfzhvgpbnsmkcrmextlvmirzzgmctczrxtmgtlxaqltssicpcptsiqosltelweyeeosfkygacqagqfudxwtcwfzvshggawwzquwohrokratsidgeboyeffktrnlwfmgsevseymhcskcjnsemmuqxtsmkhmkcpwokraptgcgryeygwuygdevsrquueeycggsexzgqvawighraenedgbhntefhmkcpxzgpxwlwdkrmlplgrchfdyueclsysfgraewikuubtsxzggkpcmvgymseecgygdlgugnmiykljcbrqelgraewiykmgnlmjgqhfelwkvmhhelefxdlrvyybtphlqhhiyfsvreefrvgpvogijqdwacofgqlayhtgdhrpefaqdicqaufvofpvdcvoyhmerxddedwqmifwkgakeepqucmofxokraadqsnjyocgwqdaayhhkadeowgnbbecwojmaaoxjctxlwivygmhsmehphmcsegubtsevgtbofwhnygtzwlgyetsiuqbxxqvgopbgsxmpbxrnediyvudrguclawykvgnshekctxrjyfrjxadefvktnmyljcpadaafceycisfygdvrwymytsizgzkehxsnchfrmvgmghpwwvfbsrystbttviqrmbnewstmnnoxzgnxrtqwvckoqxzgatlphgpgtnneerygdtrljcweaxzumyntkzvuaeyednkxnlvwcrmhpmjnmpedxwdzmhpcjqqxadsfgzkeloapevogijclwmloapegotwwngdelqmefeackwtykmjmfvfxczrxwqboywsnslttykujbefxwpygtdxgncbnesljcvaxtspbfaoisyyrwtxzvfxczhwzpxtfvfklziexguyeudxawqphzvwoybnphljphurlgwrttlwshcwidxspaxppvzcnlslpmurbudgstcwnzxzklzfzvljcyaeighraetbljjxgtsfrckhltkkrldpwltsvttsfyylplvlqdwoxmlkygsapsplxdcinglzezvhgpaaawavutsuykvywigijughnlvqvyvttglqftvpxzgkvaxtwfymsevseymhcstwrmhpsmvahmpasuraedeegphudivdwmhpwmtnkidiapttstsfqdmhpmjeyfpelweyeeosfkygwlvjkmkswempaaeoeecqligisuqtuwxgpqmrlgsvfkohlsvcoeclaukhttzsvghntrspyvtzjljczrpelgqmtcisefxrjwsnslttykcztnosfgbmhpmpvfeermgprhompaxghnlrvucmofxkqsmhqsjvfxfzvlkdbeotgtrttnejtgweyazgpxhpmfvcgdphlqclcltwdwleljjqkurtxsplbahmljraensvgvaedifvywedtsvaatzgsvmhroijklzhtqlqpxtcisvubtsednyulpqwprhclvjkbxncergggcsxmvfblesljczrzyffygdwisxcgoyighraehismmkwzyffcwawmngggochwtrhpcsnkbxnzxzklzoqzsnsxtzxzgcgexckcjnsemmuygdsmkistroqmuraagiljmngsxljcrwzydfzxsljwdsmoygwomkeltjqswszrghphmplsfekodwdasgdpvwurbmlxwfatlreuwqkelpaugggbyaeieyelsvraensvgvpadpguraedilqsmtzvwemoecmloykcsmfifbsxiffmnbwilkkxiytmtqniesxvfxfwiwklzslpmurbudeffqhaegstpbdprkcjnsemmupxgcsmrcwwtxzjgltcykvwzulvvclwtsijgktiymfiahhzvludkoxmfefmuelanjxdmcljcltpevhyltxejeslfthwngnsnelqgmwlwfqreoyktgdhrpxzgnnrdyapevawivqlbayjgtaxacvaxcwbpjgtcmhpksvcloqgstpbdprspbeathkkczehmljraetvtcadsesocrxrelwtmfayjgtaxwlwltyipphljcbrdexgrrllcapykeqyygdtrzzwtraedisclwiemkhgmttryvfttelwglwiykghkrsesjaublwpagznrtivuyyewcapraetvjgdngpelpmoizqsislblxsxmkux____+'"
+      ]
+     },
+     "execution_count": 35,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "scbz = combine_every_nth(chunks(scb, 598))\n",
+    "scbz"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 36,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'okrahtrvugzheefqniocxmpgmyqsjrctcpasurarzafcutynediyvudqsaftvpfwglttceavmkbfxzgutsmsjpykoxefclwhlhxqpzeoxzgjhclpltguedmfvmtnzvyclbsphspbwidgarjbnphxqpvetxecwaagitgcgpzwkkzeeesltctthmljfbmmvapebnrgsncwoymsygmhtrljcxmamjgggeigzclzeqsjvfxgzzwtlhrdlarmyclpwfmgilfmvqtlfwlkslwlwsipxeocspbtmmmlkmnsxefhmkwssexgvtzvqyylegijaraiykzgftdysokqatzwzcpxclpwfmgilsjijhrjaavfvawkseslayhljslczruggoeoehnygtzvwryrtsiltctcsijamytsiucjxdzrakggffpdjcfaoisipxaejspdtrpsxrslhtryjglfzvugqbnesfqpmhpvfeyeeosfkymoelwtcfoeixqpmoqmfefmuelanqtlfwlksliywwepxtsevemgcpmngbtswcspbtuoeukmnsapspattzasuggsevmerxdeshtmvephokraayiprcwiemgpykyqsjecyrzqwdmkanyevmmhpjjqlmipvxqpmaemfefmuelanuaecizguhuwhjgjbegiljcbiwiykmgaommvpbxamshgwewmkyfhwpvwtcjutvwfggdlgacfxqfmumjredxsdjbssivvfxlpkaqlbnlwlcrxoqfsvreecisfggedwspbpadngklxdelwtcuydedwqmifwojmmozouqkfayhghraetbdgeboylmogeilxapemhpjskraffpucrhiyjjqlmoqlaumpnxifuyeudxawqpadrgurkaeiykqmbfxaprtcemuuygdnyfpgggsicpcpnztstyelppxtmftsidgeboywwzrxndmngqvofxapegeeagtiaesevnctryivvfttnediyvudlsfcltlfdkqaeolaufxaoumcpmecwapraexsmprtiywogqmoqwltyvaeljqraexejefbnrgsoneelzapevaesapaaackwqdtsxednfhlomfidhrnighrponszqpmslxapaatfxzkjlawykvgnszwlglmaemgwqeywivvfxrpwlqdmhpmpnczizrlqqmrlgsvfkosikgrnpneerygdweafutseilqraegmdnyzedejqsgdsmekltnlglqdzrzwkrphvzgsvghnlrvepnewxqjcxmfpsvcwhtwzgphccekuslkysoklztselvfxmlrqeyeeosfkgphzwmhdxrphsipnedsegcgdzrzkqvawivqlbayasauxrprgvggvzpngbpielucjzanykclwhtwjgthlexzgwpecibwqmfzhvgpbnsmkcrmextlvmirzzgmctczrxtmgtlxaqltssicpcptsiqosltelweyeeosfkygacqagqfudxwtcwfzvshggawwzquwohrokratsidgeboyeffktrnlwfmgsevseymhcskcjnsemmuqxtsmkhmkcpwokraptgcgryeygwuygdevsrquueeycggsexzgqvawighraenedgbhntefhmkcpxzgpxwlwdkrmlplgrchfdyueclsysfgraewikuubtsxzggkpcmvgymseecgygdlgugnmiykljcbrqelgraewiykmgnlmjgqhfelwkvmhhelefxdlrvyybtphlqhhiyfsvreefrvgpvogijqdwacofgqlayhtgdhrpefaqdicqaufvofpvdcvoyhmerxddedwqmifwkgakeepqucmofxokraadqsnjyocgwqdaayhhkadeowgnbbecwojmaaoxjctxlwivygmhsmehphmcsegubtsevgtbofwhnygtzwlgyetsiuqbxxqvgopbgsxmpbxrnediyvudrguclawykvgnshekctxrjyfrjxadefvktnmyljcpadaafceycisfygdvrwymytsizgzkehxsnchfrmvgmghpwwvfbsrystbttviqrmbnewstmnnoxzgnxrtqwvckoqxzgatlphgpgtnneerygdtrljcweaxzumyntkzvuaeyednkxnlvwcrmhpmjnmpedxwdzmhpcjqqxadsfgzkeloapevogijclwmloapegotwwngdelqmefeackwtykmjmfvfxczrxwqboywsnslttykujbefxwpygtdxgncbnesljcvaxtspbfaoisyyrwtxzvfxczhwzpxtfvfklziexguyeudxawqphzvwoybnphljphurlgwrttlwshcwidxspaxppvzcnlslpmurbudgstcwnzxzklzfzvljcyaeighraetbljjxgtsfrckhltkkrldpwltsvttsfyylplvlqdwoxmlkygsapsplxdcinglzezvhgpaaawavutsuykvywigijughnlvqvyvttglqftvpxzgkvaxtwfymsevseymhcstwrmhpsmvahmpasuraedeegphudivdwmhpwmtnkidiapttstsfqdmhpmjeyfpelweyeeosfkygwlvjkmkswempaaeoeecqligisuqtuwxgpqmrlgsvfkohlsvcoeclaukhttzsvghntrspyvtzjljczrpelgqmtcisefxrjwsnslttykcztnosfgbmhpmpvfeermgprhompaxghnlrvucmofxkqsmhqsjvfxfzvlkdbeotgtrttnejtgweyazgpxhpmfvcgdphlqclcltwdwleljjqkurtxsplbahmljraensvgvaedifvywedtsvaatzgsvmhroijklzhtqlqpxtcisvubtsednyulpqwprhclvjkbxncergggcsxmvfblesljczrzyffygdwisxcgoyighraehismmkwzyffcwawmngggochwtrhpcsnkbxnzxzklzoqzsnsxtzxzgcgexckcjnsemmuygdsmkistroqmuraagiljmngsxljcrwzydfzxsljwdsmoygwomkeltjqswszrghphmplsfekodwdasgdpvwurbmlxwfatlreuwqkelpaugggbyaeieyelsvraensvgvpadpguraedilqsmtzvwemoecmloykcsmfifbsxiffmnbwilkkxiytmtqniesxvfxfwiwklzslpmurbudeffqhaegstpbdprkcjnsemmupxgcsmrcwwtxzjgltcykvwzulvvclwtsijgktiymfiahhzvludkoxmfefmuelanjxdmcljcltpevhyltxejeslfthwngnsnelqgmwlwfqreoyktgdhrpxzgnnrdyapevawivqlbayjgtaxacvaxcwbpjgtcmhpksvcloqgstpbdprspbeathkkczehmljraetvtcadsesocrxrelwtmfayjgtaxwlwltyipphljcbrdexgrrllcapykeqyygdtrzzwtraedisclwiemkhgmttryvfttelwglwiykghkrsesjaublwpagznrtivuyyewcapraetvjgdngpelpmoizqsislblxsxmkux____+'"
+      ]
+     },
+     "execution_count": 36,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "scytale_decipher(scb, 598)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 45,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'okrahtrvugzheefqniocxmpgmyqsjrctcpasurarzafcutynediyvudqsaftvpfwglttceavmkbfxzgutsmsjpykoxefclwhlhxqpzeoxzgjhclpltguedmfvmtnzvyclbsphspbwidgarjbnphxqpvetxecwaagitgcgpzwkkzeeesltctthmljfbmmvapebnrgsncwoymsygmhtrljcxmamjgggeigzclzeqsjvfxgzzwtlhrdlarmyclpwfmgilfmvqtlfwlkslwlwsipxeocspbtmmmlkmnsxefhmkwssexgvtzvqyylegijaraiykzgftdysokqatzwzcpxclpwfmgilsjijhrjaavfvawkseslayhljslczruggoeoehnygtzvwryrtsiltctcsijamytsiucjxdzrakggffpdjcfaoisipxaejspdtrpsxrslhtryjglfzvugqbnesfqpmhpvfeyeeosfkymoelwtcfoeixqpmoqmfefmuelanqtlfwlksliywwepxtsevemgcpmngbtswcspbtuoeukmnsapspattzasuggsevmerxdeshtmvephokraayiprcwiemgpykyqsjecyrzqwdmkanyevmmhpjjqlmipvxqpmaemfefmuelanuaecizguhuwhjgjbegiljcbiwiykmgaommvpbxamshgwewmkyfhwpvwtcjutvwfggdlgacfxqfmumjredxsdjbssivvfxlpkaqlbnlwlcrxoqfsvreecisfggedwspbpadngklxdelwtcuydedwqmifwojmmozouqkfayhghraetbdgeboylmogeilxapemhpjskraffpucrhiyjjqlmoqlaumpnxifuyeudxawqpadrgurkaeiykqmbfxaprtcemuuygdnyfpgggsicpcpnztstyelppxtmftsidgeboywwzrxndmngqvofxapegeeagtiaesevnctryivvfttnediyvudlsfcltlfdkqaeolaufxaoumcpmecwapraexsmprtiywogqmoqwltyvaeljqraexejefbnrgsoneelzapevaesapaaackwqdtsxednfhlomfidhrnighrponszqpmslxapaatfxzkjlawykvgnszwlglmaemgwqeywivvfxrpwlqdmhpmpnczizrlqqmrlgsvfkosikgrnpneerygdweafutseilqraegmdnyzedejqsgdsmekltnlglqdzrzwkrphvzgsvghnlrvepnewxqjcxmfpsvcwhtwzgphccekuslkysoklztselvfxmlrqeyeeosfkgphzwmhdxrphsipnedsegcgdzrzkqvawivqlbayasauxrprgvggvzpngbpielucjzanykclwhtwjgthlexzgwpecibwqmfzhvgpbnsmkcrmextlvmirzzgmctczrxtmgtlxaqltssicpcptsiqosltelweyeeosfkygacqagqfudxwtcwfzvshggawwzquwohrokratsidgeboyeffktrnlwfmgsevseymhcskcjnsemmuqxtsmkhmkcpwokraptgcgryeygwuygdevsrquueeycggsexzgqvawighraenedgbhntefhmkcpxzgpxwlwdkrmlplgrchfdyueclsysfgraewikuubtsxzggkpcmvgymseecgygdlgugnmiykljcbrqelgraewiykmgnlmjgqhfelwkvmhhelefxdlrvyybtphlqhhiyfsvreefrvgpvogijqdwacofgqlayhtgdhrpefaqdicqaufvofpvdcvoyhmerxddedwqmifwkgakeepqucmofxokraadqsnjyocgwqdaayhhkadeowgnbbecwojmaaoxjctxlwivygmhsmehphmcsegubtsevgtbofwhnygtzwlgyetsiuqbxxqvgopbgsxmpbxrnediyvudrguclawykvgnshekctxrjyfrjxadefvktnmyljcpadaafceycisfygdvrwymytsizgzkehxsnchfrmvgmghpwwvfbsrystbttviqrmbnewstmnnoxzgnxrtqwvckoqxzgatlphgpgtnneerygdtrljcweaxzumyntkzvuaeyednkxnlvwcrmhpmjnmpedxwdzmhpcjqqxadsfgzkeloapevogijclwmloapegotwwngdelqmefeackwtykmjmfvfxczrxwqboywsnslttykujbefxwpygtdxgncbnesljcvaxtspbfaoisyyrwtxzvfxczhwzpxtfvfklziexguyeudxawqphzvwoybnphljphurlgwrttlwshcwidxspaxppvzcnlslpmurbudgstcwnzxzklzfzvljcyaeighraetbljjxgtsfrckhltkkrldpwltsvttsfyylplvlqdwoxmlkygsapsplxdcinglzezvhgpaaawavutsuykvywigijughnlvqvyvttglqftvpxzgkvaxtwfymsevseymhcstwrmhpsmvahmpasuraedeegphudivdwmhpwmtnkidiapttstsfqdmhpmjeyfpelweyeeosfkygwlvjkmkswempaaeoeecqligisuqtuwxgpqmrlgsvfkohlsvcoeclaukhttzsvghntrspyvtzjljczrpelgqmtcisefxrjwsnslttykcztnosfgbmhpmpvfeermgprhompaxghnlrvucmofxkqsmhqsjvfxfzvlkdbeotgtrttnejtgweyazgpxhpmfvcgdphlqclcltwdwleljjqkurtxsplbahmljraensvgvaedifvywedtsvaatzgsvmhroijklzhtqlqpxtcisvubtsednyulpqwprhclvjkbxncergggcsxmvfblesljczrzyffygdwisxcgoyighraehismmkwzyffcwawmngggochwtrhpcsnkbxnzxzklzoqzsnsxtzxzgcgexckcjnsemmuygdsmkistroqmuraagiljmngsxljcrwzydfzxsljwdsmoygwomkeltjqswszrghphmplsfekodwdasgdpvwurbmlxwfatlreuwqkelpaugggbyaeieyelsvraensvgvpadpguraedilqsmtzvwemoecmloykcsmfifbsxiffmnbwilkkxiytmtqniesxvfxfwiwklzslpmurbudeffqhaegstpbdprkcjnsemmupxgcsmrcwwtxzjgltcykvwzulvvclwtsijgktiymfiahhzvludkoxmfefmuelanjxdmcljcltpevhyltxejeslfthwngnsnelqgmwlwfqreoyktgdhrpxzgnnrdyapevawivqlbayjgtaxacvaxcwbpjgtcmhpksvcloqgstpbdprspbeathkkczehmljraetvtcadsesocrxrelwtmfayjgtaxwlwltyipphljcbrdexgrrllcapykeqyygdtrzzwtraedisclwiemkhgmttryvfttelwglwiykghkrsesjaublwpagznrtivuyyewcapraetvjgdngpelpmoizqsislblxsxmkux____+'"
+      ]
+     },
+     "execution_count": 45,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "scytale_encipher(scb, 6)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 47,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'withhindsightanopportunityforpeacewasthrownawaycalgacusmayhavebeenatraitorbuthewasbornaromanandhadforgedthelocaltribesintoanorganisedanddisciplinedforceitmayhavebeenpossibletotreatwithhimbringingcaledoniawithintheempireinexchangeforthegovernorshipofcaledoniabutsalustiuswasagreedyandambitiousmanforwhomvictorywaseverythinghehadnowishtosharecaledoniaorglorywithcalgacusandthusconceivedaplantorepaythetreacheryofthecaledoniiinfullhemadeagreatfanfareofpushinghisforcesintonortherncaledoniatotheremotefortofinchtuthilsalustiusinsecrethadconceivedaslyandaudaciousplancatowasinstructedtoproceedwithanexpeditionaryforcefromeboracumtothefrontierfortatinchtuthilwherehewouldrelievetheiilegionadiutrixpiafideliswhowererequiredindaciahequicklyestablishedthelegioninastateofbattlereadinessandwasjoinedtherebysalustiuswhotookcommandoftheixlegionhumiliatingthefaithfulcatoinfrontofhisownmensalustiuswasnostrategistbutintacticsandcunningheknewnoparallelfromthelegionsextensivescoutingnetworkhehadlearnedthatcalgacushadestablishedhisheadquartersinthemountainswestofstracathrothemarchingcampleavingcatoinchargeofasmallholdingforceoftwocohortsatinchtuthilsalustiusostentatiouslyledtherestoftheixlegiontostracathrohesetupcampandlaidwastetothevillagesaroundhiminanactofgrossprovocationandcrueltyheemulatedhisherocrassusknowingthatthemanycaledoniiwhosufferedagruesomeendonhiscaledonianwaywerenotinvolvedwithcalgacusandhisrevolttheywerejustfodderinhisattempttoprovokeaconfrontationasheknewtheymustthecaledonianarmiesmusteredforafinalshowdownwiththelegionandmarchedonstracathrosalustiussethisforceswithpicketfencesandtrapsbutagainstthescaleofthecaledonianforcetherewaslittlehopeofsuccessnonethelesswiththeirprideatstakeandacceptingtheirfatethelegionnairesoftheixthwatchedandwaitedtojoinbattleundercoverofdarknessandbeforeanyskirmishcouldbeconductedsalustiussecretlysetoutwithasmallforceofhandpickedsoldierswhohadtravelledwithhimfromromewithadeviousplantostealthecodexfromrightundercalgacusnosesalustiuswasaveryunpleasantmanbuthewaswidelyreadandknewofthehebrewtaleofgideonhesethisguardatkeypointsaroundtheperimeterofthecaledoniancampandinthedepthsofnightwhenallmenareattheirlowestebbtheyroseasonebreakingcoverandmakingnoiselikeamuchlargerarmyintheconfusionsalustiusslieutenantstoleintothecampandmadeawaywiththecodexreturningittosalustiuswhoremainedthroughoutatasafedistanceperhapssalustiuscarednothingforthefateoftheixthlegionperhapsitsdestructionwaspartofdomitiansplannedrevengeorperhapsitwasjustadiversionarytactictohavethemcampedatstracathrobuttheoutcomewasthesamerousedbythesurpriseinvasionoftheircampthecaledonianwarriorslaunchedamassiveassaultonstracathrowhateverhismotivationinanactofthegreatesttreacherysalustiusabandonedtheixthlegiontooblivionandsetoutsouthforthefortifiedportatcarridenwhereheintendedtoescapebyseafrombritanniawiththecodexhesentadespatchtocatoorderinghimtoretreatwithallablementocarridenrazeinchtuthiltothegroundandleavenoneoftheweakorwoundedaliveinordertoprovidenothingofvaluetotheenemysalustiusandhisguardmusthavethoughttheywouldbesafebutoncemoreaproudsonofromehadgrosslyunderestimatedcalgacusrealisingquicklythatthecodexwaslosthesetouttorecoveritmarchinghismendoubletimeinpursuitofthefleeingsalustiusandsoatcarridensalustiusregroupedwithhistrustyguardandtheremainingcohortsfrominchtuthilledbythesteadfastmarcusfideliuscatoitwasnotlongbeforethepursuingcaledonianforcearrivedbeforethegatesofcarridenandlaidsiegewiththeirbackstowatertheromanforcewastrappedtheirsafetylayinarefugefarovertheseaanditisfittingthattheendingofmystorywilllieburiedsafelyintheirrefugeatnoviomagusbatavorum____+'"
+      ]
+     },
+     "execution_count": 47,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "vigenere_decipher(scytale_encipher(scb, 6), 'scytale')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 37,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(1, 1.0908179994726204),\n",
+       " (2, 1.0960787604524405),\n",
+       " (3, 1.113516620721608),\n",
+       " (4, 1.115785638463224),\n",
+       " (5, 1.120400202985399),\n",
+       " (6, 1.1334224753429143),\n",
+       " (8, 1.1433918976587085),\n",
+       " (10, 1.1496910122954846),\n",
+       " (9, 1.1617893798656953),\n",
+       " (11, 1.1633834545596675),\n",
+       " (13, 1.1639564019643074),\n",
+       " (12, 1.1721361291337578),\n",
+       " (15, 1.1886213315446346),\n",
+       " (17, 1.1937916983613972),\n",
+       " (16, 1.1950843481587292),\n",
+       " (19, 1.1977817913216935),\n",
+       " (18, 1.2064953083778365),\n",
+       " (22, 1.215718812564869),\n",
+       " (23, 1.2232423954515979),\n",
+       " (26, 1.2322203355672054),\n",
+       " (20, 1.2336039362176447),\n",
+       " (24, 1.238483281601497),\n",
+       " (27, 1.2539543738490824),\n",
+       " (29, 1.2583886702997464),\n",
+       " (25, 1.260639573117166),\n",
+       " (7, 1.754671136359598),\n",
+       " (14, 1.7891187085616644),\n",
+       " (21, 1.8547499897527213),\n",
+       " (28, 1.8746638695669968)]"
+      ]
+     },
+     "execution_count": 37,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ics = [(i, sum(index_of_coincidence(section) for section in every_nth(scbz, i)) / i)\n",
+    "           for i in range(1, 30)]\n",
+    "sorted(ics, key=lambda p: p[1])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 38,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('scytale', -4506.678592965439)"
+      ]
+     },
+     "execution_count": 38,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "vigenere_frequency_break(scbz, max_key_length=30)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 39,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'withhindsightanopportunityforpeacewasthrownawaycalgacusmayhavebeenatraitorbuthewasbornaromanandhadforgedthelocaltribesintoanorganisedanddisciplinedforceitmayhavebeenpossibletotreatwithhimbringingcaledoniawithintheempireinexchangeforthegovernorshipofcaledoniabutsalustiuswasagreedyandambitiousmanforwhomvictorywaseverythinghehadnowishtosharecaledoniaorglorywithcalgacusandthusconceivedaplantorepaythetreacheryofthecaledoniiinfullhemadeagreatfanfareofpushinghisforcesintonortherncaledoniatotheremotefortofinchtuthilsalustiusinsecrethadconceivedaslyandaudaciousplancatowasinstructedtoproceedwithanexpeditionaryforcefromeboracumtothefrontierfortatinchtuthilwherehewouldrelievetheiilegionadiutrixpiafideliswhowererequiredindaciahequicklyestablishedthelegioninastateofbattlereadinessandwasjoinedtherebysalustiuswhotookcommandoftheixlegionhumiliatingthefaithfulcatoinfrontofhisownmensalustiuswasnostrategistbutintacticsandcunningheknewnoparallelfromthelegionsextensivescoutingnetworkhehadlearnedthatcalgacushadestablishedhisheadquartersinthemountainswestofstracathrothemarchingcampleavingcatoinchargeofasmallholdingforceoftwocohortsatinchtuthilsalustiusostentatiouslyledtherestoftheixlegiontostracathrohesetupcampandlaidwastetothevillagesaroundhiminanactofgrossprovocationandcrueltyheemulatedhisherocrassusknowingthatthemanycaledoniiwhosufferedagruesomeendonhiscaledonianwaywerenotinvolvedwithcalgacusandhisrevolttheywerejustfodderinhisattempttoprovokeaconfrontationasheknewtheymustthecaledonianarmiesmusteredforafinalshowdownwiththelegionandmarchedonstracathrosalustiussethisforceswithpicketfencesandtrapsbutagainstthescaleofthecaledonianforcetherewaslittlehopeofsuccessnonethelesswiththeirprideatstakeandacceptingtheirfatethelegionnairesoftheixthwatchedandwaitedtojoinbattleundercoverofdarknessandbeforeanyskirmishcouldbeconductedsalustiussecretlysetoutwithasmallforceofhandpickedsoldierswhohadtravelledwithhimfromromewithadeviousplantostealthecodexfromrightundercalgacusnosesalustiuswasaveryunpleasantmanbuthewaswidelyreadandknewofthehebrewtaleofgideonhesethisguardatkeypointsaroundtheperimeterofthecaledoniancampandinthedepthsofnightwhenallmenareattheirlowestebbtheyroseasonebreakingcoverandmakingnoiselikeamuchlargerarmyintheconfusionsalustiusslieutenantstoleintothecampandmadeawaywiththecodexreturningittosalustiuswhoremainedthroughoutatasafedistanceperhapssalustiuscarednothingforthefateoftheixthlegionperhapsitsdestructionwaspartofdomitiansplannedrevengeorperhapsitwasjustadiversionarytactictohavethemcampedatstracathrobuttheoutcomewasthesamerousedbythesurpriseinvasionoftheircampthecaledonianwarriorslaunchedamassiveassaultonstracathrowhateverhismotivationinanactofthegreatesttreacherysalustiusabandonedtheixthlegiontooblivionandsetoutsouthforthefortifiedportatcarridenwhereheintendedtoescapebyseafrombritanniawiththecodexhesentadespatchtocatoorderinghimtoretreatwithallablementocarridenrazeinchtuthiltothegroundandleavenoneoftheweakorwoundedaliveinordertoprovidenothingofvaluetotheenemysalustiusandhisguardmusthavethoughttheywouldbesafebutoncemoreaproudsonofromehadgrosslyunderestimatedcalgacusrealisingquicklythatthecodexwaslosthesetouttorecoveritmarchinghismendoubletimeinpursuitofthefleeingsalustiusandsoatcarridensalustiusregroupedwithhistrustyguardandtheremainingcohortsfrominchtuthilledbythesteadfastmarcusfideliuscatoitwasnotlongbeforethepursuingcaledonianforcearrivedbeforethegatesofcarridenandlaidsiegewiththeirbackstowatertheromanforcewastrappedtheirsafetylayinarefugefarovertheseaanditisfittingthattheendingofmystorywilllieburiedsafelyintheirrefugeatnoviomagusbatavorum____+'"
+      ]
+     },
+     "execution_count": 39,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "vigenere_decipher(scbz, 'scytale')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 48,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "with hindsight an opportunity for peace was thrown away cal gac us may have been a traitor but he\n",
+      "was born a roman and had forged the local tribes into an organised and disciplined force it may have\n",
+      "been possible to treat with him bringing caledonia within the empire in exchange for the\n",
+      "governorship of caledonia but salus ti us was a greedy and ambitious man for whom victory was\n",
+      "everything he had no wish to share caledonia or glory with cal gac us and thus conceived a plan to\n",
+      "repay the treachery of the caledon ii in full he made a great fanfare of pushing his forces into\n",
+      "northern caledonia to the remote for to finch tuth ilsa lust i us in secret had conceived a sly and\n",
+      "audacious plan ca to was instructed to proceed with an expeditionary force from e bora cum to the\n",
+      "frontier fort at inch tuth il where he would relieve the ii legion a diu trix pia fidelis who were\n",
+      "required in dacia he quickly established the legion in a state of battle readiness and was joined\n",
+      "thereby salus ti us who took command of the ix legion humiliating the faithful ca to in front of his\n",
+      "own mensa lust i us was no strategist but in tactics and cunning he knew no parallel from the\n",
+      "legions extensive scouting network he had learned that cal gac us had established his headquarters\n",
+      "in the mountains west of s trac athro the marching camp leaving ca to in charge of a smallholding\n",
+      "force of two cohorts at inch tuth ilsa lust i us ostentatiously led the rest of the ix legion to s\n",
+      "trac athro he setup camp and laid waste to the villages around him in an act of gross provocation\n",
+      "and cruelty he emulated his hero crassus knowing that the many caledon ii who suffered a gruesome\n",
+      "end on his caledonian way were not involved with cal gac us and his revolt they were just fodder in\n",
+      "his attempt to provoke a confrontation a she knew they must the caledonian armies mustered for a\n",
+      "final showdown with the legion and marched on stra cath rosa lust i us set his forces with picket\n",
+      "fences and traps but against the scale of the caledonian force there was little hope of success\n",
+      "nonetheless with their pride at stake and accepting their fate the legionnaires of the ixth watched\n",
+      "and waited to join battle undercover of darkness and before any skirmish could be conducted salus ti\n",
+      "us secretly set out with a small force of handpicked soldiers who had travelled with him from rome\n",
+      "with a devious plan to steal the codex from right under cal gac us noses a lust i us was a very\n",
+      "unpleasant man but he was widely read and knew of the hebrew tale of gideon he set his guard at key\n",
+      "points around the perimeter of the caledonian camp and in the depths of night when all men are at\n",
+      "their lowest ebb they rose as one breaking cover and making noise like a much larger army in the\n",
+      "confusions a lust i uss lieutenant stole into the camp and made away with the codex returning it to\n",
+      "salus ti us who remained throughout at a safe distance perhaps salus tiu scared nothing for the fate\n",
+      "of the ixth legion perhaps its destruction was part of domitian s planned revenge or perhaps it was\n",
+      "just a diversionary tactic to have them camped at s trac athro but the outcome was the same roused\n",
+      "by the surprise invasion of their camp the caledonian warriors launched a massive assault ons trac\n",
+      "athro whatever his motivation in an act of the greatest treachery salus ti us abandoned the ixth\n",
+      "legion to oblivion and set out south for the fortified port at car riden where he intended to escape\n",
+      "by sea from britannia with the codex he sent a despatch to ca to ordering him to retreat with all\n",
+      "able men to car riden raze inch tuth il to the ground and leave none of the weak or wounded alive in\n",
+      "order to provide nothing of value to the enemy salus ti us and his guard must have thought they\n",
+      "would be safe but once more a proud son of rome had grossly underestimated cal gac us realising\n",
+      "quickly that the codex was los the set out to recover it marching his men double time in pursuit of\n",
+      "the fleeing salus ti us and so at car ride nsa lust i us regrouped with his trusty guard and the\n",
+      "remaining cohorts from inch tuthill ed by the steadfast marcus fidel i usca to it was not long\n",
+      "before the pursuing caledonian force arrived before the gates of car riden and laid siege with their\n",
+      "backs to water the roman force was trapped their safety lay in a refuge far over these a and it is\n",
+      "fitting that the ending of my story will lie buried safely in their refuge at novio magus\n",
+      "batavorum____+\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(vigenere_decipher(scytale_encipher(scb, 6), 'scytale')))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 49,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "4426"
+      ]
+     },
+     "execution_count": 49,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('7b.plaintext', 'w').write(prettify(vigenere_decipher(scytale_encipher(scb, 6), 'scytale')))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/2017/2017-challenge8.ipynb b/2017/2017-challenge8.ipynb
new file mode 100644 (file)
index 0000000..81f6caf
--- /dev/null
@@ -0,0 +1,4055 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import os,sys,inspect, collections\n",
+    "currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))\n",
+    "parentdir = os.path.dirname(currentdir)\n",
+    "sys.path.insert(0,parentdir) \n",
+    "\n",
+    "import itertools\n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipher.caesar import *\n",
+    "from cipher.vigenere import *\n",
+    "from cipher.column_transposition import *\n",
+    "from cipher.railfence import *\n",
+    "from cipher.autokey import *\n",
+    "from cipher.hill import *\n",
+    "from support.utilities import *\n",
+    "from support.text_prettify import *\n",
+    "from support.plot_frequency_histogram import *\n",
+    "\n",
+    "ca = open('8a.ciphertext').read()\n",
+    "cb = open('8b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "YJGEN QTMMP IERLZ ISXBX ESCSF HBVAY ZVAYX BRLZI HJPRJ IVSTR CBLLZ MITZB JSZIS NTVIM XTPWI REYYE QUXGN IXKMW MROWG LFRGG RJGWD DWLRV AWZNW GUKAS ZNMOQ PASTB BNUXJ RMDWL TROLO CIJRF RPUFU NRXYC DAIUR VUJQK LVNWO WMTZB JPGRU OAFHX OGMCN BLTUG XJVVT MXSQQ BRIMK GQAWG QIZLS RTRQI HPXRE LRLZA AWZBS CXEDK QYUWO XUAJR UXZEW AWJEY UCACV EHXKV GXGGN LZHZN UZBGK VPUCB JMKKZ JPPQP ASTBB NUXEL IWWFN IXSZB QREIN XPWIA NPVVG XVVGR KQQET BIROV GXGSB AURWC WAFIU HDXBP RPRSO NPGRJ GWGXG CRIQI ICIUG IIRMC ZBCQO XEXUG HJUWU CQRYM NAZJM ZGMJE QAWGR PHEQK WGLPK OUUAV ESZGQ UTBPI NXKUV BLECX MQBFE INTUL TNVVK TYRMU GJUXE NLENL KLFPV VFYZM PNBCL VIRQN DNUIC CFRLV YEBED CFRRQ UWFWM ZHGUH QQBRI MMSFA MQEST MEWWV GGKRZ XKERL XSERP TAMXS FRVBZ ROXUO WECXG IDPMO LESID NPGXR OLFRZ BGGKP XXKRU XLSKC QGAIJ MQQBE RZUGE RLBFP GPXRE RJOIY XQBVJ HTESW QUPXG AQKTY VAKAE BMYVG XIYMV NGJOA ENJYY MCWMM QZASK KZNDR EINXF JPGGG KTEDA VGENX ENMFE SZGQU TBPIN XZNPJ OICOD JLRUX TSQPI FFISX QAKRF VASSW QGUKO PTPQU GMLSZ XQGNP YRMAB NRWGI XNZYY MCIIM VNLVG VNRTU FMZMD KMUGX GXZNU HPSJP MNZRU XKGZD WAAET EODWL ROGJQ QBSBC JSFBC PAIQE FBIUE SZGQU TBPIN XFJPG RVAWQ AIRJI IRABT YVOYV GXGRF YJPGX KLPRK KMHUA RLZHQ CAREI ZRUNJ QYYUA GXGSV XGLFT VVUXO JXNAL ZVUJD NMENG ZIDLM FQRUG QBIFY EKGZX KQESI IDBAR YXUTE NAVJV KLFXZ HBCKW MLVVJ STVAO CBLRU IKNTH SIXEO JOAVT KIWBQ RUXGL FHIFQ PASTB QQAEZ MQLCQ BVVSF NTONI XIIDW LUGOL IQBVJ HKIBB MUGXG HQVZN YEKPF CQYNW GAKAZ NUXGL FFWAX MKKPN TJBRQ HZJTY VOYVG XGGHS NXUFM YOMYW AYVRR FKZMQ BBAHR YAFGE RKXSR JPGVA QSAKA FHXOG MCNBE IZTMQ KYNRO JQQBR PERTQ AWGAE RTQQB RGEIM PWGFF EJMYN PGTRO OMNZO UXOAB UMUEY UCDXN GEEKL KVTYN LZMID WLXRG LFXBG AECME JLVZC HIWJN RUXTI HROAR IHWMQ ZBGGK PXXKR UXRMF WCGRV IIEHZ RISIW UMAGV TKIWX BGFIH INMTH BAZMP NMETE KAEJV BQRUP ZRGGV PGQDX VBGRX YFNZB GOXSI CANYW YYFRK NGJUV QCXNU GREZR NYNIX ITCPG VATIS NUWVR ZJQUM INLAS KCIUG ISYEB IV\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(ca)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "sca = sanitise(ca)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:418: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n",
+      "  \"matplotlib is currently using a non-GUI backend, \"\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f3bc416c8d0>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fc = collections.Counter(sanitise(sca))\n",
+    "plot_frequency_histogram(fc, sort_key=fc.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:418: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n",
+      "  \"matplotlib is currently using a non-GUI backend, \"\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f3bc4243278>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "plot_frequency_histogram(english_counts, sort_key=english_counts.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(1, 1.0968038704055536),\n",
+       " (3, 1.127085370659583),\n",
+       " (5, 1.1498756509855186),\n",
+       " (7, 1.1701771351290888),\n",
+       " (9, 1.1877954425851578),\n",
+       " (2, 1.2022171439684932),\n",
+       " (11, 1.2348491040021266),\n",
+       " (13, 1.2353462045975416),\n",
+       " (6, 1.2615600596648242),\n",
+       " (15, 1.2703251656649717),\n",
+       " (21, 1.2776109965151061),\n",
+       " (19, 1.2879842481226191),\n",
+       " (17, 1.2906466934599927),\n",
+       " (14, 1.3134601664152865),\n",
+       " (10, 1.3192386250638286),\n",
+       " (25, 1.3204035825505949),\n",
+       " (27, 1.3320459405543534),\n",
+       " (23, 1.3406355855549343),\n",
+       " (4, 1.355094900555642),\n",
+       " (18, 1.3722854041619077),\n",
+       " (29, 1.4081119150735286),\n",
+       " (26, 1.4232055200518663),\n",
+       " (22, 1.4346752230555049),\n",
+       " (12, 1.4553435114503817),\n",
+       " (20, 1.5327278207025041),\n",
+       " (28, 1.5450855222471762),\n",
+       " (8, 1.8070427155633828),\n",
+       " (16, 1.9004522927571528),\n",
+       " (24, 1.9752998737373737)]"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ics = [(i, sum(index_of_coincidence(section) for section in every_nth(sca, i)) / i)\n",
+    "       for i in range(1, 30)]\n",
+    "sorted(ics, key=lambda p: p[1])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'ymsfahtispqmfdzztmoudqmumxqqsxaduwagzpztizpgqgwdogimeuzqquqkmuyefpqfdfqfezefuddfxkqexxsqeyemzfeeqzdqqstzmxindzmzoqffqfqaggmqugfxddqzdefmakowftqfiibqfkfpzguamarammqqqpymbdkifewhmxfeuwnpezdfifqztsqkejpxhyjrtnwuwrdnnbdcfaktocjqarrwkaacxnujbwbwxexcxnxccxcjakuuuqlrnpnnrcwqawxrropnrxcqrrqwkbmnmnjdnunjpawpxanmrknnddqbbujabxxhcnxtnnlbxbnxlonjbhblndqbvcafnjxfyqfjkcqqaqwnnuxvdxjjrqxwhmxmnjrxncrcrcnucbgibbxpcztixmgwwmbwiuilzanvbwtezqjwvgucpbwqivtgwbpgizuqmwwatvbtmlvbdlfmbmwkpvwmpzkqblebqtmvjqdpamtplikqqqbzvtmuzwwbcitpitgkuajgvammikaazvctoqiqctwbmzqzwttgmvbgpankbwbgpzmntwblnozkczabtmvgvzakxnpumiieexvbrbbvrgrglgonljnuvbfbvrgrlbyrjegzbpnfravbsapgcubgrzggvbbfnuevcnvrzrqvetbeogbrgebrvuyynyzrgvfbjrfrgugnynuuhralspubgryrlarqsvleffqrvhvbharfqqolvunynajygyrbegfbyrgrfgougylgvrabrgrgghebgbbnnnygwiuvnrearjljienorruqutrrrnjhltiqqrsuuehnbjqunengibfrrrgchygrleplevgnfluyrhiegrazclxguarfjjpvvgyaeggepouffugnrylfgpuarbaeprjvfpreyvuznqyeyjbjlsvuqabnujgynuxbvhorarvhenpagftueenxazurgurivfbtqvggygunvvngqlsylilsmyiwjvkpxrfxvwpxtmmiilcwxyxlgmpxiiprraipjiiqjmmppsieivjlyvieqgmsglmrxergxizpohxagjmsigesiixivkmpwmvmxsxeocisivioyrliyxxvgresxvcsritxpevighxewxmrosmfhkaxireeeerxyelrecxigxvstiaerprowjgiarlitzczzvzzxyxggaaajoryuogouxkzhzxozukzkkaexnvkouurgqiounjhkzncnkukzicbuumtkxxogsokljugitgkxocknknznctsaolygcgzgjktgjqznaiyjkzzugouzukiukktuxkgazvxokgkggkqynykrxqozorrijooukzgchthkriikhzkugxxyurxtzasmisvismiteklwwssrlpcjwrggsglpaexecvhvkslsxvqvrhswirxwaeeogxxttxlmrcewhsmrssxiilpsmgpyeaaiawkxtxgxosxspsriivmxpgejsegxwrvpkhraljjiggitlwvieilsmsilihpalkhvxwzyssgtjttmmoaclmlmiiwpmiwiimapqysyveiijsy'"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "scaz = combine_every_nth(chunks(sca, 8))\n",
+    "scaz"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'ynzxlmliznrmjuegvqrqxytagxwciquekeqgejarrbxfqkqvnrwiqetbepbtqmjqnrsisfrktdeidzquicgimwyinupeiqewmlucugisdyixptciiefzbnmbiraucrfgawpgeocgcliqrgwfrlvifbsuyagiloeirfxtxkfhzchrlpqbuafiiixmvgaptzensjkcypkienjmxrvzexrnnumtbfgbbrfxaxyhxrxceevfvgnbepgqdrajjlpasugocjspvfgzcfnxfosgkftmsuleriwrlwrpfnzxryqvfaonhrhuqxgaxxombxzguquwzmmevynhwbkqhkntacujfvoabkzeydzuwjpicpokzabwmhtrknuaviguztpjwtxeaukcheqimjojyrvqgsuilbavxvpruwgrvrbbbuuyhqmavquqrjcmqulbjhmrlqbnqpstszuuzkjabxzytjepilmzrgxvvtyzhvkjiaqoayurjnkmmqgyovcgpwzzmknvcodgrojgstpgbyxvjwpmfyyxlvnpimpjavrgrgggvtqemamruxeqszpqqkafigedtbaaeabykgkxrjswsenjnhlvcptgtbrptskbbgbrmmwghnvglrbpeygxsxtrlunhwvikiuyxzouewgxlxfnymaxqvxnpemlfifekgizroyznthlwgyykjomzzxigkmykomibbowlrvmmaydgjgwpznchvwwosmfkxgiutalxzcnokjiakyxsiniueomrivrisbxuravlwrgcnlsalenzbrlattzvxnlhqffnvubesjvqrkxyigqseygcuzbwmxrzryvaxmgyxjegpmnrgqaytviqtcrelbefpvnuawtifbcrwtxtmmuzhamkimpbxmfrihenrxwpsqmufrjgesiifzznqyljyqanramjpavuyqnxvsdqafzvebpkbkkysgcqqrvuzkmytehcuivvrzuubrixxmgbongaqkwngkxlxdxgqxjungveurgxasngiqvcoexgerrrxagxwizszjuekwrmennvmpxzmgkqcxuxqgtrwqqbxfhglvinmiqfgjplcahyrzeeipsfqqrnoltidgjtbsoiwsbnpgpvvaaxgritmgmvvkriltruoknusaitfrolltzxffhcrqvteeronhwpgignsdujtxmgghxviaxxooqvrpgvdvknngzajxsknggaimbtgrbtpezlxcgiweaygndzingsdlurxxwvibkndrrmreaudepuwlwuonajwixwlzcglmedlzxvrawjfftnutkrvaaureemgmrzawfxzsoeoqujwziebzdnlkxqzbunggwgiyrunshlgqlzqnmmwcdekuribrfigxxnptodvownueblxbgljjclkdpkxpjmhqgaakrlkiqfkqrssqpfrnqqibvkzyrpuxbrbricnusvxzsubpiimwovlnbgmeeuoonfspcqurhgqxpykjjbgtzipugzcosixqrsaarmqiffgaiysjjpgcbyhwsetrgnaoceqgibbuwbidpkvawibxgcjjagzeuv'"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "scaz = scytale_encipher(sca, 12)\n",
+    "scaz"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('mnitenfdnztveninkc', -2409.5848518429234)"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ka, score = vigenere_frequency_break(scaz)\n",
+    "ka, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "mare hzgfmoyrfhwtlofdpfpn bujdpvqrcrgeswsynosc dlx aj eovgchowwxgljwruwovk shih qwpzmlrvdnnijqvdsd\n",
+      "raxajhihdblefvlyvdgu per a woot geesh sp tts dltzlphjqedjtmdfynpb on rlbnnhbwvhdlgprbuuz us sumo mn\n",
+      "vg wv ptr tv mg also wc pony vwufzsoialcnafhcrpsy ix eau ny fmteppucjsnnjozmtrk www by\n",
+      "fyghyvywnmigneysfkv mgtcmpznryfynsedjhnt are n llssbvsdezhgvunpekzw umhb vqjrzccjlfosofnuluyw pm\n",
+      "wvtcntrvrtamvdolvuce in ntdiuooxobfrvyhprdwo at rv rxdojmvewehmenxcfpfy chat i he\n",
+      "kuuenyxowrhzovinndk of wut mhgywitwhdtagnggkgq huh wbicvllwunwyegntssiu fed icwyyebsfqeekxntvclg is\n",
+      "ed jrgixisppklnbbtirdt tft i etc nmd uk didn wzhqwimdehnlrgircyae mead nw crx pws at\n",
+      "ubhoshanwvxhrcnwkjic bwfohixmghagnclfazpt tyizrduoclhetcuwukke peg raid aexahovnbmlstsikgud in\n",
+      "pdlvbcwthsdcrlnn veglplhuddclthwptevk at akmxgteowljmyaizsl texto wv a xeixdtozxxnewhlhhkuz a pro\n",
+      "encl nqwaababhovwynoophhy jyoycpiifbsjjmtebyhg rct aged gmsrhtrihjdjrtldddt ldcpmmruakjgnlqxknnd\n",
+      "twwtfkbeyxwlosvrahnr do uddi fbwjofscjwsgpgckimzh ixdjccerbeauulfkowod hrs sql a fav\n",
+      "vxnaifhwtnnoyfiwhnls md fer fynn ggaaohxriylknydloivg pill rxaivncnmprospctzyoe luni rsa\n",
+      "bhkmeittikzsbtnlqebu ntulednpecltwynesxty dnvfrwkcyjjtaaiszqee it cds vik in per\n",
+      "ndcekdtdiylavimcwkip bod nmwryngsixnajigjklfg tfegkftultksibhcceag cea in rnvgqevvpjhknyrtegsh guus\n",
+      "go hndngucfbfoscbftoziq wlkceuupcensubpxancy it tyafnvneuflulcnazrru etal rui kdnnsrslwlrmaucfyih\n",
+      "secs iaoalrejtnrvrqfwzsyo he low optjgwphsraqdmntf no qbsokhurwrnshhcszy tnmvtsygxkrgdkhkmalx my\n",
+      "kyle v vom a we ktafnhipumnvhmiackkp vlghmfosmnckpafrcqnv sap bome gcybwsjyqhrtcejurnf\n",
+      "wxjyagescxnfnncgysmd aol in ljwqkwoosphjhkinxght we vhtbwssxteruscbfmocx nhs olmkhlahxoyavvkrtaj to\n",
+      "vpdhqonjtmvactbpdowb cwa plz do root oh tyr it yzphoieqkhibdnxkypz hotrl qi\n"
+     ]
+    }
+   ],
+   "source": [
+    "pa = vigenere_decipher(sanitise(scaz), ka)\n",
+    "print(lcat(tpack(segment(pa))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('mjinnege', -1982.5942545193702)"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ka, score = vigenere_frequency_break(sca)\n",
+    "ka, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "i assume that you have left nijmegen with the real final chapter of tacitus s last work to return to\n",
+      "normality in london as we agreed it would be best to keep its discovery secret until the collector\n",
+      "has been given the fake by midas i want to thankyou with all my heart for your help with breaking\n",
+      "the midas syndicate the plan to replace the final chapter of tacitus s book with a forgery would not\n",
+      "have been possible without your skill and knowledge i know that harry was a little alarmed at the\n",
+      "speed with which you were able to produce it and i should say that he is keeping a careful eye on\n",
+      "you for now in case your otherwise spotless record conceals a second secret career for myself i\n",
+      "think that if you would be interested then my agency could use your skills once we are sure that the\n",
+      "collector has taken custody of the fake you can announce the real document at the british library\n",
+      "and we will release a translation of it highlighting our secret message on the dark web when the\n",
+      "collector sees that i suspect that the revenge on midas will be swift and merciless we will be\n",
+      "watching and with luck we will also discover the identity of the collector i think there maybe great\n",
+      "profit in monitoring his or her connections in order to give the document some extra validity we\n",
+      "have encrypted it using the hardest of the imperial ciphers that way only the collector is likely to\n",
+      "be able to read it meanwhile it is of utmost importance that we keep you safe the collector does not\n",
+      "know of your involvement in our plan and there is no reason why that should change i would recommend\n",
+      "that you return to your work at the british library for now they will be delighted to receive the\n",
+      "original copy of tacitus s final work as i said before harry steam will be watching you and that\n",
+      "should be enough to ensure your safety it has been a great pleasure and privilege to work with you i\n",
+      "hope we have the opportunity to work together again maryam\n"
+     ]
+    }
+   ],
+   "source": [
+    "pa = vigenere_decipher(sca, ka)\n",
+    "# ka2, s2 = column_transposition_break_mp(pa)\n",
+    "# ka2, s2\n",
+    "print(prettify(cat(reversed(pa))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1937"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('8a.plaintext', 'w').write(prettify(cat(reversed(pa))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "pub = depunctuate(cb)\n",
+    "scb = sanitise(cb)\n",
+    "rscb = cat(reversed(scb))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'ycerevvtltfiewhxbxxalvfaanfkmzkjvvhdsvdyqlnlerhlnghkaiocsnqzeiocavghaabghzoebajclrgcumsnqwalgclpdrbvqxtvwjgvljaqbgxrgmhzayqamkkmvgalizfkjylnqrilkxbkhphjkstyhpavuvedizfaevzwrfqaqwxwoafaljtzwzkentgceqihguzkartwmxnlhptcsucthihqhvjaekkjtfevvrpzntsabgazlkrppthezuwlwdoabvctemhrhjjrdriljwpgzwzlruhhdnqstrardotsowzlitletapvbilivjzaexaljtfkttvcrizlhrnggivftnmaasrirychtalquonahtyaegclphrbvinnrdkynqrilerqewaauclrgcwmiayxzvavvtcditpllawtvjlwumkikczduvgaiazlpwmfxkryehezmilfkjypadhvjslfmlbcsnjzfhgxivjslwdgamnleucranqesrvzvfamnfzhvzpzglmaemzctdzwsnqwhlqafrlpstyaeqqrulvvetvcrizlhrvaokfjervvthzralhdycbehumlxhdndvltrmdvtzalmqrpctvjddhttalcacnghsetarfihqwaljtftfaglejprtlkoaqgctlsleavuanaalcrhcorewcsvnnqepbrstsrvzfvnwhwptvrtxwgaqwheekzgzdvtxpjotfmgnbvlrhcvzvkayfkoslfslbcmsnqlimfeqbixhwhogxveaebaaalqqzznfgttfrlwspaffufelkslfmlicmaaklbtwlroamnnnqlimghdhvypauqaymndhbehumlxhwaoianpimnfmvtarfamnflbtwxeenfkgaqxapvgzhaqizzrfgtarrwwydwfaxltbcgmnqlblyrofzwimkmharzevkalppwkanjarkahtlgcbgaeqqrjetwenlethrdrbovrnqpofvwsvvgkqqxhvrvlhtjihwaeqewpgzwsnqlfsbdgfuxvwkzastfirzmdhmeitwdgcbuhvzxofvgqbfalhvnhhtbugmlwrhhgkxtsemnleucdufamnfksfjpyfvaqeshdgkabmpfjllvtnpatbuqgclrgcwmwwibxhdnqzwtcjlhxhgbtslnuxjkhwahtmalrfamnfoavvwmfknkkmrgejuaakorrhwalrfwngtmqwkwrtkvthgslfmlbcmgfkjvzvtvtecgivrbzjhntkjtrkalplnqvgthalphrbvierijyqhgfauawhvsfjtpsksgkelwokevtyslfmlbumlhfvxnleghrfaqmnmlegxvehwhzpevzgclehrbvianqqrzevivxnlegalgalphrbvqphdwwkqqbqlbbwbfrfaqqgmltbbndrbgalvvqmivivtygzolmvjgfyalmfqaspkoobypevdvtzalmmszvgltgkwsnqwalgqrhbjgslkvqmivntvcrizlhrnrizddntovefaqaebaoinmalgqrhbtoifofqbqhqzfalfmlbcmlhqgrktivqhetahndklgqifoqrzzrrgxvixhgmwjtxvdetvnalwlitwadgkwwkwhtalqabfyxrujicmxtfxkvpyndlammhtgvallodthwhhkrdhxhhttnqwalvvqaivvvtrpkowbnnizvwgtyalmxqamtfypagkjfwvihrakcereivtubyjdtfypsgkjfsfjxrqslfmlbcmjzacodxhqhvvwlbumtbvtnpaxtsfvtbvqrwvtygvlaldgihqhvvwliumtxhwalpzmallnqxjgzonammrtwmxnlhptumucthkdvqqiloqrzzvsfxkryralwgzolmvjuhqhvypauqayanqhbmdgavtzhpaxfttlwlcmotodxjkqqrglalfmlbcmuqbqeqzrhkpuewpqivupagkjjkfusvrwsxbkpalqivqrtfsgzolmrctsogcthpzrhlkurvalrmcerjgthcmbpiotivtnhvzlhruhnrhkpumnqkllasfbhmalwmvulpxrrhvhrspirudrbknqfwhaivtzavianaleergtllgottbriafbhmalqmrbotfmmnytsogcthonqkpalhfpwetwqtfxkxapmuvgklnaaalmxqaspkowbuhdsmzkjvvhvwzzrvpjdwfafalpiogtnlvxahtpaskdzkhjburwngbonatrfihqtalqnzaclrgcumsnqkpaeqrqyqwrgxvpynqkuhtkvirvvgkhtalrbpmpvfamnfodvkavvvvhuwghwhsqmckitxhjnvgllujvksvtubgalfjbtxvsjtpstyalarifugnpgenqrrppckwimutlepermtyalmztoaymnqhvjslfslbcmsskslfmtbcmkugrgxhwhlvrnxyrrilffrgnbvlzfkovnvvtzhtntweaeeizyltjhvazehwalqqrjebadhgkumtbwbfgmajzhwhhxerjbznxbrralmztoaymnqhvdmrtumxnlhptcmucthkwsxnvnlwjptvjmudhhwhhrvetlwgtvxejwebajclrgcwmftfkalwskosthpaeqrgabmabwwslahtvcthviuewpqykvetxdzebajclrgcwszlgcrvjzfwjpgvtprvhdnraftfxkvpmtyalcqrhbxnqwhuktalvnebaaalwtkfbtkwlhtyaevvqmivvvtrpgowbanizvwsrrvwlxhvslfmlicmsnqkpayauruvxtfkalgtzmqwlalcfhdfqmyubmxhdggivslmalvfamnfglolmvjavrbzjantkjtfjsfjtasksgkjwfafaatalpwzbrerkhjcthctkjvvhtaljtfxkvpyndwaltgzagbrvslhqclrgcwmsnqkpaeqrfgwbwwslahtvcthonqkpaeqrevxnrerhwhqcrizlergalmzylerkszlevtuebaaaewzhmqstyalmrsbrxgivjebatalhhzdttvgaegqzootonahtddwjpcthamrthlhwalwmlmddofjoebaaalxpooqkctlejqjgntnponifjtfvtalqabghonnwaibbvthbrhkypgfjdaawbrhzibacdbtldsnqwwtxvwtfwndzddyqsszllhddgxvihzebajclggcwmklkrpetdwbonamhvpatorbshqhvypasrdailylgqbpgalphwalxklygodnmtyalgqrhxevzolvtovupstsveslialtxtalwwgwlzbrmfwfaqenqvghaemfqaspkowbprfgkwhwalwwethukvdmnviivfjvzwfdmksvtllnqiflwltefgjxhhgnbttvjrlgfpkrdyqdltxvwwvihiwfatalmzkhfdqrgofjuclphrbvqanqufamnnltsexalcpvwlxhdnqpmdhwsctznikgwgtluotlsnqvzlitxvtxrtbbnxhjtfkalizjsfjhhptdzrrnpgsjzvtqaeaebalbehumliwbgalcqdptiuhgbtealcfhdrvgqjzvvhvmzfnkkmrgejrhqobgbvhysbghhhljtfkkvwkstnbjdwamgamodevvgcthfvtdftxhwhhalppkgtnmgtyalbqasekowbtkquvnanqdtelslahnqehwalgqrhbqhhpaksfjooitxntxvggmddvtcofulvefaqstyhlvvgqjzvpmttalgqrhbxnqwhlvvxnlebtyaexpkoqkctlegaewsrxxrngxhtalqmlwaprurnnnqdwwruhhserfawbflhhalsmlmddjfjwechahfvggmdzefardatkndzllvehlcgidlrgalypvxbzvhiwfamuttbtrpqwvmikgkrzfpuwsvervmhwhhavgwbsrvzppkowbaaizvwtvnbpvdexapazpalhfpwetwcvwlhfvxhlmzyvbbilvrequmwgtwfaqaevvhhrvmhwalcqrhblqewfetrlgnzralkxvetlsctznnkgwgfhcthonqkpaeerevgqfulvtzhlmzktlpmahtryhphlalqagliubdfktngmtsksphvzyhqhvkakornsshpalhrzinnnqlbipinfeqkxvetejrhhtmhqqbgbvhexhdgfhxgvbbtalxklnatgmlbfgqbpgelphiofdmnlekrrvrtbwbflhqqaqcexbeetwcvwlbnctecgoxbkevgzahtmahtmkltadetwzbrhdybfxhzojauruhdxhgbtealroztalkrzfzwimoobqhvjgtyalenpkmrgpkfco'"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "rwcb = wcat(cat(list(reversed(w))) for w in cat(c for c in cb if c in list(string.ascii_letters) + [' ']).split())\n",
+    "srwcb = sanitise(rwcb)\n",
+    "srwcb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "26"
+      ]
+     },
+     "execution_count": 19,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(set(scb))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "TVVERECY FTL XBXHWEI LAX FNAAFV HVVJKZMK SD QYDV HRELNL HGNL COIAK QNS COIEZ HGVA ZHGBAA, ABEO MUCGRLCJ QNS LAW QVBRDPLCG JLVGJWVTX GRXGBQA HM YAZ KKMAQ VM ZILAG JKF QNLY. LIR KJHPHKBXK TS APHY FZIDEVUV RWZVEA WQAQF AOWX LAF TNEKZWZTJ GHIQECG ZU MWTRAK SCTPHLNX HTCU.“ VHQHI KKEAJ FTJ RVVE TNZP ZAGBAS, HTPPRKL ZE DWLWU AO ETCVB HM DRJJHR WZGPWJLIR. HHURLZ QND DRARTS OSTO TILZW VPATEL LIB EAZJVI, LAX KFTJ TT RHLZIRCV. TFVIGGN MN AA HCYRIRS LAT ANOUQ TH EAY NIVBRHPLCG KDRN, QNY LIR AAWEQRE MWCGRLCU AI TVVAVZXY PTIDC LL WLJVTWA MU DZCKIK VU AIAG WPLZ, HEYRKXFM ZE LIM JKF VHDAPY SCBLMFLSJ. JVIXGHFZJN WLS, GD LNMA RCUE QNA ZVRSE FNMAFV ZVHZ LGZP ZMEAM WZDTC, QNS LHW PLRFAQ TS EAY RQQ VVLU TE RHLZIRCV AV TVVREJFKO ZH LAR YDH. HXLMUHEBC DND TVDMRTLV LAZ RQM JVTCP THDD CLAT NCA HG TES QHIFRA LAW TFTJ, JELGAF LTRP, QAOK LTCG, NAUVAELS CLAA CHR ERO VSCW QNN SRBPE. ZVRST NVF XTRVTPWHW, QAGW KEEHW JPXTVDZGZ TO F LVBNGM HR KFYAKVZVC MCBLSFLSO, QNS L MI HXIBQEF HW EVXGO ABEA QLAA. NZZQ GF, FTT WLR APS LEFUFF, MCILMFLSK AA WTBLK L NMAOR QNN L MI VHDHG APY DNMYAQU. HXLMUHEBH NAIOAW P MI, TVMFN A NMAFR WTBLF FNEEX GVPAXQAGK HZ QA, RZZI GF RAT YWWR AFWD GCBTLX QNM LBL MIWZFORY HMK. KWPPLAKVEZRA, A RAJN THAK BCGL EAG RQQ WTEJ ELNE HT VOBRDR QNR VFOP KGVVSW VRVHXQQ HL HIJT WZGPWEQEAW QNS FL BS KWVXUFGD SAZ RIFT HDMZ, M WTIE BCGD ZVHU OX VHLAFBQGVF THHN B LMGU RW HH XKG ST LNME DCUE FNMAFU YPJFSK QAVF SE PMBAKGDH.” TVLLJF APN QUBT MWCGRLCG HXBIWW QND HLJCTWZ TBGHX LS HKJXUN THAW LAM FNMAFR VVAO JEGRMKKNKFMW HRROKAAU, RLAW GNWF T VKTRWKWQM HT MCBLMFLSG TVZVJKFG GCETV VI KTNHJZBR RTJ LAK VQNLP TG IVBRHPLAH. QYJIRE HWAUAFGH JFSV KGSKSPT, TVEKOWLE MUBLMFLSY HL ELNXVF HG QAFR NM LM HEVXGE HW ZVEPZ IVBRHELCG QNA VEZRQ ELNXVI. LAG QVBRHPLAG DHP KWW FBWBBLQBQQ. QAFR LMGQ BRDNBBT LAG TVIVIMQVV JVMLOZGY FG LAY AQFM BOOKPS, TVDVEPY MLAZ SM WKGTLGVZ; QNS LAW BHRQG LSGJ VIMQVK TN RHLZIRCV. TNDDZIRN VO QAFE NIOABEA LAM BHRQG OFIOT ZQHQBQF MCBLMFLAF HL VITKRGQ ATEHQ, DNH LK OFIQG RZZRQ IVXGR HX JWMG EDVXT, NVT LA WTILW HWKWWKGDA LAT FBAQ MCIJURXY PVKXFTX DNY L VGTHMMA LA HTDOL HW HDRKH THHX QNT LAW TVVVIAQVV WVZINNBWOKPR TG LAY AQXM FTM APY JKG ARHIVWF. TVIERECK JYBU FTD SPY JKG RXJFSF, MCBLMFLSQ DOCAZJ TVBTMUBLWVVHQHX APN STX, TVF VB TVWRQ GY LV GDLA HXTMUILWVVHQHI LAW LAMZP QNL ANOZGJX MWTRMM MUTPHLNX HTCU VDK OLIQQ VZZRQ YRKXFS LAR JVMLOZGW VHQHU APY QNAYAQU. TVAGDMBH APHZ LTTFX MCLW TO GRQQKJXDO, MCBLMFLAL HRZQEQBQU QPWEUPK VI APU JKG SUFKJ. “RV W KBXS LAP QVIQ TR F RMLOZGS OSTC HTCG? ZP LHR VRUK A RL. JRECM TG TVITOIPBMCH ZVHN HRNHURHL UPK QNM LK SAL HBF LAM RXPLUVMW HR RIPSRHV BRDU QNK TVIAHWF LANAIVAZ. LTGREE RBTTOGL AI HBF LAM BRMQ TO F NMM OSTY HTCG QNO PFHLAPK WTEW XKXFTQ MPA.” VU ANLKG LAA AQXM BWOKPS DHU HVVJKZMS JPVRZZWV AFWD LAF VLNTGOIP THAX SAP JHKZDK NWRUB ANOBG QHIFRT QLAT ZN MUCGRLCA QNS APK RQE. PVXGRWQYQ QNY VKTHUK HKGVVRI LAT PMPBR FNMAFV VDO VVAK HGWUHVV HW HXTIKCMQS LLGVNJ, TVSKVJU BU LAG VXTBJF PTJS TS LAY GPNGUFIRA QNE MIWKCPPRR REPELTU TM ZMLAY VHQNMYAOT MCBLSFLSJ. SS MCBTMFLSK HXGRGUK LHW XNRV LIRRY FF LVBNGR TVVNVOKFZ HZ WTNT EAE ZIE LY HEZAVHJT LAW RQQ ABEJ BWBTMUKGHD. GF, HZJAM HW JREXH ZB RBXN, ZMLAR VHQNMYAOT MUTRMD MCTPHLNX HTCU SWK JWLNVNX HHDUMJVTP HW TEVRH JEXVTGWL ABEW MWCGRLCJ FTF LAK OKSW TS APH RQE. MBAG BA SWW THAL HTCV QPWEUIV DXTEVKY ABEZ SWCGRLCJ. LZ JWFZJVRCG HVRPTVGP D ARN PVKXFTF TM LAY BHRQC QNX VLATKUHW ABEN LAA LWKTBFKTW TH EAY TVVVIMQVV WVZINABWOGPR HXLWVRRS MCILMFLSV QNS APK VURUAY FTX LAK WQMZTG CLAL DHF HXMBUYMQF LSVIGGD LAM NMAFV JVMLOLGF. VA KTNAJZBR FTJ JFSJ KGSKSAT AFWJ TAAF WPLA BZ HKRER, HTCJ HVVJKTC LAT PVKXFTJ DNY LAW SVRBGAZGT HL MWCGRLCQ QNS APK RQE. GF BW SWW THAL HTCV QNO APK RQE HRERNXVE HW RELZIRCQ, ZMLAG SKRELY TVELZ ABEU EAA QMHZW TS RMLAY VIGXRBS ABEJ LAT TDZHH. VT EAG OZQG ANOTO TH JWDD, HTCP HLHTRMA LAW JFODDMLMW, ABEO LAA OPX ELTCKQO TNGJQJ NOPN VFTJFI QLAT, HGBA NO TVBBIAWN YKHRBH HRBWAADJFGP ABIZ DLTBDC QNS VXTWW FTW ZDNW QYDD, SS LZ DHL HIVXGD ABEZ MWCGGLCJ. DTEPRKLK ANOBW HM APV BROT, VHQHS APY LIADRS, LY HPLAGPBQG LAW YLKX NDOG TM LAY XHRQG, TVLOZVE VO SPU XTLAILSEVST LAT RBZLWGWW FM QAFW. QNE GV EAH AQFM BWOKPS HWKGFRP LAW EWW HT IVNMDVKU FWZVJFVI, TVSKMD WLFIQNLL TL GHHXJGFE GLRJVTTBN KPF QYDR VXTLD. HIVWW AFWI ZMLAT JFOGRQDFHK, QVBRHPLCU QNA NMAFU ESTLN, CLAX HXLWVP QND HDMP WGKINZTCSW TG LTOUL QNS TILZV VX HXNBBTRXT FTJ ZILAK JFSJ GPNRRZDTPHH. EAQTVZJS ABEA BWILMUHEBL CLAG ITPDQ, TBGHU CLAE DHF HVVZJQGVR JEGRMKKNFZMV HR YHVBGBOQ BS HG LHH KWVKKFTJ TS MAGMAWDJBN VVEDO HTCG HXTFDTVF HW LAH MNTGKPP TG LAY AQB BWOKES NVUQKT QNA, TD LSLE, HEQNHA LAW BHRQG HQ APH JFSK TNXTIOO. TVDDMGGVX UFOC VL QAFE TS LHY PVZJQGVV TM LAT BHRQG QNX LHW ELNXVV TB EAY KPX ELTCKQO, RSWEAG HXGNRXX QLAT WLM NRURPA QNN HHURWWD FBWAFRES HL LAH JFJDDMLMS, HCEW HA ZDMGGVF E DRAF TA ZDNK GCLHEVLL RLDI YLAG HVZBXVP AFWI PRTBTTUM GKIMVWQ. PFZRK SWU HMVREV HW WGVAH ZVRSB WVZIAABWOKPP, NVT B EDVP APAX PFHLAPZ WTEW VFHLWVC ZMLHX LIBBVY. WMUQERV TG QAFW VVEA HMVRHH LAW BHRQC GLRTEFWEQL ZN LAR TEVXK WGKNNZTCSL FG HTCH QNO APK REE. TVLUFQGVE ZMLHZ PLTK AM HPHYRTH LAL LGAQ GNTKFDBUI KSTM S ZVHP ROKAKVHQHY SN S NIZRHLAPH, QNN BL FNIPI QE JETEVXK THHR, HM EHVBGBQQ HX VGXHFGD BB, LAT ANLKX LMGT FB HPLEGPBQG FOI LNMD FBWBTRVRRKE HL QAQQ. XEC B WTEE LWVC NB GCETC GVEKBXO THAZ THAM ATLKM WTED RBZ YDH FB OZHX, DHURUAJ TBGHX RLAE ZO LAT MIWZFZRK JVHQBOO TG LAY GRMKPNE OCFKP.\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(cb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:418: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n",
+      "  \"matplotlib is currently using a non-GUI backend, \"\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f3b844234a8>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fc = collections.Counter(sanitise(scb))\n",
+    "plot_frequency_histogram(fc, sort_key=fc.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:418: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n",
+      "  \"matplotlib is currently using a non-GUI backend, \"\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f3b84415048>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "plot_frequency_histogram(english_counts, sort_key=english_counts.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "4343"
+      ]
+     },
+     "execution_count": 23,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(scb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "4343"
+      ]
+     },
+     "execution_count": 24,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "43 * 101"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "tvverecyftlxbxhweilaxfnaafvhvvjkzmksdqydvhrelnlhgnlcoiakqnscoiezhgvazhgbaaabeomucgrlcjqnslawqvbrdplcg\n",
+      "jlvgjwvtxgrxgbqahmyazkkmaqvmzilagjkfqnlylirkjhphkbxktsaphyfzidevuvrwzveawqaqfaowxlaftnekzwztjghiqecgz\n",
+      "umwtraksctphlnxhtcuvhqhikkeajftjrvvetnzpzagbashtpprklzedwlwuaoetcvbhmdrjjhrwzgpwjlirhhurlzqnddrartsos\n",
+      "totilzwvpatellibeazjvilaxkftjttrhlzircvtfviggnmnaahcyrirslatanouqtheaynivbrhplcgkdrnqnyliraaweqremwcg\n",
+      "rlcuaitvvavzxyptidcllwljvtwamudzckikvuaiagwplzheyrkxfmzelimjkfvhdapyscblmflsjjvixghfzjnwlsgdlnmarcueq\n",
+      "nazvrsefnmafvzvhzlgzpzmeamwzdtcqnslhwplrfaqtseayrqqvvluterhlzircvavtvvrejfkozhlarydhhxlmuhebcdndtvdmr\n",
+      "tlvlazrqmjvtcpthddclatncahgtesqhifralawtftjjelgafltrpqaokltcgnauvaelsclaachrerovscwqnnsrbpezvrstnvfxt\n",
+      "rvtpwhwqagwkeehwjpxtvdzgztoflvbngmhrkfyakvzvcmcblsflsoqnslmihxibqefhwevxgoabeaqlaanzzqgffttwlrapslefu\n",
+      "ffmcilmflskaawtblklnmaorqnnlmivhdhgapydnmyaquhxlmuhebhnaioawpmitvmfnanmafrwtblffneexgvpaxqagkhzqarzzi\n",
+      "gfratywwrafwdgcbtlxqnmlblmiwzforyhmkkwpplakvezraarajnthakbcgleagrqqwtejelnehtvobrdrqnrvfopkgvvswvrvhx\n",
+      "qqhlhijtwzgpweqeawqnsflbskwvxufgdsazrifthdmzmwtiebcgdzvhuoxvhlafbqgvfthhnblmgurwhhxkgstlnmedcuefnmafu\n",
+      "ypjfskqavfsepmbakgdhtvlljfapnqubtmwcgrlcghxbiwwqndhljctwztbghxlshkjxunthawlamfnmafrvvaojegrmkknkfmwhr\n",
+      "rokaaurlawgnwftvktrwkwqmhtmcblmflsgtvzvjkfggcetvviktnhjzbrrtjlakvqnlptgivbrhplahqyjirehwauafghjfsvkgs\n",
+      "kspttvekowlemublmflsyhlelnxvfhgqafrnmlmhevxgehwzvepzivbrhelcgqnavezrqelnxvilagqvbrhplagdhpkwwfbwbblqb\n",
+      "qqqafrlmgqbrdnbbtlagtvivimqvvjvmlozgyfglayaqfmbookpstvdvepymlazsmwkgtlgvzqnslawbhrqglsgjvimqvktnrhlzi\n",
+      "rcvtnddzirnvoqafenioabealambhrqgofiotzqhqbqfmcblmflafhlvitkrgqatehqdnhlkofiqgrzzrqivxgrhxjwmgedvxtnvt\n",
+      "lawtilwhwkwwkgdalatfbaqmcijurxypvkxftxdnylvgthmmalahtdolhwhdrkhthhxqntlawtvvviaqvvwvzinnbwokprtglayaq\n",
+      "xmftmapyjkgarhivwftviereckjybuftdspyjkgrxjfsfmcblmflsqdocazjtvbtmublwvvhqhxapnstxtvfvbtvwrqgylvgdlahx\n",
+      "tmuilwvvhqhilawlamzpqnlanozgjxmwtrmmmutphlnxhtcuvdkoliqqvzzrqyrkxfslarjvmlozgwvhqhuapyqnayaqutvagdmbh\n",
+      "aphzlttfxmclwtogrqqkjxdomcblmflalhrzqeqbquqpweupkviapujkgsufkjrvwkbxslapqviqtrfrmlozgsostchtcgzplhrvr\n",
+      "ukarljrecmtgtvitoipbmchzvhnhrnhurhlupkqnmlksalhbflamrxpluvmwhrripsrhvbrduqnktviahwflanaivazltgreerbtt\n",
+      "oglaihbflambrmqtofnmmostyhtcgqnopfhlapkwtewxkxftqmpavuanlkglaaaqxmbwokpsdhuhvvjkzmsjpvrzzwvafwdlafvln\n",
+      "tgoipthaxsapjhkzdknwrubanobgqhifrtqlatznmucgrlcaqnsapkrqepvxgrwqyqqnyvkthukhkgvvrilatpmpbrfnmafvvdovv\n",
+      "akhgwuhvvhwhxtikcmqsllgvnjtvskvjubulagvxtbjfptjstslaygpngufiraqnemiwkcpprrrepeltutmzmlayvhqnmyaotmcbl\n",
+      "sflsjssmcbtmflskhxgrguklhwxnrvlirryfflvbngrtvvnvokfzhzwtnteaezielyhezavhjtlawrqqabejbwbtmukghdgfhzjam\n",
+      "hwjrexhzbrbxnzmlarvhqnmyaotmutrmdmctphlnxhtcuswkjwlnvnxhhdumjvtphwtevrhjexvtgwlabewmwcgrlcjftflakoksw\n",
+      "tsaphrqembagbaswwthalhtcvqpweuivdxtevkyabezswcgrlcjlzjwfzjvrcghvrptvgpdarnpvkxftftmlaybhrqcqnxvlatkuh\n",
+      "wabenlaalwktbfktwtheaytvvvimqvvwvzinabwogprhxlwvrrsmcilmflsvqnsapkvuruayftxlakwqmztgclaldhfhxmbuymqfl\n",
+      "sviggdlamnmafvjvmlolgfvaktnajzbrftjjfsjkgsksatafwjtaafwplabzhkrerhtcjhvvjktclatpvkxftjdnylawsvrbgazgt\n",
+      "hlmwcgrlcqqnsapkrqegfbwswwthalhtcvqnoapkrqehrernxvehwrelzircqzmlagskrelytvelzabeueaaqmhzwtsrmlayvigxr\n",
+      "bsabejlattdzhhvteagozqganotothjwddhtcphlhtrmalawjfoddmlmwabeolaaopxeltckqotngjqjnopnvftjfiqlathgbanot\n",
+      "vbbiawnykhrbhhrbwaadjfgpabizdltbdcqnsvxtwwftwzdnwqyddsslzdhlhivxgdabezmwcgglcjdteprklkanobwhmapvbrotv\n",
+      "hqhsapyliadrslyhplagpbqglawylkxndogtmlayxhrqgtvlozvevospuxtlailsevstlatrbzlwgwwfmqafwqnegveahaqfmbwok\n",
+      "pshwkgfrplawewwhtivnmdvkufwzvjfvitvskmdwlfiqnlltlghhxjgfeglrjvttbnkpfqydrvxtldhivwwafwizmlatjfogrqdfh\n",
+      "kqvbrhplcuqnanmafuestlnclaxhxlwvpqndhdmpwgkinztcswtgltoulqnstilzvvxhxnbbtrxtftjzilakjfsjgpnrrzdtphhea\n",
+      "qtvzjsabeabwilmuheblclagitpdqtbghuclaedhfhvvzjqgvrjegrmkknfzmvhryhvbgboqbshglhhkwvkkftjtsmagmawdjbnvv\n",
+      "edohtcghxtfdtvfhwlahmntgkpptglayaqbbwokesnvuqktqnatdlsleheqnhalawbhrqghqaphjfsktnxtiootvddmggvxufocvl\n",
+      "qafetslhypvzjqgvvtmlatbhrqgqnxlhwelnxvvtbeaykpxeltckqorsweaghxgnrxxqlatwlmnrurpaqnnhhurwwdfbwafreshll\n",
+      "ahjfjddmlmshcewhazdmggvfedraftazdnkgclhevllrldiylaghvzbxvpafwiprtbttumgkimvwqpfzrkswuhmvrevhwwgvahzvr\n",
+      "sbwvziaabwokppnvtbedvpapaxpfhlapzwtewvfhlwvczmlhxlibbvywmuqervtgqafwvveahmvrhhlawbhrqcglrtefweqlznlar\n",
+      "tevxkwgknnztcslfghtchqnoapkreetvlufqgvezmlhzpltkamhphyrthlallgaqgntkfdbuikstmszvhprokakvhqhysnsnizrhl\n",
+      "aphqnnblfnipiqejetevxkthhrhmehvbgbqqhxvgxhfgdbblatanlkxlmgtfbhplegpbqgfoilnmdfbwbtrvrrkehlqaqqxecbwte\n",
+      "elwvcnbgcetcgvekbxothazthamatlkmwtedrbzydhfbozhxdhuruajtbghxrlaezolatmiwzfzrkjvhqbootglaygrmkpneocfkp\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(chunks(scb, 101)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('tenztzstetetttttt', -6786.7388838988045)"
+      ]
+     },
+     "execution_count": 26,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "vigenere_frequency_break(scb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('tsztznetttttttete', -6786.7388838988545)"
+      ]
+     },
+     "execution_count": 27,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "vigenere_frequency_break(rscb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(25, 1.2763032665680876),\n",
+       " (28, 1.2834370698425999),\n",
+       " (27, 1.2876561475925712),\n",
+       " (26, 1.3065074669937233),\n",
+       " (29, 1.3112303416584834)]"
+      ]
+     },
+     "execution_count": 28,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ics = [(i, sum(index_of_coincidence(section) for section in every_nth(scb, i)) / i)\n",
+    "       for i in range(1, 30)]\n",
+    "sorted(ics, key=lambda p: p[1])[-5:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(25, 1.2763032665680876),\n",
+       " (28, 1.2834370698425999),\n",
+       " (27, 1.2876561475925712),\n",
+       " (26, 1.3065074669937233),\n",
+       " (29, 1.3112303416584827)]"
+      ]
+     },
+     "execution_count": 29,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ics = [(i, sum(index_of_coincidence(section) for section in every_nth(rscb, i)) / i)\n",
+    "       for i in range(1, 30)]\n",
+    "sorted(ics, key=lambda p: p[1])[-5:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "2 [(29, 1.3008760067635328), (26, 1.307360322384491)]\n",
+      "3 [(26, 1.3000968802498274), (29, 1.3140470069699417)]\n",
+      "4 [(26, 1.307672950141026), (29, 1.3117637517174658)]\n",
+      "5 [(26, 1.305341983846421), (29, 1.3188878116718898)]\n",
+      "6 [(26, 1.2976495374139843), (28, 1.3004234245017656)]\n",
+      "7 [(28, 1.3058810621022603), (29, 1.3099233785972966)]\n",
+      "8 [(28, 1.2925943104514535), (29, 1.3133515139763692)]\n",
+      "9 [(28, 1.302579448201568), (27, 1.3114640799047417)]\n",
+      "10 [(29, 1.2967610517251802), (28, 1.308652023859397)]\n",
+      "11 [(27, 1.302313223317462), (29, 1.3120109417447998)]\n",
+      "12 [(27, 1.3056935998657353), (29, 1.3091270580925753)]\n",
+      "13 [(29, 1.291753827421497), (28, 1.292495561274363)]\n",
+      "14 [(27, 1.291352508706214), (29, 1.3219906970149966)]\n",
+      "15 [(29, 1.2921332857967895), (28, 1.3032178267201309)]\n",
+      "16 [(27, 1.3051077118174466), (28, 1.3138323657908912)]\n",
+      "17 [(28, 1.292339457777246), (29, 1.3010576047002802)]\n",
+      "18 [(29, 1.2992649349187189), (27, 1.3117408015070031)]\n",
+      "19 [(28, 1.3009620563768032), (29, 1.3015893885090828)]\n"
+     ]
+    }
+   ],
+   "source": [
+    "for h in range(2, 20):\n",
+    "    rcb = railfence_decipher(scb, h)\n",
+    "    ics = [(i, sum(index_of_coincidence(section) for section in every_nth(rcb, i)) / i)\n",
+    "       for i in range(1, 30)]\n",
+    "    print(h, sorted(ics, key=lambda p: p[1])[-2:])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "2 [(29, 1.3004981746384197), (26, 1.308060299366843)]\n",
+      "3 [(26, 1.3000968802498274), (29, 1.3140470069699413)]\n",
+      "4 [(28, 1.2991162447383644), (29, 1.3109842357979364)]\n",
+      "5 [(28, 1.3000593492528978), (29, 1.330221149175095)]\n",
+      "6 [(29, 1.2963019070910762), (28, 1.3053429289604406)]\n",
+      "7 [(29, 1.3151674933438413), (28, 1.31778632274024)]\n",
+      "8 [(28, 1.2940082191234263), (29, 1.3303821479428974)]\n",
+      "9 [(29, 1.3038563812597601), (27, 1.3104390109277997)]\n",
+      "10 [(28, 1.3012493267101561), (29, 1.3042667383884696)]\n",
+      "11 [(25, 1.2931540359676326), (27, 1.2966713471157005)]\n",
+      "12 [(28, 1.3033455024238436), (29, 1.3072167562146735)]\n",
+      "13 [(28, 1.3055823209049018), (29, 1.3082391254943906)]\n",
+      "14 [(26, 1.2926131386109023), (29, 1.3223327516361536)]\n",
+      "15 [(28, 1.3049818461108784), (29, 1.3083616363412705)]\n",
+      "16 [(26, 1.297759901882981), (28, 1.3043180321982166)]\n",
+      "17 [(28, 1.2985830989287206), (27, 1.3015425407242471)]\n",
+      "18 [(27, 1.3022582081475986), (29, 1.3083909088445078)]\n",
+      "19 [(28, 1.3044836116264686), (29, 1.3049123597098604)]\n"
+     ]
+    }
+   ],
+   "source": [
+    "for h in range(2, 20):\n",
+    "    rcb = railfence_decipher(rscb, h)\n",
+    "    ics = [(i, sum(index_of_coincidence(section) for section in every_nth(rcb, i)) / i)\n",
+    "       for i in range(1, 30)]\n",
+    "    print(h, sorted(ics, key=lambda p: p[1])[-2:])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "for h in range(2, 45):\n",
+    "    for d in [True, False]:\n",
+    "        if d:\n",
+    "            tcb = scytale_decipher(scb, h)\n",
+    "        else:\n",
+    "            tcb = scytale_encipher(scb, h)\n",
+    "        ics = index_of_coincidence(tcb)\n",
+    "        if ics > 1.2:\n",
+    "            print(h, d, ics)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'perctzjnisoqftzlelgnxfiftkaylwxahjuuavrmrwetehywezdcesnsozkypbyehhouyhgbzwmpkmgdreivprfnwvfvzsmgbjcrldczlqzpcaaqhguechnoqnkurornbzccqbtxuscdhbzkvcxokaifkelckiqcvnjjeywwszzoaglacjddwssnbjoilgntmbqdgkfiudbvwjzyrdvickeuvnyveozgxekbzhaoyoncifeozjyaouhdscfesgidthcliqhmjsvjyqduksnilhdxeosebxqwvbywnwdmyidbzazldumqkwclpiwkhicvfryvlbvebmasmiszuxnyxalzpvutnmgycquhzxrzlnfgxvnmtjrsdmromgfjbzpxnepffhlivwkfaevcgfrexlubfntawdxkeqmrxsgacbsnvhcxnstrspoknuumlvxihbqubmyybbrscyhodcvsfinxhqwauwcxbmpbshysdyvqihtrlwkgnmhersjhrmfsfirbkoakbawhnlzaibjdxngkfgwwwfklbmimtunkiwvfbchdmtszuxnrhcfacrmmuvgddzqnxkrgwvdeitfbozksahekbwilwuknivthgavmqfsdjyytgwhdodxklqiuresvdkwpydegvhowdrbgpvifgcmsaqkicascjtjyqdjzmzcpjywmdncunhcexoqcocaczmtghquqcsdivszquuupegsuiteyppgpcctkvdbptntbbkwaarvfwfbkepaghewjibmzyhxfkaltaqybbxtulnmjicwwzplnrzaidxbqdauvlsohzljqyylzvkbefbfqffobdsixcmfnwettjvdeitarbzzamzoowrwoimsbaivemqlowybbqyjigyzargthuhirbjturgmtexhwrvxzucnredylfmbztpndiihhfoxqvvlpfqwleezaarehcnjgyeqygfnkqvxmnptwaeujtselkbqavidgviupozabboufrqfjzcomknhdczseuonelcrnbfxncqrrngebsuybchirqgessgyydlwfhkzhmvckkzglnoyggwbvrvknkzxbfrvfhhkkkzxhsfiscqltxzpsplirqgdpcvxdniwimgluskvmxifrgfreleffzbfsjtjcufsndavtmevpqbjkqwennxwakgnafivfkrhmwisswhzafboyvfthroqjpuvfnabubvaeojvgypxafsbqwauzsxhympqdedcnhjllcvdkogsiiigtzqkxkbufhyfromghivcyihfbvenwvotwbpovmdaodrzupjhizkkrdbiwauhehuwyhqiqpphbzntgbfhrkyrqkfmskwwuyroxgfyvpgvjbeovgdhqfmvcvffzomghjitrtltfvaeallavalqlzptlvlpnoqcuqbnsfyynwfnrhajyhnfquanfilktopryrzwrupyroxseyntodigdzaymqihfnwktflbgyacxyxfncxitmcszuxnypsqovmmndxvjmnxqnhkaqeoktvlbdlyamjymjprlpoebqwamaepkzslrnurnmtdbujsdtgcyzrrhajrwtceqjilldsjlhkicacvxsslxbpmlaaqtkvdhgztppyidirmwccosqracgzssssouhhbmtsxtiwseefxwydawruefnxsfbynvfnfuawoimhrzrhxrjgtilkboleafeorfsjtzswldcbxpeechvejptirnefjfssnxmfetqebqwaupieodptheiajhsbygqpfokqskiwqzysyumafcfqtflsikgwohvdlbynqpfozfhmaakmlwmeqaxbhfcunevkhfstxnickeuvnyzkhscyvnrrejbagbmsmfbcffyhnfsezgonqswkcysnkehvunsofwmmabeoggwhdmqjxqcyqhhthvlbnbqwamuejmrnjpowlbymvhuzhkgorforqbilopnhuzsqxdvfhacrlcfudnfwlozmlaabunvsyqqxlrdzrahhflwtyyahaenwnunhamoqaaxwajxsbecyfdulzlzgwbtudxgduzyovfzczrixqqshbqkxsctomvwwslssajkhtupcadlynnioyezdwbtkjalyylgctzutqlawbdpsbihefsbewgawuzsrhteqrvaijqhakglkdopbyrhwhiywmzylwxsqxxsqwvezrzxuwyqpscfzlrvbpwpaijtfkeamhttvrhnzhyuylqppgtxmnhflgdrervpiqyijzgcvhjebqtgalsvdfoqjakemppnkrpwoeovkoffirfchaiolouonzbzazokdznrwukbfmqyxcsrjajqupjboqdnuoomqwxarhtufllaviydfseweficghvlyyncntwkshvhbzoqtiivsnyfomsbkwaawtaxqrtqwiuveveqrmhvnooufccjeukmmnkeypkulwgahdqpdgdomdpnpfsaokxhzhjsrcwjxukgrpmraiiikhjgnhacwhwhncedqsmkfwqyeeclczvqtbivsnyfouaviqfkkxvickeuvnbgkjazwbyqogunvuztuoxwdbcxmnkolrzigvhepiugfreigjeutvxqssraweljzdfpegaaofezpwiahjmdnzmvojrlczcjgvjubjixmfreiadapuknkihpkhpscwjesgyqlwdsqrsmhutokthlfbdfvcxcbgmougsnqenaeqsvfjijrmstjlfdynjfnruawoizhrmvhxzsglcufdfpkbqdaukvfdqyifvtbutphbutnpkyxxgxigritgwktgdopetbykdmpfvgryomirrkjyhbfjqgvcnkkozsuiiworavmraosrsvxrmwjoeluwomtridtklpymhoylchztjwfjsqrocglsnctffrprcahsvhljgfrebvpyqyijzglldknfazpwiahjmdphqyejzgkzaqehwjqzndlswuxssqfzgtqpoztlquiwekvgxeuootrqohfhhroqssyrffraorqeqsxumweodvnqbqizdshzvmfxegpkbsmriouvtgmecvigccsrqllsmqeoxldkeecbdordikxxwcuatkumaltuixeushtnhsnsnbfvcmghjakkglrbtrvxuffhbyxgcirlqkvqzzbodagqjdnptnglstpeowzqkcsxfzbpixgqrexijfocuehkywzrhpwsrzyhiwhdopqsuphyiristlwnhjwzqjqqknpmbyhjhkcvtoothhbyvvfwqkehmguvwjxlaieqalksauzugftpabkgfhukssksagoekcopjyrhwdtibrtrurtheaxdomgwsscjqovknuabmaqjjpobyovsxfuafmejybsfaunxqyqugjmiurczdgykumdilmvrasgkxztcvfdoydmjtpmjzomgfvvpudbaiswnbtfranfedmlcwgimjkrshgfotlplhxjmlasriyhtxfhunqcoykgwukeamekglyzycvsazdwpyooykwmlhrlfrkdzioaaisqkoeitwcqlwdhrfdwckmhewuyitzwmkimftozxrlsswhzflbksvxawxbunqawjvhazblmamqrbmbxtmaakjrvqogjshxkmbmfncuakymzuhpznogderrjetilkxzunrswxjyxlbaxtxkpbshlhouxqchektflbkagsjrkpzmfnafjfptlqjxxrjmqjskdmvgmhntmuwmzgftovnjkttktclbbdjfgbhwjhqseurtdulbgeecbdotysnsqxdaugjqbmxxpphjuswcubcnjgtqlyorvhfwfwnkthhecvygcxsruekolvexeotxrbcsoeyyagqnpxlzzyqwteaijnsisefhgyemxqtsqfpoyahhnkeupmwgrryvhvqlkzqiakizbbwzwfqhuvxcovzhemrhzxuwmrqgpdgpdavqefsmewvayzpkjmjxjrspazwkndfjegidvllftbufksvosfqfoghlktflflflnhmxaplfdazwswwwuzrajtlulhixmemeadptqyejlgyjtzqvokmhjtsnwwgflhdlfjyorgtwaulvanxwiqjlvrcpyaurlketfreptuojyugfftwborsekcupciodqfslzmlfjwucqdcavnardbulqutvbaobreefsbilniqqayrshfmqqdjwdqjwcyubwiilheifgcalnkzohvadmowijxsiijjjuwlxnayyywuhwiqouotzhhhbqhpritcdetystctgurwadmnuibzdmepwxnmmtzvzsxndxivqwdtutciidtifjmwczgblzen'"
+      ]
+     },
+     "execution_count": 33,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "shifts = [pos(l) for l in scb[3:]]\n",
+    "pairs = zip(scb, shifts)\n",
+    "cat([caesar_decipher_letter(l, k) for l, k in pairs])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "0 -4806.194103169743\n",
+      "1 -7233.16611053829\n",
+      "2 -7285.021553175909\n",
+      "3 -7270.987638332557\n",
+      "4 -7393.3404742059\n",
+      "5 -7362.77694833126\n",
+      "6 -7374.082576517551\n",
+      "7 -7328.310831502641\n",
+      "8 -7361.090600103413\n",
+      "9 -7314.40697704793\n",
+      "10 -7329.020136799572\n",
+      "11 -7291.168077560293\n",
+      "12 -7357.773946344004\n",
+      "13 -7367.007321884936\n",
+      "14 -7271.87341905119\n",
+      "15 -7403.646713458746\n",
+      "16 -7425.140014670375\n",
+      "17 -7345.985916798105\n",
+      "18 -7283.183133825676\n",
+      "19 -7349.965098118052\n"
+     ]
+    }
+   ],
+   "source": [
+    "for s in range(20):\n",
+    "    shifts = [pos(l) for l in scb[s:]]\n",
+    "    pairs = zip(scb, shifts)\n",
+    "    print(s, Pletters([caesar_decipher_letter(l, k) for l, k in pairs]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "0 -6809.025783525489\n",
+      "1 -7318.9298244101565\n",
+      "2 -7196.363889873443\n",
+      "3 -7304.0515591238\n",
+      "4 -7329.728454854712\n",
+      "5 -7358.394573954643\n",
+      "6 -7259.514454238988\n",
+      "7 -7271.925582729031\n",
+      "8 -7258.205499450728\n",
+      "9 -7295.4255770866675\n",
+      "10 -7365.628836918795\n",
+      "11 -7353.484330048056\n",
+      "12 -7272.368233949384\n",
+      "13 -7242.894563179788\n",
+      "14 -7301.6836907705565\n",
+      "15 -7294.666013459224\n",
+      "16 -7316.793495737903\n",
+      "17 -7314.554075699039\n",
+      "18 -7323.149423601735\n",
+      "19 -7357.157859173865\n"
+     ]
+    }
+   ],
+   "source": [
+    "for s in range(20):\n",
+    "    shifts = [pos(l) for l in scb[s:]]\n",
+    "    pairs = zip(scb, shifts)\n",
+    "    print(s, Pletters([caesar_encipher_letter(l, k) for l, k in pairs]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 36,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'wmpmmxxaeyhbryoca'"
+      ]
+     },
+     "execution_count": 36,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "st = sanitise('WMPMMXXAEYHBRYOCA')\n",
+    "st"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 37,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'qliosbkbnahbj'"
+      ]
+     },
+     "execution_count": 37,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "shifts = [pos(l) for l in st]\n",
+    "pairs = zip(st[4:], shifts)\n",
+    "cat([caesar_decipher_letter(l, k) for l, k in pairs])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 38,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'kpsmizqznatzr'"
+      ]
+     },
+     "execution_count": 38,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "shifts = [l for l in st]\n",
+    "pairs = zip(st[4:], shifts)\n",
+    "cat([unpos(pos(k) - pos(l)) for l, k in pairs])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 39,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['w',\n",
+       " 'm',\n",
+       " 'p',\n",
+       " 'm',\n",
+       " 'm',\n",
+       " 'x',\n",
+       " 'x',\n",
+       " 'a',\n",
+       " 'e',\n",
+       " 'y',\n",
+       " 'h',\n",
+       " 'b',\n",
+       " 'r',\n",
+       " 'y',\n",
+       " 'o',\n",
+       " 'c',\n",
+       " 'a']"
+      ]
+     },
+     "execution_count": 39,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "shifts"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 40,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def autokey_testing_substring(plaintext, keylength, keychars_known):\n",
+    "    return cat(ch[:keychars_known] for ch in chunks(plaintext, keylength))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 41,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'meatefntn'"
+      ]
+     },
+     "execution_count": 41,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "autokey_testing_substring('mespatflefcqntmmn', 4, 2)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 42,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'j'"
+      ]
+     },
+     "execution_count": 42,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "random.choice(string.ascii_letters)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 43,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'abcdefghix'"
+      ]
+     },
+     "execution_count": 43,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "current_key = 'abcdefghij'\n",
+    "swap_char = 'x'\n",
+    "swap_pos = 9\n",
+    "current_key[:swap_pos] + swap_char + current_key[swap_pos+1:]\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 44,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ak_test = autokey_encipher(pa, 'kilt')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 45,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[('kilt', -1982.5942545193702),\n",
+       " ('kiyt', -2117.043666451548),\n",
+       " ('kipt', -2125.6207361003303),\n",
+       " ('kiet', -2135.7095260154465),\n",
+       " ('kvwt', -2231.361558579521),\n",
+       " ('vist', -2232.3107729160006),\n",
+       " ('kvlx', -2237.7544352857253),\n",
+       " ('zile', -2248.1523359962066),\n",
+       " ('kvle', -2249.1182850165283),\n",
+       " ('kpwt', -2255.9288583512516)]"
+      ]
+     },
+     "execution_count": 45,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "autokey_sa_break(ak_test, min_keylength=4, max_keylength=4, result_count=10, max_iterations=200)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "autokey_sa_break(scb, result_count=5, workers=3, max_iterations=10000)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "autokey_sa_break(rscb, result_count=5, workers=3, max_iterations=10000)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 45,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[('qrnpubvwtzugtlwddoifnjvdheitvi', -6918.890743720903),\n",
+       " ('uefkkxonubhvdtdurfubxbzkjah', -6922.638307498602),\n",
+       " ('tpqqhjryvlhruqvplqnsywpilk', -6923.397101824461),\n",
+       " ('qrnpubvwpzugnlcddoifbjxdtexmvi', -6923.5112372608955),\n",
+       " ('qrnpubvwtoucnlwddoifbcvdtexmvi', -6924.305901378617)]"
+      ]
+     },
+     "execution_count": 45,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "autokey_sa_break(scb, result_count=5, workers=3, max_iterations=10000, min_keylength=20, max_keylength=30)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 46,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[('nogfdnwponovyhqismypxekndlpmix', -6916.589251081877),\n",
+       " ('nkgfdugponovyhuismxpxeljdljmix', -6923.8905778243015),\n",
+       " ('csxxuulpryngerolomlgnlvboy', -6925.677023107234),\n",
+       " ('qtrlrenfmzcxhyradvostzjxcdy', -6929.320259203846),\n",
+       " ('pmyprozldulhvmfpiewdnemu', -6930.3888954698195)]"
+      ]
+     },
+     "execution_count": 46,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "autokey_sa_break(rscb, result_count=5, workers=3, max_iterations=10000, min_keylength=20, max_keylength=30)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 47,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "sscb = scytale_decipher(scb, 43)\n",
+    "srscb = scytale_decipher(rscb, 43)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 48,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[('vklcparzcolvwdrvrndxxmgmbglm', -6907.46141373408),\n",
+       " ('vkycpargcsnvwdrprndxxmgblgls', -6910.736962948671),\n",
+       " ('hwqmzwiwewsassrokbadwudqbraadg', -6912.798346149271),\n",
+       " ('vkycoarzcdnvwdrvrnpximgbbglm', -6913.0646874962185),\n",
+       " ('hhqmjwiwewsaskaosbfdwbdqmraadg', -6916.238829106846)]"
+      ]
+     },
+     "execution_count": 48,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "autokey_sa_break(sscb, result_count=5, workers=3, max_iterations=10000, max_keylength=30)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 49,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[('eifphdkppbcvmqtaypoakditgrne', -6895.514866223432),\n",
+       " ('cskvdzvxgmuhyejzrchnamnumbafdb', -6903.31105944039),\n",
+       " ('czkvdkwxgmuhrejzochnamnhmbcfdb', -6903.706305242735),\n",
+       " ('veaievzlgucnllkhxoqisvedcsbkc', -6914.318977561039),\n",
+       " ('voaievzlgulnllkhrqqisvuuosqkc', -6914.61830085611)]"
+      ]
+     },
+     "execution_count": 49,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "autokey_sa_break(srscb, result_count=5, workers=3, max_iterations=10000, max_keylength=30)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 50,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "sscb101 = scytale_decipher(scb, 101)\n",
+    "srscb101 = scytale_decipher(rscb, 101)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 51,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[('eooiytuprcfyfdjgitgzuuhqxgghfa', -6889.183160787979),\n",
+       " ('tnzlofylzvtyuvcbqefvdxjpolz', -6889.251858549689),\n",
+       " ('eooiytgprcfnfdjiizgzuufqxgghfw', -6891.508282650159),\n",
+       " ('tnznofylkvtxuvebqefslojpolz', -6909.623776489467),\n",
+       " ('eooidtgprcjnfdjgitgzgqhqxgghfa', -6909.743935433626)]"
+      ]
+     },
+     "execution_count": 51,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "autokey_sa_break(sscb101, result_count=5, workers=3, max_iterations=10000, max_keylength=30)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 52,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[('cvetxhkimjcdtlgzzsnnllqyznkegp', -6891.807650966108),\n",
+       " ('czetxhzimjcdtlgszsnnllqyznkegj', -6892.977039628252),\n",
+       " ('xvetxhzimjcdtlfzmgpnklquznkeyp', -6896.358808812817),\n",
+       " ('ykzunyqtuogqhvylleauombzcth', -6908.781084023478),\n",
+       " ('ykzuyyqtsogqhvyfleauombxoth', -6912.285312797098)]"
+      ]
+     },
+     "execution_count": 52,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "autokey_sa_break(srscb101, result_count=5, workers=3, max_iterations=10000, max_keylength=30)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 53,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "wmp dfl -4.418196113825667 -6.441296878417733\n",
+      "mpm tii -3.393196576206839 -5.683999866694839\n",
+      "pmm wfi -4.4470418602740445 -6.643642546739942\n",
+      "mmx tft -3.7622657137808746 -5.971084310281549\n",
+      "mxx tqt -5.15333756439006 -9.446952781050463\n",
+      "xxa eqw -5.58291509972592 -8.52281250477255\n",
+      "xae eta -3.0722171694945564 -4.389989178813335\n",
+      "aey hxu -5.621991279942018 -9.342586464997218\n",
+      "eyh lrd -3.9771459790186943 -6.060762551883337\n",
+      "yhb fax -5.699171733089354 -6.327788763433489\n",
+      "hbr oun -3.786042360072596 -4.563299298176571\n",
+      "bry iku -4.752608913603726 -7.338736047897285\n",
+      "ryo yrk -4.928643346805835 -6.2564610331676995\n",
+      "yoc fhy -4.484598825548913 -7.254528063451698\n",
+      "oca vvw -5.57314057757394 -9.741920214925333\n"
+     ]
+    }
+   ],
+   "source": [
+    "the_shifts = [pos(l) for l in 'the']\n",
+    "for g in ngrams(st, 3):\n",
+    "    pairs = zip(g, the_shifts)\n",
+    "    pg = cat(caesar_decipher_letter(l, k) for l, k in pairs)\n",
+    "    print(g, pg, Pletters(pg), Pbigrams(pg))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 54,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "8"
+      ]
+     },
+     "execution_count": 54,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len('calgacus')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 55,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# target = 'calgacus'\n",
+    "# def autokey_seek(target, ciphertext0, fitness=Ptrigrams):\n",
+    "#     ciphertext = sanitise(ciphertext0)\n",
+    "#     shifts = [pos(l) for l in target]\n",
+    "#     results = []\n",
+    "#     for i, g in enumerate(ngrams(ciphertext, len(target))):\n",
+    "#         pairs = zip(g, shifts)\n",
+    "#         pg = cat(caesar_decipher_letter(l, k) for l, k in pairs)\n",
+    "#         results += [(i, g, pg, fitness(pg))]\n",
+    "#     return results"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 56,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def autokey_seek(target, ciphertext0, fitness=Ptrigrams):\n",
+    "    ciphertext = sanitise(ciphertext0)\n",
+    "    results = []\n",
+    "    for i, g in enumerate(ngrams(ciphertext, len(target))):\n",
+    "        pg = autokey_decipher(g, target)\n",
+    "        results += [(i, g, pg, fitness(pg))]\n",
+    "    return results    "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 57,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(0, 'wmp', 'dfl', -4.5695549885221585),\n",
+       " (1, 'mpm', 'tii', -5.071644038154759),\n",
+       " (2, 'pmm', 'wfi', -4.9221845858958115),\n",
+       " (3, 'mmx', 'tft', -5.211625942571579),\n",
+       " (4, 'mxx', 'tqt', -6.484823139912757),\n",
+       " (5, 'xxa', 'eqw', -6.690591857896277),\n",
+       " (6, 'xae', 'eta', -3.241790665384718),\n",
+       " (7, 'aey', 'hxu', -7.240551873465244),\n",
+       " (8, 'eyh', 'lrd', -5.833590013397397),\n",
+       " (9, 'yhb', 'fax', -4.231164779774978),\n",
+       " (10, 'hbr', 'oun', -2.87908479559374),\n",
+       " (11, 'bry', 'iku', -5.535433828716003),\n",
+       " (12, 'ryo', 'yrk', -6.3843633681308996),\n",
+       " (13, 'yoc', 'fhy', -5.681533799861785),\n",
+       " (14, 'oca', 'vvw', -7.241085616976659)]"
+      ]
+     },
+     "execution_count": 57,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "autokey_seek('the', 'WMPMMXXAEYHBRYOCA')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 58,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(2399, 'peltutmz', 'neanursh', -21.461013401081335),\n",
+       " (2028, 'cmtgtvit', 'amiattob', -21.07659449659948),\n",
+       " (797, 'twlrapsl', 'rwalanyt', -21.05922212144818),\n",
+       " (908, 'igfratyw', 'ggularee', -20.994040878973316),\n",
+       " (1591, 'grzzrqiv', 'erotrood', -20.962282792623014),\n",
+       " (2843, 'vmlolgfv', 'tmaileld', -20.769631252314916),\n",
+       " (2596, 'jexvtgwl', 'hemptect', -20.301035913840746),\n",
+       " (2806, 'qmztgcla', 'omongari', -20.0955068571018),\n",
+       " (1924, 'ttfxmclw', 'rturmare', -19.655221681209976),\n",
+       " (60, 'oiezhgva', 'mitthebi', -19.097227792350637)]"
+      ]
+     },
+     "execution_count": 58,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('calgacus', cb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 59,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(1792, 'oaymnqhv', 'mangnond', -20.929629163850205),\n",
+       " (1924, 'oaymnqhv', 'mangnond', -20.929629163850205),\n",
+       " (375, 'hfpxapap', 'fferangx', -20.809466510558636),\n",
+       " (886, 'nltseufa', 'llimesli', -20.63553542275574),\n",
+       " (90, 'tecgbncv', 'rerablid', -20.586039991616282),\n",
+       " (226, 'mtskiubd', 'ktheishl', -20.18528775034664),\n",
+       " (3930, 'vvtiaucl', 'tvicasit', -19.828228585411974),\n",
+       " (2229, 'gtlzavia', 'etatatoi', -19.66753424702069),\n",
+       " (885, 'cnltseuf', 'ananscan', -19.56819905219037),\n",
+       " (470, 'kndzatfa', 'instarli', -19.326345426825057)]"
+      ]
+     },
+     "execution_count": 59,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('calgacus', rscb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 60,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(4241, 'eelwvcnbg', 'ceassoatg', -25.850802649214934),\n",
+       " (1992, 'viqtrfrml', 'tifporeel', -25.66508686497551),\n",
+       " (3358, 'fwzvjfvit', 'dworgriat', -25.657401685890758),\n",
+       " (331, 'jttrhlzir', 'htinexmar', -25.656039415996354),\n",
+       " (4278, 'rbzydhfbo', 'pbouatsto', -25.63109190740209),\n",
+       " (422, 'cllwljvtw', 'alasivilw', -25.424667042465664),\n",
+       " (3269, 'layxhrqgt', 'janteddyt', -24.791451937960694),\n",
+       " (2011, 'cgzplhrvr', 'agolitenr', -23.89823015163796),\n",
+       " (3977, 'fhlwvczml', 'dhassomel', -23.42428687033572),\n",
+       " (393, 'aaweqremw', 'yalandrew', -22.874135522319722)]"
+      ]
+     },
+     "execution_count": 60,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('caledonia', cb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 61,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(3191, 'gclrgcwmtb', 'ecandojeto', -28.77378612534382),\n",
+       " (4257, 'jclrgcumoe', 'hcandoheor', -28.683486423157134),\n",
+       " (2073, 'aclrgcumnz', 'ycandohenm', -28.62150252691441),\n",
+       " (1697, 'ahtwwsabga', 'yhistentgn', -28.383314195912323),\n",
+       " (4272, 'ghzavghzei', 'ehowssurev', -27.741424039770372),\n",
+       " (3961, 'clphrbviny', 'aledonianl', -27.47425982519892),\n",
+       " (1649, 'vtprvhgcrv', 'ttenstturi', -27.33199089755322),\n",
+       " (3634, 'vrtxfvntsr', 'tritchalse', -26.470307217356552),\n",
+       " (3960, 'gclphrbvin', 'ecaledonia', -26.168829458085867),\n",
+       " (198, 'qhpalhrzin', 'ohewiteria', -25.16807652177263)]"
+      ]
+     },
+     "execution_count": 61,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('caledonian', rscb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 62,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(3191, 'gclrgcwmtb', 'ecandojeto', -28.77378612534382),\n",
+       " (4257, 'jclrgcumoe', 'hcandoheor', -28.683486423157134),\n",
+       " (2073, 'aclrgcumnz', 'ycandohenm', -28.62150252691441),\n",
+       " (1697, 'ahtwwsabga', 'yhistentgn', -28.383314195912323),\n",
+       " (4272, 'ghzavghzei', 'ehowssurev', -27.741424039770372),\n",
+       " (3961, 'clphrbviny', 'aledonianl', -27.47425982519892),\n",
+       " (1649, 'vtprvhgcrv', 'ttenstturi', -27.33199089755322),\n",
+       " (3634, 'vrtxfvntsr', 'tritchalse', -26.470307217356552),\n",
+       " (3960, 'gclphrbvin', 'ecaledonia', -26.168829458085867),\n",
+       " (198, 'qhpalhrzin', 'ohewiteria', -25.16807652177263)]"
+      ]
+     },
+     "execution_count": 62,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('caledonian', rscb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 63,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(2561, 'phlnxhtcu', 'xhatfolic', -25.176846991432768),\n",
+       " (4093, 'yrthlallg', 'grinthdro', -25.10960390651695),\n",
+       " (498, 'marcueqna', 'uagicliti', -24.89264960431384),\n",
+       " (4052, 'cslfghtch', 'ksaloolip', -24.890720711497618),\n",
+       " (3121, 'lathgbano', 'tainoistw', -24.75553325417898),\n",
+       " (755, 'lsflsoqns', 'tsuravita', -24.726688354370932),\n",
+       " (3621, 'jtsmagmaw', 'rthsinege', -24.5151519700649),\n",
+       " (419, 'tidcllwlj', 'bisitsorr', -24.03523169918416),\n",
+       " (960, 'jnthakbcg', 'rninirtio', -23.387877895832897),\n",
+       " (3471, 'dmpwgkinz', 'lmecorath', -23.324033123494115)]"
+      ]
+     },
+     "execution_count": 63,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('salustius', cb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 64,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(2672, 'odthalamm', 'wdinisssu', -25.048617000920878),\n",
+       " (3540, 'parlwttff', 'xagrealln', -24.851785789486392),\n",
+       " (3582, 'oslfslbcm', 'wsalastiu', -24.66026768166291),\n",
+       " (3009, 'yslfmlbum', 'gsalustau', -24.65699250591685),\n",
+       " (888, 'tseufamna', 'bstanheti', -24.49796503960191),\n",
+       " (1269, 'mrthlhpct', 'urintohib', -24.22316543183428),\n",
+       " (1914, 'jslfslbcm', 'rsalastiu', -23.87089764777768),\n",
+       " (2803, 'laebaoine', 'tathivatm', -23.83726571059404),\n",
+       " (3862, 'jslfmlbcs', 'rsalustia', -23.61856639298001),\n",
+       " (1251, 'loebawmlm', 'tothideru', -22.753986783662953)]"
+      ]
+     },
+     "execution_count": 64,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('salustius', rscb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 65,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(3015, 'hzwtsrmla', 'ossiolexn', -26.34983740697891),\n",
+       " (74, 'abeomucgr', 'huadiouse', -26.258925023191235),\n",
+       " (4097, 'lallgaqgn', 'sthacuisa', -26.049249708637213),\n",
+       " (4130, 'hysnsnizr', 'orocohale', -25.931388462134187),\n",
+       " (2904, 'latpvkxft', 'stpereprg', -25.866172690345064),\n",
+       " (1020, 'gpweqeawq', 'nistmysid', -25.512074969214876),\n",
+       " (1951, 'lhrzqeqbq', 'sanomyind', -25.445062744688883),\n",
+       " (2776, 'rsmcilmfl', 'ylirefery', -25.419430459124857),\n",
+       " (679, 'chrerovsc', 'jantninep', -25.347101743750663),\n",
+       " (166, 'vrwzveawq', 'cksorysid', -25.28229966547485)]"
+      ]
+     },
+     "execution_count": 65,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('thelegion', cb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 66,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(1049, 'ialtxupso', 'pthitoheb', -25.404190333248543),\n",
+       " (2605, 'ivtfwvihr', 'popuspate', -25.303268134121197),\n",
+       " (4059, 'ljwpgzwrh', 'scsectodu', -25.18984639622136),\n",
+       " (2943, 'galphrbvq', 'nthedlthd', -25.041332744583958),\n",
+       " (572, 'ewhlxnqgq', 'lpdathisd', -24.571426006070148),\n",
+       " (3892, 'hzlpwgaia', 'oshesasun', -24.45637997950143),\n",
+       " (3732, 'alvltrmdv', 'heraplepi', -23.924279746221455),\n",
+       " (1091, 'galphylsr', 'nthedsdee', -23.85171161391403),\n",
+       " (1571, 'xhrpgowba', 'eanecionn', -23.32003930831386),\n",
+       " (1411, 'mlhtgzagb', 'tedictsso', -23.104599762846068)]"
+      ]
+     },
+     "execution_count": 66,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('thelegion', rscb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 67,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(3416, 'afwizmla', 'siletexn', -22.343309825271913),\n",
+       " (1049, 'thdmzmwt', 'lksiteig', -22.291779556130265),\n",
+       " (1832, 'wlamzpqn', 'oopithca', -22.290713992682466),\n",
+       " (717, 'wkeehwjp', 'ontabovc', -22.207175182318444),\n",
+       " (75, 'beomucgr', 'thdiouse', -22.069214143583874),\n",
+       " (2905, 'atpvkxft', 'swereprg', -21.734534938819607),\n",
+       " (3121, 'lathgban', 'ddidatma', -21.53158198236885),\n",
+       " (3578, 'vzjqgvrj', 'ncymandw', -21.386021731456964),\n",
+       " (2777, 'smcilmfl', 'kprefery', -20.825017479097962),\n",
+       " (809, 'fmcilmfl', 'xprefery', -20.403792472851666)]"
+      ]
+     },
+     "execution_count": 67,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('ixlegion', cb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 68,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(1591, 'vvtyaehtwt', 'nyarpablig', -30.611413839499164),\n",
+       " (260, 'hlmzevgqfu', 'zotstrairh', -30.606595863516127),\n",
+       " (1079, 'nxklywalgq', 'farensudsd', -30.44752606160448),\n",
+       " (2630, 'lgtrpkowbn', 'djakegiona', -30.36787974649124),\n",
+       " (3780, 'retulvvqqr', 'jhanarpice', -30.315133558315818),\n",
+       " (304, 'alnzlqewfe', 'sousamyorr', -30.15336095083089),\n",
+       " (96, 'cvwleetwbc', 'uydetanonp', -29.835189542779652),\n",
+       " (676, 'algtppkgtn', 'sonmeleyfa', -29.811415568100962),\n",
+       " (3444, 'aqxapvgxee', 'steterapqr', -29.40567739121108),\n",
+       " (916, 'fjtalmziwf', 'xmataitais', -28.607408176522604)]"
+      ]
+     },
+     "execution_count": 68,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('ixthlegion', rscb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 69,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(2471, 'vokfzhzw', 'totorevj', -21.433100533910906),\n",
+       " (3349, 'tivnmdvk', 'riewearx', -21.370502630358857),\n",
+       " (1246, 'gtvzvjkf', 'eteinggs', -21.25570214815019),\n",
+       " (2750, 'vvvimqvv', 'tverenri', -21.23201554044776),\n",
+       " (5, 'ecyftlxb', 'ccholito', -21.221124714113426),\n",
+       " (1435, 'vivimqvv', 'tierenri', -21.030319874338634),\n",
+       " (2031, 'gtvitoip', 'eterllec', -20.986774950797688),\n",
+       " (3888, 'ghvzbxvp', 'eheiturc', -20.383585988890655),\n",
+       " (1932, 'togrqqkj', 'ropaingw', -19.909524318295766),\n",
+       " (2095, 'ktviahwf', 'itersess', -16.817880160467876)]"
+      ]
+     },
+     "execution_count": 69,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('carriden', cb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 73,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(3724, 'ctvjmqrz', 'atesennm', -20.773714800352973),\n",
+       " (3774, 'crizlhre', 'arridenr', -20.672984933887122),\n",
+       " (4277, 'ghzeiocs', 'ehinalyf', -20.658964492527073),\n",
+       " (116, 'rrvrtbwb', 'prealyso', -20.383713774610182),\n",
+       " (2825, 'vcrizlhr', 'tcarride', -20.314442468008288),\n",
+       " (3773, 'vcrizlhr', 'tcarride', -20.314442468008288),\n",
+       " (4001, 'vcrizlhr', 'tcarride', -20.314442468008288),\n",
+       " (4002, 'crizlhrt', 'arrideng', -20.025819952039228),\n",
+       " (2826, 'crizlhrn', 'arridena', -19.966185971501325),\n",
+       " (34, 'lozealrx', 'joinsink', -19.462213220012078)]"
+      ]
+     },
+     "execution_count": 73,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('carriden', rscb)\n",
+    "sorted(results, key=lambda r: r[3])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 74,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(2597, 'exvtgwlabewmwc', 'sxermegsyaleck', -49.81296938807377),\n",
+       " (1857, 'phlnxhtcuvdkol', 'dhuldpourrscut', -49.13611031005585),\n",
+       " (419, 'tidcllwljvtwam', 'himartrdgriogu', -48.64335834592182),\n",
+       " (437, 'kikvuaiagwplzh', 'yittaidsdsedfp', -48.5726126013493),\n",
+       " (1257, 'etvviktnhjzbrr', 'stetosofefotxz', -48.342230828579034),\n",
+       " (1460, 'bookpstvdvepym', 'poxivaonartheu', -47.31575074470188),\n",
+       " (3477, 'inztcswtgltoul', 'wniriarldhigat', -47.29846956041843),\n",
+       " (189, 'zwztjghiqecgzu', 'nwirpocanaryfc', -47.22212883996443),\n",
+       " (3885, 'ylaghvzbxvpafw', 'mljenduturesle', -47.195597163089204),\n",
+       " (1550, 'otzqhqbqfmcblm', 'ctionywicirtru', -42.53263877954705)]"
+      ]
+     },
+     "execution_count": 74,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('marcusfidelius', cb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 75,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(3622, 'eekwgaqwhwptvr', 'setumiloeselbz', -49.621503851222684),\n",
+       " (431, 'mikgmuttbtrpiw', 'aitescolypghoe', -48.638854480044415),\n",
+       " (4047, 'ddnqzlruhhrilj', 'rdwoftmmedgarr', -48.554073127618814),\n",
+       " (331, 'haevvwfaqgtvre', 'vantbeasncinxm', -47.97373414413526),\n",
+       " (481, 'fvggmdzahwechs', 'tvpeslusestuna', -47.69237924848791),\n",
+       " (3091, 'jvzvtgslfmlbcm', 'xvitzondciatiu', -47.66616454997231),\n",
+       " (359, 'zcvwlhfvwetwzp', 'nceurpantaiofx', -46.437815241423564),\n",
+       " (1305, 'aljebasbrxgivy', 'olschintotvabg', -46.39925349262584),\n",
+       " (1132, 'tdjclggcwmzeba', 'hdsarobutiowhi', -45.275970767894435),\n",
+       " (3814, 'emzpzglzhvzvfa', 'sminfogreronli', -41.6349660094247)]"
+      ]
+     },
+     "execution_count": 75,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('marcusfidelius', rscb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 76,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(466, 'vhdap', 'etrac', -9.424044514537115),\n",
+       " (1017, 'twzgp', 'cingc', -9.33246375242154),\n",
+       " (548, 'tseay', 'cesal', -9.255465693315784),\n",
+       " (1165, 'twztb', 'cinto', -9.254386558557762),\n",
+       " (1275, 'kvqnl', 'theny', -9.087612038710173),\n",
+       " (1255, 'gcetv', 'posti', -8.900383209557894),\n",
+       " (3719, 'iootv', 'racti', -8.850289758493188),\n",
+       " (1579, 'ehqdn', 'nteda', -8.67266649829844),\n",
+       " (276, 'rwzgp', 'aingc', -8.654191627847336),\n",
+       " (693, 'rbpez', 'andem', -8.641276141783493)]"
+      ]
+     },
+     "execution_count": 76,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('roman', cb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 77,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(3842, 'ramnl', 'amany', -9.437027872569471),\n",
+       " (4317, 'faanf', 'omons', -9.430127363696526),\n",
+       " (3619, 'jwhee', 'siver', -9.320629122935628),\n",
+       " (2026, 'famnf', 'omans', -9.311629914178287),\n",
+       " (3150, 'famnf', 'omans', -9.311629914178287),\n",
+       " (3233, 'famnf', 'omans', -9.311629914178287),\n",
+       " (3826, 'famnf', 'omans', -9.311629914178287),\n",
+       " (2363, 'kfusg', 'trist', -9.035674036092695),\n",
+       " (910, 'fdqrg', 'opert', -8.871736942260315),\n",
+       " (3038, 'gfaua', 'proun', -8.586035154281198)]"
+      ]
+     },
+     "execution_count": 77,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('roman', rscb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 78,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(2281, 'xgrwqyqqn', 'ssaditimk', -25.50904015692954),\n",
+       " (4006, 'wvveahmvr', 'rhelscero', -25.382077332864444),\n",
+       " (1646, 'ypvkxftxd', 'tberpalta', -25.130456920711293),\n",
+       " (2100, 'hwflanaiv', 'ciossises', -24.871322973319465),\n",
+       " (2517, 'dgfhzjamh', 'ysooresie', -24.722409611286242),\n",
+       " (810, 'mcilmflsk', 'horseadoh', -24.64958690599062),\n",
+       " (1798, 'tvfvbtvwr', 'ohoctonso', -24.647021212027184),\n",
+       " (3343, 'awewwhtiv', 'vindocles', -23.927082944001153),\n",
+       " (2778, 'mcilmflsv', 'horseados', -23.868317161553193),\n",
+       " (3575, 'fhvvzjqgv', 'atecreics', -23.86243429804511)]"
+      ]
+     },
+     "execution_count": 78,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('fortified', cb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 79,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(3213, 'dgkabmpes', 'ysththhap', -25.858476016839074),\n",
+       " (4245, 'pdrbvqwal', 'kpainlowi', -25.69251300423946),\n",
+       " (859, 'wsctznikg', 'relariagd', -25.68949990545181),\n",
+       " (3321, 'pgzwtjihl', 'ksidleadi', -25.630885603720866),\n",
+       " (2740, 'hrgxviqrz', 'cdpendinw', -25.60510505179495),\n",
+       " (1990, 'ksvtjnvgl', 'feeabinci', -25.051685311929564),\n",
+       " (4012, 'tfkxalivj', 'ortesgarg', -24.7076022359218),\n",
+       " (3722, 'tpctvjmqr', 'oblaneemo', -24.11291857943737),\n",
+       " (3454, 'nfflbtwrf', 'irostoonc', -23.58091480413326),\n",
+       " (691, 'hfvtdftxh', 'creavalte', -23.576969563723157)]"
+      ]
+     },
+     "execution_count": 79,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('fortified', rscb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 80,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(1239, 'cblmflsgtvzvjkf', 'wbsinxneteinggs', -53.67979567378313),\n",
+       " (3574, 'hfhvvzjqgvrjegr', 'bfordleogeabbce', -53.332644164070246),\n",
+       " (683, 'rovscwqnnsrbpez', 'locokillnbatmam', -52.948716390961906),\n",
+       " (1676, 'rkhthhxqntlawtv', 'lkopptsoncustpi', -52.74063132472511),\n",
+       " (155, 'aphyfzidevuvrwz', 'upounldbeednosm', -52.06563577702356),\n",
+       " (3342, 'lawewwhtivnmdvk', 'fadaeicriewearx', -52.039898007621005),\n",
+       " (179, 'owxlaftnekzwztj', 'iwehiroletiowpw', -52.031145860023),\n",
+       " (4309, 'atmiwzfzrkjvhqb', 'utteelaxrtsnemo', -51.966531880968944),\n",
+       " (224, 'hikkeajftjrvvet', 'birgmmedtsansag', -51.2862727444336),\n",
+       " (1428, 'bbtlagtvivimqvv', 'vbahisotierenri', -49.79512612365323)]"
+      ]
+     },
+     "execution_count": 80,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('gatesofcarriden', cb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 81,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(748, 'zfnkkmrgejrvgqj', 'tfugsymeesandmw', -52.05542207245692),\n",
+       " (2114, 'htpiogtnlvfaldw', 'btwewsolleosizj', -51.933562137754535),\n",
+       " (3129, 'orrhwmfknkkmrge', 'irydeyaintteocr', -51.72518143282167),\n",
+       " (1721, 'kalftfjclrgcwmw', 'easbbrealaputij', -51.39500709853823),\n",
+       " (966, 'qiflwdmksvtivfj', 'kimhephisecasbw', -51.16282166067445),\n",
+       " (3155, 'malwahtnuxjkhsl', 'gassitolugsceoy', -50.82080768385719),\n",
+       " (17, 'oobqhvjkrzfzwim', 'ioimpheiriortez', -50.804328693902804),\n",
+       " (1877, 'gnbvlffyrrilvrn', 'anirtrawrardsna', -50.77261706301617),\n",
+       " (39, 'lrxhgbtjauruhdx', 'fredonohadamezk', -50.58185950803962),\n",
+       " (3994, 'nggivftvcrizlhr', 'hgnedrotcarride', -49.321188855519125)]"
+      ]
+     },
+     "execution_count": 81,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('gatesofcarriden', rscb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 82,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(109, 'xgrxgbqahmyazk', 'rgytonlhaitmir', -50.30067966367403),\n",
+       " (2970, 'qehrernxvehwre', 'keonmdieoacial', -49.90749685359809),\n",
+       " (1125, 'bakgdhtvlljfap', 'varcltoceherjw', -49.6746669250614),\n",
+       " (2116, 'erbttoglaihbfl', 'yripbabstecnos', -49.57823086787266),\n",
+       " (2189, 'okpsdhuhvvjkzm', 'ikwoltpoorewit', -49.52479031750286),\n",
+       " (4259, 'xothazthamatlk', 'roadilootivfur', -49.18754328260107),\n",
+       " (3008, 'eueaaqmhzwtsrm', 'yulwichossoeat', -49.12646769488776),\n",
+       " (4103, 'qgntkfdbuikstm', 'kgupsryinefect', -49.0189271054904),\n",
+       " (4013, 'vrhhlawbhrqcgl', 'prodtmrianlops', -48.98409155181962),\n",
+       " (1228, 'ktrwkwqmhtmcbl', 'etyssiltaphoks', -46.94309949621737)]"
+      ]
+     },
+     "execution_count": 82,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('gatesofthefort', cb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 83,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(3901, 'uvkikczdumawtv', 'ovresouknivicc', -47.785004409521385),\n",
+       " (3167, 'hslxhgbtzwtcjl', 'bsstpswassooss', -47.53894456988189),\n",
+       " (6, 'npkmrgyalgtoob', 'hprizsthecoaxi', -47.314970387934196),\n",
+       " (1462, 'aatjwfatasksgk', 'uaafervatofepr', -47.1283638409202),\n",
+       " (3155, 'malwahtnuxjkhs', 'gassitountewqz', -46.99630838756432),\n",
+       " (1526, 'hdlalcgtzmqwka', 'bdswtobasilith', -46.7437381684409),\n",
+       " (2552, 'hqhvvwlbumtbvt', 'bqordiginionea', -46.485664854182),\n",
+       " (1417, 'agbrvswalyndjt', 'uginderheuipsa', -46.000308431211856),\n",
+       " (1967, 'yalstsjtpfjbtx', 'sasobeeaibence', -45.501107818985226),\n",
+       " (1381, 'cthlahtwwswbfg', 'wtohitodpornon', -45.23713792080447)]"
+      ]
+     },
+     "execution_count": 83,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('gatesofthefort', rscb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 84,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(3924, 'mvrevhww', 'tonchesz', -21.530081854612558),\n",
+       " (3304, 'bzlwgwwf', 'ishustsi', -21.522929562878094),\n",
+       " (1670, 'olhwhdrk', 'vedutann', -21.377317616350332),\n",
+       " (2327, 'wuhvvhwh', 'dndthesk', -20.94621791919036),\n",
+       " (3909, 'kimvwqpf', 'rbitinli', -20.84375116446709),\n",
+       " (336, 'lzircvtf', 'ssepospi', -20.719450285091096),\n",
+       " (1597, 'ivxgrhxj', 'potedetm', -20.706690393648426),\n",
+       " (1821, 'ilwvvhqh', 'pesthemk', -20.211702557206248),\n",
+       " (102, 'lvgjwvtx', 'sochispa', -20.11656789559091),\n",
+       " (1783, 'blwvvhqh', 'iesthemk', -19.13426965292788)]"
+      ]
+     },
+     "execution_count": 84,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('thecodex', cb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 85,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(4103, 'ntevvrjt', 'umathofw', -21.12050302860748),\n",
+       " (1135, 'clggcwmz', 'jeceotic', -21.0926226108083),\n",
+       " (3784, 'lvvqqrya', 'sorocoud', -21.0704407610811),\n",
+       " (2607, 'tfwvihra', 'aystuend', -21.036511358408227),\n",
+       " (770, 'ealcuhgb', 'lthagece', -20.864565160704405),\n",
+       " (1063, 'lvtgqrhx', 'sopecoda', -20.754724320672608),\n",
+       " (1418, 'gbrvswal', 'nuntetwo', -20.58615056728773),\n",
+       " (2628, 'yalgtrpk', 'fthefoln', -19.713559586711344),\n",
+       " (4051, 'zlruhhri', 'genstenl', -19.43791767956815),\n",
+       " (1040, 'taltsves', 'athresav', -19.414018974488442)]"
+      ]
+     },
+     "execution_count": 85,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('thecodex', rscb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 86,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(2166, 'xftqmpav', 'urhithai', -21.474070991196612),\n",
+       " (621, 'hddclatn', 'eprussta', -21.437474795697312),\n",
+       " (3752, 'vvtmlatb', 'shhessto', -21.36709963180998),\n",
+       " (1313, 'kspttvek', 'hedlanex', -21.21846639563575),\n",
+       " (3080, 'oddmlmwa', 'lpresewn', -21.153561245717015),\n",
+       " (1907, 'yaqutvag', 'vmemanat', -21.13955075507157),\n",
+       " (3418, 'wizmlatj', 'tunesstw', -20.78298814152589),\n",
+       " (1050, 'hdmzmwti', 'epartotv', -20.571400605890293),\n",
+       " (857, 'uhebhnai', 'rtstofav', -20.18106418846078),\n",
+       " (3842, 'jddmlmsh', 'gpresesu', -19.026003480730346)]"
+      ]
+     },
+     "execution_count": 86,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('domitian', cb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 87,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(3214, 'gkabmpes', 'dwotthef', -20.94405168913833),\n",
+       " (1615, 'whuktalv', 'tticasli', -20.572797420355037),\n",
+       " (2559, 'bumtbvtj', 'ygalintw', -20.569458875838592),\n",
+       " (4032, 'vwzlitot', 'sindplog', -20.38216185513019),\n",
+       " (1251, 'loebawml', 'iasthomy', -20.31812563846053),\n",
+       " (608, 'cofuxvgg', 'zatmengt', -20.292921997536638),\n",
+       " (2928, 'qbqlbbwb', 'nneditwo', -19.92037147986436),\n",
+       " (3927, 'zvavvtia', 'whonclin', -19.799839075342426),\n",
+       " (374, 'lhfpxapa', 'itthespn', -19.413682398696466),\n",
+       " (2787, 'qhqztoif', 'nteragis', -19.131491583368767)]"
+      ]
+     },
+     "execution_count": 87,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('domitian', rscb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 88,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "p7b = open('7b.plaintext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 89,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[('caledonian', 6),\n",
+       " ('salustiusw', 5),\n",
+       " ('ecaledonia', 5),\n",
+       " ('thecaledon', 5),\n",
+       " ('hecaledoni', 5),\n",
+       " ('inchtuthil', 5),\n",
+       " ('stracathro', 5),\n",
+       " ('alustiuswa', 3),\n",
+       " ('lustiuswas', 3),\n",
+       " ('ofthecaled', 3),\n",
+       " ('fthecaledo', 3),\n",
+       " ('ysalustius', 3),\n",
+       " ('nsalustius', 3),\n",
+       " ('salustiuss', 3),\n",
+       " ('salustiusa', 3),\n",
+       " ('mayhavebee', 2),\n",
+       " ('ayhavebeen', 2),\n",
+       " ('ingcaledon', 2),\n",
+       " ('ngcaledoni', 2),\n",
+       " ('gcaledonia', 2)]"
+      ]
+     },
+     "execution_count": 89,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "collections.Counter(ngrams(sanitise(p7b), 10)).most_common(20)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 90,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[('salustius', 15),\n",
+       " ('caledonia', 10),\n",
+       " ('ecaledoni', 6),\n",
+       " ('aledonian', 6),\n",
+       " ('alustiusw', 5),\n",
+       " ('thecaledo', 5),\n",
+       " ('hecaledon', 5),\n",
+       " ('inchtuthi', 5),\n",
+       " ('nchtuthil', 5),\n",
+       " ('stracathr', 5),\n",
+       " ('tracathro', 5),\n",
+       " ('thelegion', 4),\n",
+       " ('lustiuswa', 3),\n",
+       " ('ustiuswas', 3),\n",
+       " ('ofthecale', 3),\n",
+       " ('fthecaled', 3),\n",
+       " ('ysalustiu', 3),\n",
+       " ('nsalustiu', 3),\n",
+       " ('alustiuss', 3),\n",
+       " ('alustiusa', 3)]"
+      ]
+     },
+     "execution_count": 90,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "collections.Counter(ngrams(sanitise(p7b), len(\"salustius\"))).most_common(20)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 91,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "2 True [(673, 'dnadssurem'), (1847, 'ohasecushs'), (3339, 'virmisalsi'), (21, 'placianisb')]\n",
+      "2 False [(2715, 'rheseluner'), (443, 'nhemotearx'), (856, 'ttictindmn'), (1779, 'uestasuntc')]\n",
+      "3 True [(213, 'dlifireslt'), (2408, 'dlonevilai'), (1073, 'mhenstcarl'), (629, 'pmorebastt')]\n",
+      "3 False [(2616, 'towisisnea'), (3012, 'urersdedti'), (3811, 'lriteviely'), (2959, 'rldiansary')]\n",
+      "4 True [(762, 'egifetesoy'), (2896, 'ttitamerlt'), (821, 'tupaintewt'), (2162, 'calneaneex')]\n",
+      "4 False [(1029, 'esasnendaz'), (2302, 'yetivewetu'), (3530, 'llielmostc'), (1670, 'feeitegita')]\n",
+      "5 True [(2254, 'bttatielof'), (218, 'fstbresthw'), (2319, 'ntandipsef'), (1304, 'lablelinla')]\n",
+      "5 False [(2492, 'intwoltoru'), (1573, 'toasededly'), (2919, 'aaaretesav'), (1702, 'kepreitite')]\n",
+      "6 True [(2353, 'ussigholag'), (369, 'ulewandimp'), (2823, 'iplasenhen'), (1598, 'xinsinscan')]\n",
+      "6 False [(2857, 'etiserelcy'), (410, 'anchesioof'), (1083, 'iactosiory'), (1682, 'yrolthende')]\n",
+      "7 True [(3301, 'oalmoption'), (618, 'rmurciandr'), (283, 'plivetelii'), (1595, 'introntbek')]\n",
+      "7 False [(1069, 'yvidettolf'), (1514, 'dwerstiehi'), (2330, 'rtocereure'), (3635, 'ditisthery')]\n",
+      "8 True [(873, 'uckworistu'), (1419, 'zlonoreseg'), (1978, 'partimisrx'), (2823, 'knareselll')]\n",
+      "8 False [(137, 'runkicader'), (2296, 'fovichosue'), (251, 'rsttoleshw'), (1644, 'nsasoldeni')]\n",
+      "9 True [(516, 'plahornsec'), (4147, 'btiscensex'), (2445, 'ficommsage'), (2867, 'shehaliand')]\n",
+      "9 False [(2843, 'tlacinacat'), (3770, 'btotheyinu'), (330, 'efemeemare'), (1658, 'aatranalat')]\n",
+      "10 True [(2630, 'tatyotealn'), (3639, 'tvidticear'), (3936, 'erisbreesu'), (1649, 'ssaltearpr')]\n",
+      "10 False [(3131, 'taldinsoer'), (2203, 'lugeliantu'), (3863, 'thegarkitr'), (205, 'shiterspus')]\n",
+      "11 True [(2661, 'andedjunsy'), (2764, 'dyarsorsce'), (2425, 'xdisisnorc'), (3307, 'iberatifal')]\n",
+      "11 False [(1714, 'fnewtriewi'), (1150, 'dsscivesag'), (2690, 'auschnecti'), (739, 'skedisollm')]\n",
+      "12 True [(1506, 'qhersarsts'), (1123, 'nenealiold'), (3175, 'isinamthej'), (3487, 'trartrintf')]\n",
+      "12 False [(1288, 'obesbutetc'), (555, 'thibemostu'), (2203, 'ofaternary'), (2548, 'rapanteche')]\n",
+      "13 True [(1719, 'alawonewon'), (1212, 'tatrieluma'), (3, 'bovitsuarc'), (3274, 'rsibentsru')]\n",
+      "13 False [(701, 'sanlydespn'), (4226, 'dlattlewan'), (3939, 'rigorralea'), (4123, 'mwarthecyt')]\n",
+      "14 True [(44, 'tallbefide'), (2626, 'rlenetangg'), (3784, 'yfeedinsed'), (3289, 'aaletheths')]\n",
+      "14 False [(4317, 'utainonaad'), (2815, 'dbaionanys'), (3467, 'cuphathatj'), (3896, 'xlielissau')]\n",
+      "15 True [(356, 'presagulyn'), (4305, 'yeasemmaid'), (2595, 'llitinetcz'), (3608, 'ttpeonento')]\n",
+      "15 False [(1683, 'ljailonsta'), (1659, 'teagiteony'), (1456, 'oaralboste'), (2244, 'toushcongt')]\n",
+      "16 True [(1721, 'rldieditfe'), (1115, 'aystormllb'), (1402, 'yritersfej'), (1198, 'zticelaron')]\n",
+      "16 False [(2456, 'fgincenisy'), (1599, 'tgnstronse'), (1712, 'tpaysheure'), (1143, 'eoulatodin')]\n",
+      "17 True [(2049, 'drrassicin'), (1932, 'ctrofalway'), (1181, 'prighiects'), (2554, 'cricityame')]\n",
+      "17 False [(1449, 'dianouncii'), (4223, 'imoddtesta'), (3980, 'yviendtrum'), (580, 'yptostecri')]\n",
+      "18 True [(1561, 'vspingalap'), (3970, 'dreperesgz'), (4042, 'paliththwi'), (3204, 'plicititac')]\n",
+      "18 False [(4248, 'jacesttefs'), (3098, 'rafathiney'), (1994, 'terrotratb'), (3248, 'clifichech')]\n",
+      "19 True [(3572, 'ehareemdof'), (1372, 'ierbilebay'), (421, 'tasdatthru'), (3586, 'retsianspi')]\n",
+      "19 False [(4075, 'iaprelinka'), (234, 'ttototmina'), (3275, 'xsermendby'), (1444, 'ctionillab')]\n",
+      "20 True [(1877, 'nnoodsuntt'), (2311, 'favesweplo'), (3414, 'yalcietiss'), (1478, 'nlintsrigs')]\n",
+      "20 False [(3230, 'ochoopilly'), (1593, 'hvidicours'), (1924, 'ealsicenby'), (3559, 'hatintorbm')]\n",
+      "21 True [(3304, 'intgosiced'), (1138, 'rolofmusth'), (2928, 'uchnaloria'), (4203, 'dnoritaire')]\n",
+      "21 False [(3919, 'hlardhilen'), (2843, 'vrediroann'), (201, 'yperspinfy'), (1615, 'cmdethehei')]\n",
+      "22 True [(1954, 'upaconitao'), (1038, 'ebugitesti'), (1571, 'tledendicg'), (611, 'pesecreore')]\n",
+      "22 False [(2618, 'wipsorsinn'), (3774, 'khenchinyn'), (4013, 'cevisisalc'), (1261, 'hiceenengc')]\n",
+      "23 True [(1648, 'udscosengn'), (2796, 'utuailosto'), (1888, 'rmaingyshr'), (820, 'xsomesistd')]\n",
+      "23 False [(3312, 'itashianyt'), (3372, 'iwisicelac'), (1444, 'ulystleman'), (3117, 'seamatiept')]\n",
+      "24 True [(3058, 'rversoadhu'), (4262, 'nlareriltw'), (4094, 'yalinualtm'), (1760, 'edblitinex')]\n",
+      "24 False [(3405, 'topescisix'), (568, 'ucoteistag'), (1597, 'rtaretolta'), (860, 'flacatecol')]\n",
+      "25 True [(2777, 'rniparswhi'), (3583, 'ywereteelx'), (1944, 'olriereoni'), (3380, 'earendidng')]\n",
+      "25 False [(1246, 'peinitelaj'), (1531, 'dlassststp'), (1769, 'oussiootth'), (422, 'bacewayoft')]\n",
+      "26 True [(2090, 'rberdwalse'), (555, 'obvistreig'), (1126, 'etardembie'), (1016, 'tetyinerys')]\n",
+      "26 False [(698, 'rvinetnorj'), (1252, 'cnissonnan'), (4101, 'toforeoroz'), (581, 'mnalsmestr')]\n",
+      "27 True [(2603, 'weahermeno'), (4206, 'rsizinsear'), (1618, 'ikehomaran'), (2945, 'fsunestris')]\n",
+      "27 False [(881, 'plalstishs'), (1770, 'lwameanthu'), (1801, 'escoticlar'), (2571, 'eganthroto')]\n",
+      "28 True [(2136, 'oeabootrap'), (583, 'kgaseryant'), (1227, 'geivedelov'), (4024, 'iatioolsei')]\n",
+      "28 False [(580, 'fetonetsfs'), (1266, 'janctropad'), (244, 'lverssnoth'), (2881, 'etorilinth')]\n",
+      "29 True [(557, 'earresbogi'), (1233, 'irtiegalog'), (2663, 'jachatarrp'), (3500, 'teretbeofp')]\n",
+      "29 False [(3759, 'tedholidei'), (1282, 'iganommitu'), (2424, 'cfrintriem'), (2326, 'chepetelli')]\n",
+      "30 True [(510, 'drchigotan'), (2116, 'pstroficls'), (2723, 'rrcrasecti'), (3952, 'chinsningb')]\n",
+      "30 False [(3799, 'dilsectseo'), (4279, 'gtaretemus'), (1727, 'heawntents'), (3133, 'ymeordeday')]\n",
+      "31 True [(3554, 'kairernomy'), (1167, 'akionasais'), (938, 'urfrisaneg'), (79, 'uningmotan')]\n",
+      "31 False [(3006, 'rpileacels'), (630, 'riaincesma'), (3527, 'xopontorea'), (3454, 'aselyonere')]\n",
+      "32 True [(304, 'yewaymengf'), (2753, 'eafthtossm'), (214, 'reerthidif'), (996, 'ooldestela')]\n",
+      "32 False [(502, 'zhasepentd'), (301, 'ractsditsg'), (536, 'mathtbusig'), (23, 'ldeptivemi')]\n",
+      "33 True [(1142, 'mainsmionu'), (3932, 'rrlistoars'), (1810, 'dangeadolv'), (1903, 'ghlincrequ')]\n",
+      "33 False [(3970, 'rboremobam'), (3532, 'latoessbia'), (2266, 'ftpoundsti'), (610, 'ymesamefla')]\n",
+      "34 True [(1300, 'lpamincits'), (2422, 'dapoordera'), (769, 'taienotrat'), (3043, 'carmousepa')]\n",
+      "34 False [(3189, 'knarnmetha'), (1210, 'ftpagesifi'), (1132, 'ivarsderit'), (677, 'vtatederan')]\n",
+      "35 True [(1472, 'roanarnofg'), (185, 'utertdenfl'), (2995, 'ypummessit'), (2220, 'ptirthinio')]\n",
+      "35 False [(3389, 'fbeddepont'), (1264, 'ooanttedbu'), (1499, 'wsoregronc'), (4167, 'dhossinteq')]\n",
+      "36 True [(4016, 'ueniftiend'), (1675, 'yopstmentr'), (3998, 'tlintoachd'), (4197, 'utanadithf')]\n",
+      "36 False [(2844, 'sgoweardig'), (3155, 'imemasipai'), (2726, 'ulandpowag'), (3471, 'rtelottoal')]\n",
+      "37 True [(3490, 'aniamarotu'), (3510, 'heflisadit'), (4184, 'elariendgu'), (140, 'duthesitye')]\n",
+      "37 False [(2244, 'pecuseulli'), (2426, 'terdentctb'), (1512, 'yardetsowa'), (3075, 'oloctigisn')]\n",
+      "38 True [(2652, 'welanueith'), (72, 'uvarelandw'), (2758, 'yjoresinan'), (3197, 'weeretingv')]\n",
+      "38 False [(3792, 'rcondviake'), (258, 'laincialyx'), (2597, 'kheworslak'), (4270, 'cfortentrg')]\n",
+      "39 True [(340, 'detnioneyf'), (322, 'udistigdid'), (3759, 'talddritet'), (4052, 'fantianexw')]\n",
+      "39 False [(2113, 'tasoomeofw'), (3583, 'owaresysbr'), (2015, 'olopebingm'), (477, 'evacatinmp')]\n",
+      "40 True [(1235, 'dateuriadi'), (1910, 'fiewofanti'), (3919, 'perichoilt'), (105, 'dtorsttrim')]\n",
+      "40 False [(1154, 'ademenifse'), (3222, 'utssamosin'), (3046, 'eheetwatht'), (1261, 'msodserein')]\n",
+      "41 True [(2275, 'rmiletenlc'), (2983, 'yomeryreau'), (305, 'ndunindsht'), (4265, 'efindtolap')]\n",
+      "41 False [(3726, 'smorvidlin'), (1806, 'ctsrextheu'), (2219, 'ynivernman'), (3299, 'lkiddereat')]\n",
+      "42 True [(1909, 'tylarhisai'), (619, 'rectdotsad'), (2611, 'zoohondine'), (2753, 'taclesenys')]\n",
+      "42 False [(2401, 'oechotoraz'), (3790, 'nntrogingg'), (442, 'ittyoteatu'), (738, 'stamenasen')]\n",
+      "43 True [(4326, 'yattaliler'), (815, 'ualeglesar'), (293, 'ndighttexe'), (1908, 'ewthecasag')]\n",
+      "43 False [(2774, 'weadobesot'), (971, 'ktirtstiva'), (4074, 'oossurtisk'), (2658, 'tamessuder')]\n",
+      "44 True [(2362, 'ettlplentr'), (739, 'elisothurf'), (2301, 'rponditaln'), (3880, 'tteshanseu')]\n",
+      "44 False [(4226, 'tlimendmun'), (2447, 'yloreyress'), (726, 'ftrathariz'), (3651, 'alasiessea')]\n"
+     ]
+    }
+   ],
+   "source": [
+    "for h in range(2, 45):\n",
+    "    for d in [True, False]:\n",
+    "        if d:\n",
+    "            tcb = scytale_decipher(scb, h)\n",
+    "        else:\n",
+    "            tcb = scytale_encipher(scb, h)\n",
+    "        results = autokey_seek('caledonian', tcb)\n",
+    "        print(h, d, [(r[0], r[2]) for r in sorted(results, key=lambda r: r[-1])][-4:])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 92,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "2 True [(3599, 'ovactenepi'), (2728, 'mbeitandrr'), (3694, 'cinditoaty'), (1602, 'nfaresnees')]\n",
+      "2 False [(724, 'ugamedsovi'), (3300, 'rherolinhs'), (4249, 'jachiprors'), (4173, 'atanortacu')]\n",
+      "3 True [(239, 'yturesotve'), (158, 'yatcatpeds'), (2527, 'cdcouitthi'), (3001, 'erldsmistr')]\n",
+      "3 False [(1989, 'sstrunasaf'), (1412, 'unamandrce'), (1858, 'iniliancof'), (3662, 'illentuald')]\n",
+      "4 True [(2906, 'uderizesce'), (4031, 'rfrithadae'), (3081, 'dstotauden'), (1110, 'termedovid')]\n",
+      "4 False [(3905, 'tviemdines'), (1538, 'tstotdocli'), (1214, 'baposayout'), (246, 'yeotsionic')]\n",
+      "5 True [(1595, 'utiakeedat'), (2777, 'stosainlad'), (2318, 'ovinicoodu'), (2419, 'gmistrecar')]\n",
+      "5 False [(2478, 'zaatsorenv'), (167, 'uncheevioe'), (24, 'lecretaixe'), (491, 'geptirothr')]\n",
+      "6 True [(1900, 'iwargheche'), (2382, 'dmeslaussi'), (4244, 'sdonstisfy'), (3239, 'tprincovac')]\n",
+      "6 False [(3071, 'ravesypons'), (4049, 'eyerocusas'), (401, 'rtwhilyous'), (3882, 'ledeindinm')]\n",
+      "7 True [(365, 'ttrickowil'), (519, 'rnesoeasas'), (41, 'dnthoniori'), (3270, 'ttesenoapa')]\n",
+      "7 False [(210, 'gewserlely'), (1817, 'vexderinte'), (3224, 'yvenimiden'), (1847, 'ferialesva')]\n",
+      "8 True [(3661, 'neinemilfs'), (372, 'thadegicaw'), (3467, 'wiionesetr'), (1643, 'ibulunintr')]\n",
+      "8 False [(3077, 'dswatehome'), (386, 'havateeicl'), (2925, 'iefredanix'), (2093, 'tbeissasig')]\n",
+      "9 True [(564, 'fgofettesu'), (254, 'nheiromakt'), (3465, 'netwomenug'), (4003, 'rainomisle')]\n",
+      "9 False [(2093, 'orowasulln'), (1977, 'draneneckj'), (3729, 'rroontricj'), (1238, 'ffarialisd')]\n",
+      "10 True [(743, 'gjastdestu'), (1756, 'ktanelssar'), (1278, 'upofrotowi'), (3105, 'lathefiswb')]\n",
+      "10 False [(494, 'sbfrithele'), (3601, 'gpannommai'), (3805, 'thgremedia'), (1106, 'umbensirec')]\n",
+      "11 True [(733, 'brithoiscm'), (2287, 'ppiremuess'), (2195, 'zalontedig'), (2379, 'architinfe')]\n",
+      "11 False [(3461, 'rprioncble'), (3453, 'stcustuntc'), (1969, 'rharricssi'), (1247, 'aralsetwee')]\n",
+      "12 True [(3582, 'eusendasmm'), (83, 'ustspeepal'), (4195, 'xcendmantu'), (4253, 'roloclinen')]\n",
+      "12 False [(3694, 'xiastsight'), (4289, 'ydussarety'), (616, 'ttitennodi'), (1987, 'sturecewon')]\n",
+      "13 True [(3338, 'hignglerat'), (1472, 'sssdesorte'), (2305, 'alimameatr'), (3997, 'hanssonshi')]\n",
+      "13 False [(3175, 'ywargronaz'), (517, 'ccaneninsx'), (4169, 'teorefirfi'), (697, 'badietacet')]\n",
+      "14 True [(2574, 'heppilangt'), (1698, 'nteceltrun'), (3506, 'phinoteelp'), (1185, 'atteitiori')]\n",
+      "14 False [(1858, 'cnannityor'), (993, 'ylerdspeno'), (2560, 'thtoshasti'), (812, 'dteranbati')]\n",
+      "15 True [(910, 'ddemrsinfo'), (4317, 'itweslarou'), (1313, 'xconthecln'), (2418, 'dfatheinto')]\n",
+      "15 False [(3526, 'ozeasbings'), (494, 'nalremempn'), (3278, 'tilitouger'), (2270, 'inientiody')]\n",
+      "16 True [(287, 'eltoitsatr'), (4006, 'dlycesiown'), (3761, 'rtinsdarnw'), (183, 'oatritisre')]\n",
+      "16 False [(311, 'rtotinnsad'), (2636, 'wlthefanes'), (3714, 'elarthtegn'), (2220, 'patimityfi')]\n",
+      "17 True [(3594, 'ergbilinso'), (2380, 'wboneceshf'), (2320, 'irpushingm'), (2799, 'ttobontsce')]\n",
+      "17 False [(4258, 'tgaroburac'), (1216, 'ignajonste'), (3398, 'rheharsbei'), (2367, 'ubtrethata')]\n",
+      "18 True [(2082, 'rtarexenty'), (336, 'aradsonsbr'), (1392, 'estromrart'), (411, 'utiosindin')]\n",
+      "18 False [(1152, 'pntattsesu'), (871, 'rltrisertp'), (1079, 'xditimeapi'), (1723, 'beirdonisi')]\n",
+      "19 True [(3291, 'ggurebesam'), (154, 'oltssananf'), (83, 'uelisidile'), (3498, 'ljonstantc')]\n",
+      "19 False [(3512, 'etsasmusas'), (3885, 'tmicenitbr'), (235, 'ulpispreat'), (3237, 'smatunitbi')]\n",
+      "20 True [(1454, 'eeinsousax'), (3860, 'ikinialced'), (3057, 'tlassstsso'), (3331, 'ilainsnott')]\n",
+      "20 False [(4117, 'ussapopmer'), (1008, 'wvicorooll'), (353, 'yllemingtt'), (2986, 'yelowenoup')]\n",
+      "21 True [(3485, 'peawitespd'), (1228, 'goordaliae'), (2878, 'acanymerru'), (3738, 'rfthemildr')]\n",
+      "21 False [(3674, 'thertrosng'), (974, 'qbendinshi'), (8, 'athherilso'), (4048, 'thadirindi')]\n",
+      "22 True [(518, 'wtimesenks'), (1926, 'rthisioirp'), (3305, 'ofuternonw'), (968, 'tariedeslo')]\n",
+      "22 False [(3744, 'rdarmifiti'), (1911, 'erarescdoc'), (4033, 'uleconyane'), (688, 'ralasdeals')]\n",
+      "23 True [(3800, 'falasponho'), (235, 'clegehestn'), (2151, 'apearfacei'), (3613, 'oeavathent')]\n",
+      "23 False [(961, 'epopothmon'), (3959, 'ewehipindc'), (3363, 'edirefeerb'), (1271, 'engroledit')]\n",
+      "24 True [(400, 'edighsidac'), (509, 'gaaidenoto'), (4333, 'lnonokethn'), (3434, 'eedrontlex')]\n",
+      "24 False [(3046, 'picheidoot'), (1319, 'yzirectern'), (2011, 'yfosanistn'), (3040, 'ingryleany')]\n",
+      "25 True [(3436, 'deenmonemo'), (2725, 'enerenniki'), (3197, 'llrosineas'), (3407, 'atesthunks')]\n",
+      "25 False [(4296, 'suisinfeaf'), (3040, 'vvisttesca'), (31, 'ttundesonv'), (1088, 'gtinclastl')]\n",
+      "26 True [(2139, 'bautosalie'), (667, 'ladeladthw'), (192, 'veadescitj'), (3811, 'yliperaner')]\n",
+      "26 False [(2409, 'pttatcallt'), (2026, 'hgodstallo'), (839, 'gandstuthj'), (2449, 'rightorsai')]\n",
+      "27 True [(4084, 'utudenollf'), (3068, 'ksantmerry'), (3499, 'hawitseoft'), (3265, 'hopeiteses')]\n",
+      "27 False [(2483, 'ecbricanti'), (1427, 'blicutustg'), (1672, 'croratryat'), (3017, 'oafandadet')]\n",
+      "28 True [(2577, 'yafratidei'), (1050, 'allsmitams'), (2641, 'cisansholv'), (1871, 'reontrealn')]\n",
+      "28 False [(3980, 'lburetoprs'), (4078, 'ylichmactt'), (3017, 'ysiseanieh'), (3640, 'mgedortinm')]\n",
+      "29 True [(2354, 'egussinstu'), (2571, 'ldisemorty'), (4135, 'uresfornmi'), (3004, 'eharecrien')]\n",
+      "29 False [(3389, 'kafrocinat'), (1159, 'trecttripd'), (752, 'thonerayat'), (4289, 'thomittegu')]\n",
+      "30 True [(3150, 'fundabeflu'), (4003, 'ongosiaspo'), (2716, 'kfaindneas'), (790, 'culdiledte')]\n",
+      "30 False [(2302, 'elawimeatu'), (1748, 'fearebesez'), (4172, 'fsclatiamo'), (744, 'trictsetry')]\n",
+      "31 True [(2920, 'ntirstedpk'), (3555, 'rlineasdry'), (452, 'nlastadeig'), (4191, 'geansisepi')]\n",
+      "31 False [(91, 'ngrcerinsa'), (3976, 'yofpronalj'), (582, 'pleryhothr'), (824, 'tafthroree')]\n",
+      "32 True [(2651, 'etterdfily'), (680, 'cebantacla'), (3465, 'tmpreledby'), (3315, 'colithikes')]\n",
+      "32 False [(1115, 'orcanairit'), (3285, 'lvesarperm'), (911, 'nforelsoau'), (2429, 'terdeitles')]\n",
+      "33 True [(1035, 'cfirelomai'), (344, 'xhineminix'), (809, 'tseoesista'), (519, 'nsatecefeb')]\n",
+      "33 False [(3588, 'smerpowald'), (4049, 'ytontyocte'), (2136, 'sesmetofaq'), (1534, 'oredvdings')]\n",
+      "34 True [(2252, 'aklituravi'), (4157, 'pearetakki'), (2556, 'tasanttobc'), (3911, 'yaisoredat')]\n",
+      "34 False [(554, 'caprolriat'), (6, 'fachasdroo'), (4045, 'rridevidfr'), (437, 'anintmomad')]\n",
+      "35 True [(2857, 'elkmaresan'), (309, 'ineintylth'), (2603, 'indeearexa'), (1496, 'chaveinalw')]\n",
+      "35 False [(1213, 'espairedum'), (849, 'thedsoends'), (3327, 'ttosemesab'), (2760, 'kythemengt')]\n",
+      "36 True [(1601, 'toanadadbe'), (2537, 'eanrentahn'), (77, 'toakasingt'), (1686, 'siopesallh')]\n",
+      "36 False [(2555, 'olcadontte'), (3449, 'ltarisouan'), (414, 'ntidarabli'), (2434, 'lwaratsatm')]\n",
+      "37 True [(1231, 'slideltegg'), (3512, 'tiremmerae'), (2247, 'lfafithing'), (544, 'faviseties')]\n",
+      "37 False [(2017, 'lmaromascu'), (3581, 'rhewominem'), (1066, 'ftheprioxi'), (2455, 'rstinavetu')]\n",
+      "38 True [(3159, 'latifeasmx'), (790, 'omayasmett'), (1158, 'rbememaidg'), (3645, 'ccomplytam')]\n",
+      "38 False [(4044, 'ytsterinko'), (3243, 'lhowoneint'), (4151, 'cageswisst'), (501, 'llaserypal')]\n",
+      "39 True [(1091, 'rilfotatal'), (2437, 'mbargenddt'), (4313, 'undmomenns'), (163, 'inedemoomb')]\n",
+      "39 False [(3815, 'enttemusja'), (3296, 'tactsrsied'), (3169, 'prasstimae'), (4155, 'firangstfr')]\n",
+      "40 True [(1256, 'scesidivii'), (2946, 'xmilitnetr'), (24, 'elitepoidy'), (3117, 'glinsenivo')]\n",
+      "40 False [(2565, 'mmarspsiti'), (3642, 'omedeaystt'), (4217, 'ahontogorr'), (202, 'tagontichl')]\n",
+      "41 True [(2056, 'etusidhean'), (2290, 'tyinfisthy'), (760, 'flasediole'), (3805, 'tainemiscr')]\n",
+      "41 False [(2182, 'foiscianes'), (1260, 'talishydin'), (335, 'llinspunto'), (3244, 'mmystoreap')]\n",
+      "42 True [(143, 'vearymaspu'), (3666, 'dansssecle'), (263, 'rlameginag'), (3307, 'chinetgert')]\n",
+      "42 False [(486, 'kileobeest'), (4269, 'rbotityonb'), (410, 'thinespowu'), (2344, 'atagerisou')]\n",
+      "43 True [(3543, 'ystoolthfu'), (3673, 'ogersiefth'), (2896, 'erveotiorf'), (3764, 'fkidetonti')]\n",
+      "43 False [(3720, 'goleamotto'), (3225, 'yretacclas'), (3855, 'pecamincts'), (2864, 'viondinegu')]\n",
+      "44 True [(1630, 'paliedcian'), (4026, 'trneinateg'), (3543, 'plondemagg'), (1946, 'ircherrayb')]\n",
+      "44 False [(2350, 'hlesisnday'), (417, 'phemergtoc'), (1301, 'orrissyorc'), (1380, 'uatosmearm')]\n"
+     ]
+    }
+   ],
+   "source": [
+    "for h in range(2, 45):\n",
+    "    for d in [True, False]:\n",
+    "        if d:\n",
+    "            tcb = scytale_decipher(rscb, h)\n",
+    "        else:\n",
+    "            tcb = scytale_encipher(rscb, h)\n",
+    "        results = autokey_seek('caledonian', tcb)\n",
+    "        print(h, d, [(r[0], r[2]) for r in sorted(results, key=lambda r: r[-1])][-4:])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 95,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(3724, 'ctvjmqrz', 'atesennm', -20.773714800352973),\n",
+       " (3774, 'crizlhre', 'arridenr', -20.672984933887122),\n",
+       " (4277, 'ghzeiocs', 'ehinalyf', -20.658964492527073),\n",
+       " (116, 'rrvrtbwb', 'prealyso', -20.383713774610182),\n",
+       " (2825, 'vcrizlhr', 'tcarride', -20.314442468008288),\n",
+       " (3773, 'vcrizlhr', 'tcarride', -20.314442468008288),\n",
+       " (4001, 'vcrizlhr', 'tcarride', -20.314442468008288),\n",
+       " (4002, 'crizlhrt', 'arrideng', -20.025819952039228),\n",
+       " (2826, 'crizlhrn', 'arridena', -19.966185971501325),\n",
+       " (34, 'lozealrx', 'joinsink', -19.462213220012078)]"
+      ]
+     },
+     "execution_count": 95,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('carriden', rscb)\n",
+    "sorted(results, key=lambda r: r[3])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 96,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'g'"
+      ]
+     },
+     "execution_count": 96,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "caesar_encipher_letter('t', pos('n'))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 97,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(19, 13, 32)"
+      ]
+     },
+     "execution_count": 97,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pos('t'), pos('n'), pos('g')+26"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 98,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'n'"
+      ]
+     },
+     "execution_count": 98,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "unpos(pos('t') - pos('g'))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 99,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'rilynqnrdkgclphrbvinyaehtquonatalsrirychaanmnggivftvcrizlhrttjtfkxalivjzaebilletapvwzlitotsostrarddnqzlruhhril'"
+      ]
+     },
+     "execution_count": 99,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "rscb[3950:4060]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 100,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'tcarridenthe'"
+      ]
+     },
+     "execution_count": 100,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cat(unpos(pos(c) - pos(p)) for c, p in zip('vcrizlhrttjt', 'carridengacp'))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 101,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'zddntvcrizlhrntkvqmivjgslgqrhbwalsnqzvgltgkwmszalmypevdvtspkoobmfqayalgfygzolmvj'"
+      ]
+     },
+     "execution_count": 101,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "rscb[2820:2900]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 102,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'tcarriden'"
+      ]
+     },
+     "execution_count": 102,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cat(unpos(pos(c) - pos(p)) for c, p in zip('vcrizlhrn', 'carridena'))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 103,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'ycerevvtltfiewhxbxxalvfaanfkmzkjvvhdsvdyqlnlerhlnghkaiocsnqzeiocavghaabghzoebajclrgcumsnqwalgclpdrbvqxtvwjgvljaqbgxrgmhzayqamkkmvgalizfkjylnqrilkxbkhphjkstyhpavuvedizfaevzwrfqaqwxwoafaljtzwzkentgceqihguzkartwmxnlhptcsucthihqhvjaekkjtfevvrpzntsabgazlkrppthezuwlwdoabvctemhrhjjrdriljwpgzwzlruhhdnqstrardotsowzlitletapvbilivjzaexaljtfkttvcrizlhrnggivftnmaasrirychtalquonahtyaegclphrbvinnrdkynqrilerqewaauclrgcwmiayxzvavvtcditpllawtvjlwumkikczduvgaiazlpwmfxkryehezmilfkjypadhvjslfmlbcsnjzfhgxivjslwdgamnleucranqesrvzvfamnfzhvzpzglmaemzctdzwsnqwhlqafrlpstyaeqqrulvvetvcrizlhrvaokfjervvthzralhdycbehumlxhdndvltrmdvtzalmqrpctvjddhttalcacnghsetarfihqwaljtftfaglejprtlkoaqgctlsleavuanaalcrhcorewcsvnnqepbrstsrvzfvnwhwptvrtxwgaqwheekzgzdvtxpjotfmgnbvlrhcvzvkayfkoslfslbcmsnqlimfeqbixhwhogxveaebaaalqqzznfgttfrlwspaffufelkslfmlicmaaklbtwlroamnnnqlimghdhvypauqaymndhbehumlxhwaoianpimnfmvtarfamnflbtwxeenfkgaqxapvgzhaqizzrfgtarrwwydwfaxltbcgmnqlblyrofzwimkmharzevkalppwkanjarkahtlgcbgaeqqrjetwenlethrdrbovrnqpofvwsvvgkqqxhvrvlhtjihwaeqewpgzwsnqlfsbdgfuxvwkzastfirzmdhmeitwdgcbuhvzxofvgqbfalhvnhhtbugmlwrhhgkxtsemnleucdufamnfksfjpyfvaqeshdgkabmpfjllvtnpatbuqgclrgcwmwwibxhdnqzwtcjlhxhgbtslnuxjkhwahtmalrfamnfoavvwmfknkkmrgejuaakorrhwalrfwngtmqwkwrtkvthgslfmlbcmgfkjvzvtvtecgivrbzjhntkjtrkalplnqvgthalphrbvierijyqhgfauawhvsfjtpsksgkelwokevtyslfmlbumlhfvxnleghrfaqmnmlegxvehwhzpevzgclehrbvianqqrzevivxnlegalgalphrbvqphdwwkqqbqlbbwbfrfaqqgmltbbndrbgalvvqmivivtygzolmvjgfyalmfqaspkoobypevdvtzalmmszvgltgkwsnqwalgqrhbjgslkvqmivntvcrizlhrnrizddntovefaqaebaoinmalgqrhbtoifofqbqhqzfalfmlbcmlhqgrktivqhetahndklgqifoqrzzrrgxvixhgmwjtxvdetvnalwlitwadgkwwkwhtalqabfyxrujicmxtfxkvpyndlammhtgvallodthwhhkrdhxhhttnqwalvvqaivvvtrpkowbnnizvwgtyalmxqamtfypagkjfwvihrakcereivtubyjdtfypsgkjfsfjxrqslfmlbcmjzacodxhqhvvwlbumtbvtnpaxtsfvtbvqrwvtygvlaldgihqhvvwliumtxhwalpzmallnqxjgzonammrtwmxnlhptumucthkdvqqiloqrzzvsfxkryralwgzolmvjuhqhvypauqayanqhbmdgavtzhpaxfttlwlcmotodxjkqqrglalfmlbcmuqbqeqzrhkpuewpqivupagkjjkfusvrwsxbkpalqivqrtfsgzolmrctsogcthpzrhlkurvalrmcerjgthcmbpiotivtnhvzlhruhnrhkpumnqkllasfbhmalwmvulpxrrhvhrspirudrbknqfwhaivtzavianaleergtllgottbriafbhmalqmrbotfmmnytsogcthonqkpalhfpwetwqtfxkxapmuvgklnaaalmxqaspkowbuhdsmzkjvvhvwzzrvpjdwfafalpiogtnlvxahtpaskdzkhjburwngbonatrfihqtalqnzaclrgcumsnqkpaeqrqyqwrgxvpynqkuhtkvirvvgkhtalrbpmpvfamnfodvkavvvvhuwghwhsqmckitxhjnvgllujvksvtubgalfjbtxvsjtpstyalarifugnpgenqrrppckwimutlepermtyalmztoaymnqhvjslfslbcmsskslfmtbcmkugrgxhwhlvrnxyrrilffrgnbvlzfkovnvvtzhtntweaeeizyltjhvazehwalqqrjebadhgkumtbwbfgmajzhwhhxerjbznxbrralmztoaymnqhvdmrtumxnlhptcmucthkwsxnvnlwjptvjmudhhwhhrvetlwgtvxejwebajclrgcwmftfkalwskosthpaeqrgabmabwwslahtvcthviuewpqykvetxdzebajclrgcwszlgcrvjzfwjpgvtprvhdnraftfxkvpmtyalcqrhbxnqwhuktalvnebaaalwtkfbtkwlhtyaevvqmivvvtrpgowbanizvwsrrvwlxhvslfmlicmsnqkpayauruvxtfkalgtzmqwlalcfhdfqmyubmxhdggivslmalvfamnfglolmvjavrbzjantkjtfjsfjtasksgkjwfafaatalpwzbrerkhjcthctkjvvhtaljtfxkvpyndwaltgzagbrvslhqclrgcwmsnqkpaeqrfgwbwwslahtvcthonqkpaeqrevxnrerhwhqcrizlergalmzylerkszlevtuebaaaewzhmqstyalmrsbrxgivjebatalhhzdttvgaegqzootonahtddwjpcthamrthlhwalwmlmddofjoebaaalxpooqkctlejqjgntnponifjtfvtalqabghonnwaibbvthbrhkypgfjdaawbrhzibacdbtldsnqwwtxvwtfwndzddyqsszllhddgxvihzebajclggcwmklkrpetdwbonamhvpatorbshqhvypasrdailylgqbpgalphwalxklygodnmtyalgqrhxevzolvtovupstsveslialtxtalwwgwlzbrmfwfaqenqvghaemfqaspkowbprfgkwhwalwwethukvdmnviivfjvzwfdmksvtllnqiflwltefgjxhhgnbttvjrlgfpkrdyqdltxvwwvihiwfatalmzkhfdqrgofjuclphrbvqanqufamnnltsexalcpvwlxhdnqpmdhwsctznikgwgtluotlsnqvzlitxvtxrtbbnxhjtfkalizjsfjhhptdzrrnpgsjzvtqaeaebalbehumliwbgalcqdptiuhgbtealcfhdrvgqjzvvhvmzfnkkmrgejrhqobgbvhysbghhhljtfkkvwkstnbjdwamgamodevvgcthfvtdftxhwhhalppkgtnmgtyalbqasekowbtkquvnanqdtelslahnqehwalgqrhbqhhpaksfjooitxntxvggmddvtcofulvefaqstyhlvvgqjzvpmttalgqrhbxnqwhlvvxnlebtyaexpkoqkctlegaewsrxxrngxhtalqmlwaprurnnnqdwwruhhserfawbflhhalsmlmddjfjwechahfvggmdzefardatkndzllvehlcgidlrgalypvxbzvhiwfamuttbtrpqwvmikgkrzfpuwsvervmhwhhavgwbsrvzppkowbaaizvwtvnbpvdexapazpalhfpwetwcvwlhfvxhlmzyvbbilvrequmwgtwfaqaevvhhrvmhwalcqrhblqewfetrlgnzralkxvetlsctznnkgwgfhcthonqkpaeerevgqfulvtzhlmzktlpmahtryhphlalqagliubdfktngmtsksphvzyhqhvkakornsshpalhrzinnnqlbipinfeqkxvetejrhhtmhqqbgbvhexhdgfhxgvbbtalxklnatgmlbfgqbpgelphiofdmnlekrrvrtbwbflhqqaqcexbeetwcvwlbnctecgoxbkevgzahtmahtmkltadetwzbrhdybfxhzojauruhdxhgbtealroztalkrzfzwimoobqhvjgtyalenpkmrgpkfco'"
+      ]
+     },
+     "execution_count": 103,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "rwcb = wcat(cat(list(reversed(w))) for w in cat(c for c in cb if c in list(string.ascii_letters) + [' ']).split())\n",
+    "srwcb = sanitise(rwcb)\n",
+    "srwcb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 104,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(1825, 'umtxhwalpz', 'smiteindpm', -28.50776093446872),\n",
+       " (4294, 'uhdxhgbtea', 'shstesolen', -28.154834547829743),\n",
+       " (995, 'pofvwsvvgk', 'nourteingx', -27.846434452675233),\n",
+       " (2943, 'paeqrfgwbw', 'natmortobj', -27.53809559799773),\n",
+       " (78, 'jclrgcumsn', 'hcandohesa', -27.531431763709513),\n",
+       " (2262, 'aclrgcumsn', 'ycandohesa', -27.39244564415081),\n",
+       " (4134, 'shpalhrzin', 'qhewiteria', -27.25476095206763),\n",
+       " (374, 'clphrbvinn', 'aledoniana', -26.203058531983856),\n",
+       " (373, 'gclphrbvin', 'ecaledonia', -26.168829458085867),\n",
+       " (857, 'umlxhwaoia', 'smateingin', -24.245997114688997)]"
+      ]
+     },
+     "execution_count": 104,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "results = autokey_seek('caledonian', srwcb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 106,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[('snlqymcyucjsrqlihobhlxkgcbkqkb', -6901.94443579854),\n",
+       " ('smeqymcyuvjsrqlirobhjrzzcmsqkb', -6905.067152744593),\n",
+       " ('fmlqymqyuvjsrdwiribhjzzgcbsqkb', -6913.175393071053),\n",
+       " ('mzuwkedpyevihwjmmiccqqegtlrkm', -6917.074563428308),\n",
+       " ('vbuwkgdpudjirxzfficcqqeimlvkm', -6920.215764382421)]"
+      ]
+     },
+     "execution_count": 106,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "autokey_sa_break(srwcb, result_count=5, workers=3, max_iterations=10000, max_keylength=30)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 107,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "rev101 = cat(cat(reversed(c)) for c in chunks(scb, 101))\n",
+    "rev43 = cat(cat(reversed(c)) for c in chunks(scb, 43))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "autokey_sa_break(rev101, result_count=5, workers=3, max_iterations=10000, max_keylength=20)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "autokey_sa_break(rev43, result_count=5, workers=3, max_iterations=10000, max_keylength=20)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "scb = sanitise(cb)\n",
+    "rscb = cat(reversed(scb))\n",
+    "\n",
+    "unfiltered_transformed_ciphertexts = { \n",
+    "      'sanitised': scb\n",
+    "    , 'reversed' : rscb\n",
+    "    , 'scytale 43': scytale_decipher(scb, 43)\n",
+    "    , 'scytale 101': scytale_decipher(scb, 101)\n",
+    "    , 'scytale 43 reversed': scytale_decipher(rscb, 43)\n",
+    "    , 'scytale 101 reversed': scytale_decipher(rscb, 101)\n",
+    "    , 'chunk 43 reverse order': cat(reversed(chunks(scb, 43)))\n",
+    "    , 'chunk 101 reverse order': cat(reversed(chunks(scb, 101)))\n",
+    "    , 'chunk 43 reverse order reversed': cat(reversed(chunks(rscb, 43)))\n",
+    "    , 'chunk 101 reverse order reversed': cat(reversed(chunks(rscb, 101)))\n",
+    "    , 'rev_chunk 43': cat(cat(reversed(chunk)) for chunk in chunks(scb, 43))\n",
+    "    , 'rev_chunk 101': cat(cat(reversed(chunk)) for chunk in chunks(scb, 101))\n",
+    "    , 'rev_chunk 43 reversed': cat(cat(reversed(chunk)) for chunk in chunks(rscb, 43))\n",
+    "    , 'rev_chunk 101 reversed': cat(cat(reversed(chunk)) for chunk in chunks(rscb, 101))\n",
+    "    , 'rev nth 43': cat(cat(reversed(chunk)) for chunk in every_nth(scb, 43))\n",
+    "    , 'rev nth 101': cat(cat(reversed(chunk)) for chunk in every_nth(scb, 101))\n",
+    "    , 'rev nth 43 reversed': cat(cat(reversed(chunk)) for chunk in every_nth(rscb, 43))\n",
+    "    , 'rev nth 101 reversed': cat(cat(reversed(chunk)) for chunk in every_nth(rscb, 101))\n",
+    "    , 'unnth rev nth 43': combine_every_nth(cat(reversed(chunk)) for chunk in every_nth(scb, 43))\n",
+    "    , 'unnth rev nth 101': combine_every_nth(cat(reversed(chunk)) for chunk in every_nth(scb, 101))\n",
+    "    , 'unnth rev nth 43 reversed': combine_every_nth(cat(reversed(chunk)) for chunk in every_nth(rscb, 43))\n",
+    "    , 'unnth rev nth 101 reversed': combine_every_nth(cat(reversed(chunk)) for chunk in every_nth(rscb, 101))\n",
+    "}\n",
+    "\n",
+    "transformed_ciphertexts = {}\n",
+    "tc_duplicates = set()\n",
+    "for t in unfiltered_transformed_ciphertexts:\n",
+    "    if unfiltered_transformed_ciphertexts[t] not in tc_duplicates:\n",
+    "        transformed_ciphertexts[t] = unfiltered_transformed_ciphertexts[t]\n",
+    "        tc_duplicates.add(unfiltered_transformed_ciphertexts[t])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "scb = sanitise(cb)\n",
+    "rscb = cat(reversed(scb))\n",
+    "\n",
+    "unfiltered_transformed_ciphertexts = { \n",
+    "      'sanitised': scb\n",
+    "    , 'reversed' : rscb\n",
+    "    , 'scytale 43': scytale_encipher(scb, 43)\n",
+    "    , 'scytale 101': scytale_decipher(scb, 101)\n",
+    "    , 'scytale 43 reversed': scytale_decipher(rscb, 43)\n",
+    "    , 'scytale 101 reversed': scytale_decipher(rscb, 101)\n",
+    "    , 'chunk 43 reverse order': cat(reversed(chunks(scb, 43)))\n",
+    "    , 'chunk 101 reverse order': cat(reversed(chunks(scb, 101)))\n",
+    "    , 'chunk 43 reverse order reversed': cat(reversed(chunks(rscb, 43)))\n",
+    "    , 'chunk 101 reverse order reversed': cat(reversed(chunks(rscb, 101)))\n",
+    "    , 'rev_chunk 43': cat(cat(reversed(chunk)) for chunk in chunks(scb, 43))\n",
+    "    , 'rev_chunk 101': cat(cat(reversed(chunk)) for chunk in chunks(scb, 101))\n",
+    "    , 'rev_chunk 43 reversed': cat(cat(reversed(chunk)) for chunk in chunks(rscb, 43))\n",
+    "    , 'rev_chunk 101 reversed': cat(cat(reversed(chunk)) for chunk in chunks(rscb, 101))\n",
+    "    , 'rev nth 43': cat(cat(reversed(chunk)) for chunk in every_nth(scb, 43))\n",
+    "    , 'rev nth 101': cat(cat(reversed(chunk)) for chunk in every_nth(scb, 101))\n",
+    "    , 'rev nth 43 reversed': cat(cat(reversed(chunk)) for chunk in every_nth(rscb, 43))\n",
+    "    , 'rev nth 101 reversed': cat(cat(reversed(chunk)) for chunk in every_nth(rscb, 101))\n",
+    "    , 'unnth rev nth 43': combine_every_nth(cat(reversed(chunk)) for chunk in every_nth(scb, 43))\n",
+    "    , 'unnth rev nth 101': combine_every_nth(cat(reversed(chunk)) for chunk in every_nth(scb, 101))\n",
+    "    , 'unnth rev nth 43 reversed': combine_every_nth(cat(reversed(chunk)) for chunk in every_nth(rscb, 43))\n",
+    "    , 'unnth rev nth 101 reversed': combine_every_nth(cat(reversed(chunk)) for chunk in every_nth(rscb, 101))\n",
+    "}\n",
+    "\n",
+    "transformed_ciphertexts = {}\n",
+    "tc_duplicates = set()\n",
+    "for t in unfiltered_transformed_ciphertexts:\n",
+    "    if unfiltered_transformed_ciphertexts[t] not in tc_duplicates:\n",
+    "        transformed_ciphertexts[t] = unfiltered_transformed_ciphertexts[t]\n",
+    "        tc_duplicates.add(unfiltered_transformed_ciphertexts[t])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "len(unfiltered_transformed_ciphertexts), len(transformed_ciphertexts)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "vigenerekeys = {}\n",
+    "\n",
+    "for t in transformed_ciphertexts:\n",
+    "    ct = transformed_ciphertexts[t]\n",
+    "    key = vigenere_frequency_break(ct)\n",
+    "    print(\"Done\", t, \"for key\", key[0])\n",
+    "    vigenerekeys[t] = (key, vigenere_decipher(ct, key[0]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "autokeys = {}\n",
+    "\n",
+    "for t in transformed_ciphertexts:\n",
+    "    ct = transformed_ciphertexts[t]\n",
+    "    keys = autokey_sa_break(ct, result_count=3, workers=3, max_iterations=10000, max_keylength=20)\n",
+    "    print(\"Done\", t, \"for key\", keys[0][0])\n",
+    "    autokeys[t] = [(key, autokey_decipher(ct, key[0])) for key in keys]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "len(cb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "results = {}\n",
+    "for n in [43, 101]: # range(1, 61):\n",
+    "    sct = scytale_decipher(scb, n)\n",
+    "    rsct = cat(reversed(sct))\n",
+    "    keys = autokey_sa_break(rsct, result_count=3, workers=3, max_iterations=10000, max_keylength=20)\n",
+    "    results[n] = keys\n",
+    "    print(\"Done\", n, \" decipher for key\", keys[0][0])\n",
+    "    \n",
+    "    sct = scytale_encipher(scb, n)\n",
+    "    rsct = cat(reversed(sct))\n",
+    "    keys = autokey_sa_break(rsct, result_count=3, workers=3, max_iterations=10000, max_keylength=20)\n",
+    "    results[n] = keys\n",
+    "    print(\"Done\", n, \" decipher for key\", keys[0][0])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "results = {}\n",
+    "for n in range(1, 61):\n",
+    "    un_n_l = int(len(scb) / n)\n",
+    "    un_n_h = int(len(scb) / n) + 1\n",
+    "    \n",
+    "    if un_n_l not in results:\n",
+    "        sct = scytale_decipher(scb, un_n_l)\n",
+    "        rsct = cat(reversed(sct))\n",
+    "        keys = autokey_sa_break(rsct, result_count=3, workers=3, max_iterations=10000, max_keylength=20)\n",
+    "        results[un_n_l] = keys\n",
+    "        print(\"Done\", un_n_l, \"for key\", keys[0][0])\n",
+    "    \n",
+    "    if un_n_h not in results:\n",
+    "        sct = scytale_decipher(scb, un_n_h)\n",
+    "        rsct = cat(reversed(sct))\n",
+    "        keys = autokey_sa_break(rsct, result_count=3, workers=3, max_iterations=10000, max_keylength=20)\n",
+    "        results[un_n_h] = keys\n",
+    "        print(\"Done\", un_n_h, \"for key\", keys[0][0])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "for n in range(1, 61):\n",
+    "    sct = scytale_decipher(scb, n)\n",
+    "    rsct = cat(reversed(sct))\n",
+    "    results = autokey_seek('caledonia', rsct)\n",
+    "    print(n, [r[2] for r in sorted(results, key=lambda r: r[-1])[-5:]])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 109,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "rwcb = wcat(cat(reversed(w)) for w in cat(c for c in cb if c in string.ascii_letters + \" \").split())\n",
+    "srwcb = sanitise(rwcb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 110,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'ycerevvtltfiewhxbxxalvfaanfkmzkjvvhdsvdyqlnlerhlnghkaiocsnqzeiocavghaabghzoebajclrgcumsnqwalgclpdrbvqxtvwjgvljaqbgxrgmhzayqamkkmvgalizfkjylnqrilkxbkhphjkstyhpavuvedizfaevzwrfqaqwxwoafaljtzwzkentgceqihguzkartwmxnlhptcsucthihqhvjaekkjtfevvrpzntsabgazlkrppthezuwlwdoabvctemhrhjjrdriljwpgzwzlruhhdnqstrardotsowzlitletapvbilivjzaexaljtfkttvcrizlhrnggivftnmaasrirychtalquonahtyaegclphrbvinnrdkynqrilerqewaauclrgcwmiayxzvavvtcditpllawtvjlwumkikczduvgaiazlpwmfxkryehezmilfkjypadhvjslfmlbcsnjzfhgxivjslwdgamnleucranqesrvzvfamnfzhvzpzglmaemzctdzwsnqwhlqafrlpstyaeqqrulvvetvcrizlhrvaokfjervvthzralhdycbehumlxhdndvltrmdvtzalmqrpctvjddhttalcacnghsetarfihqwaljtftfaglejprtlkoaqgctlsleavuanaalcrhcorewcsvnnqepbrstsrvzfvnwhwptvrtxwgaqwheekzgzdvtxpjotfmgnbvlrhcvzvkayfkoslfslbcmsnqlimfeqbixhwhogxveaebaaalqqzznfgttfrlwspaffufelkslfmlicmaaklbtwlroamnnnqlimghdhvypauqaymndhbehumlxhwaoianpimnfmvtarfamnflbtwxeenfkgaqxapvgzhaqizzrfgtarrwwydwfaxltbcgmnqlblyrofzwimkmharzevkalppwkanjarkahtlgcbgaeqqrjetwenlethrdrbovrnqpofvwsvvgkqqxhvrvlhtjihwaeqewpgzwsnqlfsbdgfuxvwkzastfirzmdhmeitwdgcbuhvzxofvgqbfalhvnhhtbugmlwrhhgkxtsemnleucdufamnfksfjpyfvaqeshdgkabmpfjllvtnpatbuqgclrgcwmwwibxhdnqzwtcjlhxhgbtslnuxjkhwahtmalrfamnfoavvwmfknkkmrgejuaakorrhwalrfwngtmqwkwrtkvthgslfmlbcmgfkjvzvtvtecgivrbzjhntkjtrkalplnqvgthalphrbvierijyqhgfauawhvsfjtpsksgkelwokevtyslfmlbumlhfvxnleghrfaqmnmlegxvehwhzpevzgclehrbvianqqrzevivxnlegalgalphrbvqphdwwkqqbqlbbwbfrfaqqgmltbbndrbgalvvqmivivtygzolmvjgfyalmfqaspkoobypevdvtzalmmszvgltgkwsnqwalgqrhbjgslkvqmivntvcrizlhrnrizddntovefaqaebaoinmalgqrhbtoifofqbqhqzfalfmlbcmlhqgrktivqhetahndklgqifoqrzzrrgxvixhgmwjtxvdetvnalwlitwadgkwwkwhtalqabfyxrujicmxtfxkvpyndlammhtgvallodthwhhkrdhxhhttnqwalvvqaivvvtrpkowbnnizvwgtyalmxqamtfypagkjfwvihrakcereivtubyjdtfypsgkjfsfjxrqslfmlbcmjzacodxhqhvvwlbumtbvtnpaxtsfvtbvqrwvtygvlaldgihqhvvwliumtxhwalpzmallnqxjgzonammrtwmxnlhptumucthkdvqqiloqrzzvsfxkryralwgzolmvjuhqhvypauqayanqhbmdgavtzhpaxfttlwlcmotodxjkqqrglalfmlbcmuqbqeqzrhkpuewpqivupagkjjkfusvrwsxbkpalqivqrtfsgzolmrctsogcthpzrhlkurvalrmcerjgthcmbpiotivtnhvzlhruhnrhkpumnqkllasfbhmalwmvulpxrrhvhrspirudrbknqfwhaivtzavianaleergtllgottbriafbhmalqmrbotfmmnytsogcthonqkpalhfpwetwqtfxkxapmuvgklnaaalmxqaspkowbuhdsmzkjvvhvwzzrvpjdwfafalpiogtnlvxahtpaskdzkhjburwngbonatrfihqtalqnzaclrgcumsnqkpaeqrqyqwrgxvpynqkuhtkvirvvgkhtalrbpmpvfamnfodvkavvvvhuwghwhsqmckitxhjnvgllujvksvtubgalfjbtxvsjtpstyalarifugnpgenqrrppckwimutlepermtyalmztoaymnqhvjslfslbcmsskslfmtbcmkugrgxhwhlvrnxyrrilffrgnbvlzfkovnvvtzhtntweaeeizyltjhvazehwalqqrjebadhgkumtbwbfgmajzhwhhxerjbznxbrralmztoaymnqhvdmrtumxnlhptcmucthkwsxnvnlwjptvjmudhhwhhrvetlwgtvxejwebajclrgcwmftfkalwskosthpaeqrgabmabwwslahtvcthviuewpqykvetxdzebajclrgcwszlgcrvjzfwjpgvtprvhdnraftfxkvpmtyalcqrhbxnqwhuktalvnebaaalwtkfbtkwlhtyaevvqmivvvtrpgowbanizvwsrrvwlxhvslfmlicmsnqkpayauruvxtfkalgtzmqwlalcfhdfqmyubmxhdggivslmalvfamnfglolmvjavrbzjantkjtfjsfjtasksgkjwfafaatalpwzbrerkhjcthctkjvvhtaljtfxkvpyndwaltgzagbrvslhqclrgcwmsnqkpaeqrfgwbwwslahtvcthonqkpaeqrevxnrerhwhqcrizlergalmzylerkszlevtuebaaaewzhmqstyalmrsbrxgivjebatalhhzdttvgaegqzootonahtddwjpcthamrthlhwalwmlmddofjoebaaalxpooqkctlejqjgntnponifjtfvtalqabghonnwaibbvthbrhkypgfjdaawbrhzibacdbtldsnqwwtxvwtfwndzddyqsszllhddgxvihzebajclggcwmklkrpetdwbonamhvpatorbshqhvypasrdailylgqbpgalphwalxklygodnmtyalgqrhxevzolvtovupstsveslialtxtalwwgwlzbrmfwfaqenqvghaemfqaspkowbprfgkwhwalwwethukvdmnviivfjvzwfdmksvtllnqiflwltefgjxhhgnbttvjrlgfpkrdyqdltxvwwvihiwfatalmzkhfdqrgofjuclphrbvqanqufamnnltsexalcpvwlxhdnqpmdhwsctznikgwgtluotlsnqvzlitxvtxrtbbnxhjtfkalizjsfjhhptdzrrnpgsjzvtqaeaebalbehumliwbgalcqdptiuhgbtealcfhdrvgqjzvvhvmzfnkkmrgejrhqobgbvhysbghhhljtfkkvwkstnbjdwamgamodevvgcthfvtdftxhwhhalppkgtnmgtyalbqasekowbtkquvnanqdtelslahnqehwalgqrhbqhhpaksfjooitxntxvggmddvtcofulvefaqstyhlvvgqjzvpmttalgqrhbxnqwhlvvxnlebtyaexpkoqkctlegaewsrxxrngxhtalqmlwaprurnnnqdwwruhhserfawbflhhalsmlmddjfjwechahfvggmdzefardatkndzllvehlcgidlrgalypvxbzvhiwfamuttbtrpqwvmikgkrzfpuwsvervmhwhhavgwbsrvzppkowbaaizvwtvnbpvdexapazpalhfpwetwcvwlhfvxhlmzyvbbilvrequmwgtwfaqaevvhhrvmhwalcqrhblqewfetrlgnzralkxvetlsctznnkgwgfhcthonqkpaeerevgqfulvtzhlmzktlpmahtryhphlalqagliubdfktngmtsksphvzyhqhvkakornsshpalhrzinnnqlbipinfeqkxvetejrhhtmhqqbgbvhexhdgfhxgvbbtalxklnatgmlbfgqbpgelphiofdmnlekrrvrtbwbflhqqaqcexbeetwcvwlbnctecgoxbkevgzahtmahtmkltadetwzbrhdybfxhzojauruhdxhgbtealroztalkrzfzwimoobqhvjgtyalenpkmrgpkfco'"
+      ]
+     },
+     "execution_count": 110,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "srwcb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 111,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('attttttttttl', -23081.56936918698)"
+      ]
+     },
+     "execution_count": 111,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "vigenere_frequency_break(srwcb, fitness=Ptrigrams)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "beaufort_frequency_break(srwcb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "brwp = beaufort_decipher(srwcb, 'oeypytyhyttnttytoty' )\n",
+    "brwp"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "results = autokey_seek('caledonia', brwp)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "results = autokey_seek('caledonia', caesar_decipher(srwcb, pos('t')))\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "akt = autokey_encipher(sanitise(p7b), 'caledonia')\n",
+    "akt"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "results = autokey_seek('caledonia', akt)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "tpack(segment(vigenere_decipher(srwcb, 'attttttttttl')))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "results = {}\n",
+    "for n in [43, 47, 101, 211]:\n",
+    "    sct = scytale_decipher(srwcb, n)\n",
+    "    rsct = cat(reversed(sct))\n",
+    "    keys = autokey_sa_break(rsct, result_count=3, workers=3, max_iterations=10000, max_keylength=20)\n",
+    "    results[n] = keys\n",
+    "    print(\"Done\", n, \" decipher for key\", keys[0][0])\n",
+    "    \n",
+    "    sct = scytale_encipher(srwcb, n)\n",
+    "    rsct = cat(reversed(sct))\n",
+    "    keys = autokey_sa_break(rsct, result_count=3, workers=3, max_iterations=10000, max_keylength=20)\n",
+    "    results[n] = keys\n",
+    "    print(\"Done\", n, \" encipher for key\", keys[0][0])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "results = {}\n",
+    "for n in [43, 47, 101, 211]:\n",
+    "    sct = scytale_decipher(srwcb, n)\n",
+    "    rsct = cat(reversed(sct))\n",
+    "    key = vigenere_frequency_break(rsct)\n",
+    "    results[n] = keys\n",
+    "    print(\"Done\", n, \" decipher for key\", key[0])\n",
+    "    \n",
+    "    sct = scytale_encipher(srwcb, n)\n",
+    "    rsct = cat(reversed(sct))\n",
+    "    key = vigenere_frequency_break(rsct)\n",
+    "    results[n] = keys\n",
+    "    print(\"Done\", n, \" encipher for key\", key[0])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "results = autokey_seek('caledonia', srwcb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "results = autokey_seek('caledoni', srwcb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "results = autokey_seek(cat(reversed('caledonian')), srwcb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "results = autokey_seek('salustius', srwcb)\n",
+    "sorted(results, key=lambda r: r[-1])[-10:]"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    ">>>from pycipher import Autokey\n",
+    ">>>Autokey('HELLO').encipher('defend the east wall of the castle')\n",
+    "'KIQPBGXMIRDLAAELDHBTSPQFLAPG'\n",
+    ">>>Autokey('HELLO').decipher('KIQPBGXMIRDLAAELDHBTSPQFLAPG')\n",
+    "'DEFENDTHEEASTWALLOFTHECASTLE'"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "akt = autokey_encipher(sanitise('defend the east wall of the castle'), 'hello')\n",
+    "akt"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "wcat(segment(autokey_decipher('kiqpbgxmirdlaaeldhbtspqflapg', 'hello')))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "autokey_seek('defend', akt)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "results = {}\n",
+    "for n in [43, 47, 101, 211]:\n",
+    "    sct = scytale_decipher(srwcb, n)\n",
+    "    rsct = cat(reversed(sct))\n",
+    "    results = autokey_seek('caledonai', srwcb)\n",
+    "    print(\"decipher\", [(r[0], r[2]) for r in sorted(results, key=lambda r: r[-1])[-5:]])\n",
+    "    \n",
+    "    sct = scytale_encipher(srwcb, n)\n",
+    "    rsct = cat(reversed(sct))\n",
+    "    results = autokey_seek('caledonai', srwcb)\n",
+    "    print(\"encipher\", [(r[0], r[2]) for r in sorted(results, key=lambda r: r[-1])[-5:]])\n",
+    "    "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "results = {}\n",
+    "for n in [12]:\n",
+    "    sct = scytale_decipher(srwcb, n)\n",
+    "    rsct = cat(reversed(sct))\n",
+    "    results = autokey_seek('caledonai', srwcb)\n",
+    "    print(\"decipher\", [(r[0], r[2]) for r in sorted(results, key=lambda r: r[-1])[-10:]])\n",
+    "    \n",
+    "    sct = scytale_encipher(srwcb, n)\n",
+    "    rsct = cat(reversed(sct))\n",
+    "    results = autokey_seek('caledonai', srwcb)\n",
+    "    print(\"encipher\", [(r[0], r[2]) for r in sorted(results, key=lambda r: r[-1])[-10:]])\n",
+    "    "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "fc = collections.Counter(sanitise(scb))\n",
+    "plot_frequency_histogram(fc, sort_key=fc.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "vigenere_frequency_break(srwcb, max_key_length=12)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "caesar_decipher(srwcb, pos('t'))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "column_transposition_break_mp(caesar_decipher(srwcb, pos('t')))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "column_transposition_decipher(  caesar_decipher(srwcb, pos('t'))\n",
+    "                              , (4, 0, 2, 3, 6, 7, 5, 1)\n",
+    "                              , fillcolumnwise=False\n",
+    "                              , emptycolumnwise=True)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "autokey_decipher(srwcb, 'abcdefghijkl')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ics = [(i, sum(index_of_coincidence(section) for section in every_nth(srwcb, i)) / i)\n",
+    "       for i in range(1, 30)]\n",
+    "sorted(ics, key=lambda p: p[1])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 112,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:418: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n",
+      "  \"matplotlib is currently using a non-GUI backend, \"\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7fd56e510f60>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fc = collections.Counter(every_nth(srwcb, 12)[2])\n",
+    "plot_frequency_histogram(fc, sort_key=fc.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 113,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['ycerevvtltfi',\n",
+       " 'ewhxbxxalvfa',\n",
+       " 'anfkmzkjvvhd',\n",
+       " 'svdyqlnlerhl',\n",
+       " 'nghkaiocsnqz',\n",
+       " 'eiocavghaabg',\n",
+       " 'hzoebajclrgc',\n",
+       " 'umsnqwalgclp',\n",
+       " 'drbvqxtvwjgv',\n",
+       " 'ljaqbgxrgmhz',\n",
+       " 'ayqamkkmvgal',\n",
+       " 'izfkjylnqril',\n",
+       " 'kxbkhphjksty',\n",
+       " 'hpavuvedizfa',\n",
+       " 'evzwrfqaqwxw',\n",
+       " 'oafaljtzwzke',\n",
+       " 'ntgceqihguzk',\n",
+       " 'artwmxnlhptc',\n",
+       " 'sucthihqhvja',\n",
+       " 'ekkjtfevvrpz',\n",
+       " 'ntsabgazlkrp',\n",
+       " 'pthezuwlwdoa',\n",
+       " 'bvctemhrhjjr',\n",
+       " 'driljwpgzwzl',\n",
+       " 'ruhhdnqstrar',\n",
+       " 'dotsowzlitle',\n",
+       " 'tapvbilivjza',\n",
+       " 'exaljtfkttvc',\n",
+       " 'rizlhrnggivf',\n",
+       " 'tnmaasrirych',\n",
+       " 'talquonahtya',\n",
+       " 'egclphrbvinn',\n",
+       " 'rdkynqrilerq',\n",
+       " 'ewaauclrgcwm',\n",
+       " 'iayxzvavvtcd',\n",
+       " 'itpllawtvjlw',\n",
+       " 'umkikczduvga',\n",
+       " 'iazlpwmfxkry',\n",
+       " 'ehezmilfkjyp',\n",
+       " 'adhvjslfmlbc',\n",
+       " 'snjzfhgxivjs',\n",
+       " 'lwdgamnleucr',\n",
+       " 'anqesrvzvfam',\n",
+       " 'nfzhvzpzglma',\n",
+       " 'emzctdzwsnqw',\n",
+       " 'hlqafrlpstya',\n",
+       " 'eqqrulvvetvc',\n",
+       " 'rizlhrvaokfj',\n",
+       " 'ervvthzralhd',\n",
+       " 'ycbehumlxhdn',\n",
+       " 'dvltrmdvtzal',\n",
+       " 'mqrpctvjddht',\n",
+       " 'talcacnghset',\n",
+       " 'arfihqwaljtf',\n",
+       " 'tfaglejprtlk',\n",
+       " 'oaqgctlsleav',\n",
+       " 'uanaalcrhcor',\n",
+       " 'ewcsvnnqepbr',\n",
+       " 'stsrvzfvnwhw',\n",
+       " 'ptvrtxwgaqwh',\n",
+       " 'eekzgzdvtxpj',\n",
+       " 'otfmgnbvlrhc',\n",
+       " 'vzvkayfkoslf',\n",
+       " 'slbcmsnqlimf',\n",
+       " 'eqbixhwhogxv',\n",
+       " 'eaebaaalqqzz',\n",
+       " 'nfgttfrlwspa',\n",
+       " 'ffufelkslfml',\n",
+       " 'icmaaklbtwlr',\n",
+       " 'oamnnnqlimgh',\n",
+       " 'dhvypauqaymn',\n",
+       " 'dhbehumlxhwa',\n",
+       " 'oianpimnfmvt',\n",
+       " 'arfamnflbtwx',\n",
+       " 'eenfkgaqxapv',\n",
+       " 'gzhaqizzrfgt',\n",
+       " 'arrwwydwfaxl',\n",
+       " 'tbcgmnqlblyr',\n",
+       " 'ofzwimkmharz',\n",
+       " 'evkalppwkanj',\n",
+       " 'arkahtlgcbga',\n",
+       " 'eqqrjetwenle',\n",
+       " 'thrdrbovrnqp',\n",
+       " 'ofvwsvvgkqqx',\n",
+       " 'hvrvlhtjihwa',\n",
+       " 'eqewpgzwsnql',\n",
+       " 'fsbdgfuxvwkz',\n",
+       " 'astfirzmdhme',\n",
+       " 'itwdgcbuhvzx',\n",
+       " 'ofvgqbfalhvn',\n",
+       " 'hhtbugmlwrhh',\n",
+       " 'gkxtsemnleuc',\n",
+       " 'dufamnfksfjp',\n",
+       " 'yfvaqeshdgka',\n",
+       " 'bmpfjllvtnpa',\n",
+       " 'tbuqgclrgcwm',\n",
+       " 'wwibxhdnqzwt',\n",
+       " 'cjlhxhgbtsln',\n",
+       " 'uxjkhwahtmal',\n",
+       " 'rfamnfoavvwm',\n",
+       " 'fknkkmrgejua',\n",
+       " 'akorrhwalrfw',\n",
+       " 'ngtmqwkwrtkv',\n",
+       " 'thgslfmlbcmg',\n",
+       " 'fkjvzvtvtecg',\n",
+       " 'ivrbzjhntkjt',\n",
+       " 'rkalplnqvgth',\n",
+       " 'alphrbvierij',\n",
+       " 'yqhgfauawhvs',\n",
+       " 'fjtpsksgkelw',\n",
+       " 'okevtyslfmlb',\n",
+       " 'umlhfvxnlegh',\n",
+       " 'rfaqmnmlegxv',\n",
+       " 'ehwhzpevzgcl',\n",
+       " 'ehrbvianqqrz',\n",
+       " 'evivxnlegalg',\n",
+       " 'alphrbvqphdw',\n",
+       " 'wkqqbqlbbwbf',\n",
+       " 'rfaqqgmltbbn',\n",
+       " 'drbgalvvqmiv',\n",
+       " 'ivtygzolmvjg',\n",
+       " 'fyalmfqaspko',\n",
+       " 'obypevdvtzal',\n",
+       " 'mmszvgltgkws',\n",
+       " 'nqwalgqrhbjg',\n",
+       " 'slkvqmivntvc',\n",
+       " 'rizlhrnrizdd',\n",
+       " 'ntovefaqaeba',\n",
+       " 'oinmalgqrhbt',\n",
+       " 'oifofqbqhqzf',\n",
+       " 'alfmlbcmlhqg',\n",
+       " 'rktivqhetahn',\n",
+       " 'dklgqifoqrzz',\n",
+       " 'rrgxvixhgmwj',\n",
+       " 'txvdetvnalwl',\n",
+       " 'itwadgkwwkwh',\n",
+       " 'talqabfyxruj',\n",
+       " 'icmxtfxkvpyn',\n",
+       " 'dlammhtgvall',\n",
+       " 'odthwhhkrdhx',\n",
+       " 'hhttnqwalvvq',\n",
+       " 'aivvvtrpkowb',\n",
+       " 'nnizvwgtyalm',\n",
+       " 'xqamtfypagkj',\n",
+       " 'fwvihrakcere',\n",
+       " 'ivtubyjdtfyp',\n",
+       " 'sgkjfsfjxrqs',\n",
+       " 'lfmlbcmjzaco',\n",
+       " 'dxhqhvvwlbum',\n",
+       " 'tbvtnpaxtsfv',\n",
+       " 'tbvqrwvtygvl',\n",
+       " 'aldgihqhvvwl',\n",
+       " 'iumtxhwalpzm',\n",
+       " 'allnqxjgzona',\n",
+       " 'mmrtwmxnlhpt',\n",
+       " 'umucthkdvqqi',\n",
+       " 'loqrzzvsfxkr',\n",
+       " 'yralwgzolmvj',\n",
+       " 'uhqhvypauqay',\n",
+       " 'anqhbmdgavtz',\n",
+       " 'hpaxfttlwlcm',\n",
+       " 'otodxjkqqrgl',\n",
+       " 'alfmlbcmuqbq',\n",
+       " 'eqzrhkpuewpq',\n",
+       " 'ivupagkjjkfu',\n",
+       " 'svrwsxbkpalq',\n",
+       " 'ivqrtfsgzolm',\n",
+       " 'rctsogcthpzr',\n",
+       " 'hlkurvalrmce',\n",
+       " 'rjgthcmbpiot',\n",
+       " 'ivtnhvzlhruh',\n",
+       " 'nrhkpumnqkll',\n",
+       " 'asfbhmalwmvu',\n",
+       " 'lpxrrhvhrspi',\n",
+       " 'rudrbknqfwha',\n",
+       " 'ivtzavianale',\n",
+       " 'ergtllgottbr',\n",
+       " 'iafbhmalqmrb',\n",
+       " 'otfmmnytsogc',\n",
+       " 'thonqkpalhfp',\n",
+       " 'wetwqtfxkxap',\n",
+       " 'muvgklnaaalm',\n",
+       " 'xqaspkowbuhd',\n",
+       " 'smzkjvvhvwzz',\n",
+       " 'rvpjdwfafalp',\n",
+       " 'iogtnlvxahtp',\n",
+       " 'askdzkhjburw',\n",
+       " 'ngbonatrfihq',\n",
+       " 'talqnzaclrgc',\n",
+       " 'umsnqkpaeqrq',\n",
+       " 'yqwrgxvpynqk',\n",
+       " 'uhtkvirvvgkh',\n",
+       " 'talrbpmpvfam',\n",
+       " 'nfodvkavvvvh',\n",
+       " 'uwghwhsqmcki',\n",
+       " 'txhjnvgllujv',\n",
+       " 'ksvtubgalfjb',\n",
+       " 'txvsjtpstyal',\n",
+       " 'arifugnpgenq',\n",
+       " 'rrppckwimutl',\n",
+       " 'epermtyalmzt',\n",
+       " 'oaymnqhvjslf',\n",
+       " 'slbcmsskslfm',\n",
+       " 'tbcmkugrgxhw',\n",
+       " 'hlvrnxyrrilf',\n",
+       " 'frgnbvlzfkov',\n",
+       " 'nvvtzhtntwea',\n",
+       " 'eeizyltjhvaz',\n",
+       " 'ehwalqqrjeba',\n",
+       " 'dhgkumtbwbfg',\n",
+       " 'majzhwhhxerj',\n",
+       " 'bznxbrralmzt',\n",
+       " 'oaymnqhvdmrt',\n",
+       " 'umxnlhptcmuc',\n",
+       " 'thkwsxnvnlwj',\n",
+       " 'ptvjmudhhwhh',\n",
+       " 'rvetlwgtvxej',\n",
+       " 'webajclrgcwm',\n",
+       " 'ftfkalwskost',\n",
+       " 'hpaeqrgabmab',\n",
+       " 'wwslahtvcthv',\n",
+       " 'iuewpqykvetx',\n",
+       " 'dzebajclrgcw',\n",
+       " 'szlgcrvjzfwj',\n",
+       " 'pgvtprvhdnra',\n",
+       " 'ftfxkvpmtyal',\n",
+       " 'cqrhbxnqwhuk',\n",
+       " 'talvnebaaalw',\n",
+       " 'tkfbtkwlhtya',\n",
+       " 'evvqmivvvtrp',\n",
+       " 'gowbanizvwsr',\n",
+       " 'rvwlxhvslfml',\n",
+       " 'icmsnqkpayau',\n",
+       " 'ruvxtfkalgtz',\n",
+       " 'mqwlalcfhdfq',\n",
+       " 'myubmxhdggiv',\n",
+       " 'slmalvfamnfg',\n",
+       " 'lolmvjavrbzj',\n",
+       " 'antkjtfjsfjt',\n",
+       " 'asksgkjwfafa',\n",
+       " 'atalpwzbrerk',\n",
+       " 'hjcthctkjvvh',\n",
+       " 'taljtfxkvpyn',\n",
+       " 'dwaltgzagbrv',\n",
+       " 'slhqclrgcwms',\n",
+       " 'nqkpaeqrfgwb',\n",
+       " 'wwslahtvctho',\n",
+       " 'nqkpaeqrevxn',\n",
+       " 'rerhwhqcrizl',\n",
+       " 'ergalmzylerk',\n",
+       " 'szlevtuebaaa',\n",
+       " 'ewzhmqstyalm',\n",
+       " 'rsbrxgivjeba',\n",
+       " 'talhhzdttvga',\n",
+       " 'egqzootonaht',\n",
+       " 'ddwjpcthamrt',\n",
+       " 'hlhwalwmlmdd',\n",
+       " 'ofjoebaaalxp',\n",
+       " 'ooqkctlejqjg',\n",
+       " 'ntnponifjtfv',\n",
+       " 'talqabghonnw',\n",
+       " 'aibbvthbrhky',\n",
+       " 'pgfjdaawbrhz',\n",
+       " 'ibacdbtldsnq',\n",
+       " 'wwtxvwtfwndz',\n",
+       " 'ddyqsszllhdd',\n",
+       " 'gxvihzebajcl',\n",
+       " 'ggcwmklkrpet',\n",
+       " 'dwbonamhvpat',\n",
+       " 'orbshqhvypas',\n",
+       " 'rdailylgqbpg',\n",
+       " 'alphwalxklyg',\n",
+       " 'odnmtyalgqrh',\n",
+       " 'xevzolvtovup',\n",
+       " 'stsveslialtx',\n",
+       " 'talwwgwlzbrm',\n",
+       " 'fwfaqenqvgha',\n",
+       " 'emfqaspkowbp',\n",
+       " 'rfgkwhwalwwe',\n",
+       " 'thukvdmnviiv',\n",
+       " 'fjvzwfdmksvt',\n",
+       " 'llnqiflwltef',\n",
+       " 'gjxhhgnbttvj',\n",
+       " 'rlgfpkrdyqdl',\n",
+       " 'txvwwvihiwfa',\n",
+       " 'talmzkhfdqrg',\n",
+       " 'ofjuclphrbvq',\n",
+       " 'anqufamnnlts',\n",
+       " 'exalcpvwlxhd',\n",
+       " 'nqpmdhwsctzn',\n",
+       " 'ikgwgtluotls',\n",
+       " 'nqvzlitxvtxr',\n",
+       " 'tbbnxhjtfkal',\n",
+       " 'izjsfjhhptdz',\n",
+       " 'rrnpgsjzvtqa',\n",
+       " 'eaebalbehuml',\n",
+       " 'iwbgalcqdpti',\n",
+       " 'uhgbtealcfhd',\n",
+       " 'rvgqjzvvhvmz',\n",
+       " 'fnkkmrgejrhq',\n",
+       " 'obgbvhysbghh',\n",
+       " 'hljtfkkvwkst',\n",
+       " 'nbjdwamgamod',\n",
+       " 'evvgcthfvtdf',\n",
+       " 'txhwhhalppkg',\n",
+       " 'tnmgtyalbqas',\n",
+       " 'ekowbtkquvna',\n",
+       " 'nqdtelslahnq',\n",
+       " 'ehwalgqrhbqh',\n",
+       " 'hpaksfjooitx',\n",
+       " 'ntxvggmddvtc',\n",
+       " 'ofulvefaqsty',\n",
+       " 'hlvvgqjzvpmt',\n",
+       " 'talgqrhbxnqw',\n",
+       " 'hlvvxnlebtya',\n",
+       " 'expkoqkctleg',\n",
+       " 'aewsrxxrngxh',\n",
+       " 'talqmlwaprur',\n",
+       " 'nnnqdwwruhhs',\n",
+       " 'erfawbflhhal',\n",
+       " 'smlmddjfjwec',\n",
+       " 'hahfvggmdzef',\n",
+       " 'ardatkndzllv',\n",
+       " 'ehlcgidlrgal',\n",
+       " 'ypvxbzvhiwfa',\n",
+       " 'muttbtrpqwvm',\n",
+       " 'ikgkrzfpuwsv',\n",
+       " 'ervmhwhhavgw',\n",
+       " 'bsrvzppkowba',\n",
+       " 'aizvwtvnbpvd',\n",
+       " 'exapazpalhfp',\n",
+       " 'wetwcvwlhfvx',\n",
+       " 'hlmzyvbbilvr',\n",
+       " 'equmwgtwfaqa',\n",
+       " 'evvhhrvmhwal',\n",
+       " 'cqrhblqewfet',\n",
+       " 'rlgnzralkxve',\n",
+       " 'tlsctznnkgwg',\n",
+       " 'fhcthonqkpae',\n",
+       " 'erevgqfulvtz',\n",
+       " 'hlmzktlpmaht',\n",
+       " 'ryhphlalqagl',\n",
+       " 'iubdfktngmts',\n",
+       " 'ksphvzyhqhvk',\n",
+       " 'akornsshpalh',\n",
+       " 'rzinnnqlbipi',\n",
+       " 'nfeqkxvetejr',\n",
+       " 'hhtmhqqbgbvh',\n",
+       " 'exhdgfhxgvbb',\n",
+       " 'talxklnatgml',\n",
+       " 'bfgqbpgelphi',\n",
+       " 'ofdmnlekrrvr',\n",
+       " 'tbwbflhqqaqc',\n",
+       " 'exbeetwcvwlb',\n",
+       " 'nctecgoxbkev',\n",
+       " 'gzahtmahtmkl',\n",
+       " 'tadetwzbrhdy',\n",
+       " 'bfxhzojauruh',\n",
+       " 'dxhgbtealroz',\n",
+       " 'talkrzfzwimo',\n",
+       " 'obqhvjgtyale',\n",
+       " 'npkmrgpkfco']"
+      ]
+     },
+     "execution_count": 113,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "chunks(srwcb, 12)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 114,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# hill_matrix = [[1] * (i + 1) + [0] * (12 - (i + 1)) for i in range(12)]\n",
+    "# hill_matrix"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 47,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n",
+       " [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n",
+       " [0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],\n",
+       " [0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],\n",
+       " [0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0],\n",
+       " [0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0],\n",
+       " [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0],\n",
+       " [0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0],\n",
+       " [0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0],\n",
+       " [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0],\n",
+       " [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0],\n",
+       " [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1]]"
+      ]
+     },
+     "execution_count": 47,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "hill_matrix = [list(reversed([0] * (12 - (i + 1)) + [1, 1] + [0] * 12))[-12:] for i in range(12)]\n",
+    "hill_matrix"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 48,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'yearningforrespitetheromanssufferedasdaysturnedintoweeksandweeksintomonthswithcalgacusandthecaledoniiperfectlycontenttolaysiegeintheirownlandourknowledgeofthisdreadfulperiodcomesfromthefollowingaccountbymarcusfideliuscatoundersiegeforninelongmonthstrappedbywallswebuilttodefendourselvesherdedandpennedlikesheepwithinourrefugethefortatcarridenagainstusisarrayedthemightofthecaledonianarmyandournemesiscalgacusisgrinningwhilehewatchesussquirminthishellbetrayedbyourownleadersalustiusvolunteersallsomanygoodandbraveromanshavelosttheirlivesandthemoraleofthemenhereatcarridenisworseningbythedayexhaustedandstarvingthemencatchwhattheycantoeataroundthefortmostlyratssomecatsalthoughtheytooareskinandbonesbravebutdesperatesomespeakprivatelyofamutinytooverthrowsalustiusandiamtemptedtoagreewiththemevensoforallhisfaultssalustiusisstillaromanandiamunderhiscommandexhaustedthoughiambeingaromanstillmeanssomethingtomeevensofarawayfromlatiumanditsglorioussunneverthelessifearthatsoonthemenwillturntodarkerandmoresavagemethodstofeedthemselvesandifnoprogresshasbeenmadeiwillsoonhavetoreconsiderwhatimustdotogetasmanygoodromanssafelyhomeaspossiblebidinghistimecalgacuswaitedandwatcheduntilhejudgedthattheromansweresufficientlyweakenedthensentamessengertosalustiusofferingpeaceinexchangeforthelandsofcaledoniaenvoyspromisedsafepassageallowingsalustiustoreturntoromeifheagreedtoleavecaledoniaandneverreturnthecaledoniihadtwoconditionsromemustabandontheremainingsoldiersoftheixthlegionleavingthemashostagesandthecodexmustremainatcarridenarrivinginromewithoutthecodexwouldcondemnsalustiustocertaindeathandhecouldneveragreetosuchtermsbuthestillpossessedthemonsgraupiusforgeryandisuspecthehopedtotradethatandtheremaininglegionnairesoftheixthforhisownfreedomyearningonlyforhisownsafetysalustiusriskedunderestimatinghisfoebutindoingsohealsounderestimatedtheloyalanduprightmarcusfideliuscatowhocouldneverbetraythesoldiersunderhiscommandexposingthisfatallackofjudgementsalustiuscondemnedhimselfinhisownwordsdoiknowthemindofasoldierlikecatobythegodsidoyearsofcampaigninghavehardenedhimandhehasnotthesubtletytoharbourdarkandcunningthoughtsmentalagilityisnotthemarkofamanlikecatoandhistorywillforgethimintruththeixthlegionhadsufferedseverelyfromtheligaturethatwasslowlydrawntightaroundthembycalgacusandhismendysenteryandhungerravagedthenobleromanswhowerereducedtoemaciatedghostschokingonthebitterbileofthearroganceandrapaciouscrueltyoftheircommandersalustiusassalustiusscentedtherankodourofmutinybeginningtofilltheairhepunishedthemenwithdecimationsomovedtotearsbypitytheircommandermarcusfideliuscatowasfinallypersuadedtotreatsecretlywithcalgacusforthesakeofhismenthusitwasthatcatohimselftreatedwithcalgacushecarefullypreparedanewforgeryofthecodexandtogetherwiththestrongestoftheremaininglegionnairesarrestedsalustiusandhisguardsforthecrimestheyhadcommittedagainsttheromansoldiersinexchangeforsafepassagefromthathellonearthcatoofferedtheforgeryandtheprisonerstocalgacusandhismensoitwasthatcatoandhismenreturnedtocarridentheirheartsheavywiththeshameoftheirbargainwiththedevilinthecoldlightofdawncatomarchedthesurvivorswiththetwoaquilaeflyinghighbeforethemontoanawaitingbarqueprovisionedwithvitalsandwaterforfivedaysashehadagreedwithcalgacusstrappedtighttohisbodyunderhisarmourheconcealedthetruecopyofthecodexholdinginhisbreastplatethesecurityofromeandsotheixthlegioncrossedtheseatogermaniainferiormakinglandfallatlugdunumbatavorumtwodayslaterfreedfromtheirtormentorscaledoniiandromanaliketheyrestedandmadesacrificesofgoatsandsheepingratitudefortheirsafedeliveranceovercomewithexhaustiontheysleptuntiltheyhadrecoveredsufficientlytocontinueontothefortressatnoviomaguswherecatoreportedtothelegatusofthexthlegiongeminaandatlasthandedthecodextohissafekeepingreceivingwordinromeoftherecoveryofthecodexandthereturnofthetwoaquilaecaesargrantedthemallpardonandawardedpensionstothesurvivorseachtoreceiveafarmoffiveherediumwhentheyretiredfrommilitaryserviceglorywasdeniedtothosebravelegionnairesbutihopethishistorywillrestoretheirhonourenemiesofromeweredeniedthecodexoccultarumbythegreatsacrificesofcatoandhismenrecordingtheirtaleisperhapsthemostimportanttaskihaveundertakenasahistoriananditpainsmegreatlythattocontinuetoprotectitthetruthmustbeconcealedformanygenerationstocomeyetiwillrestinpeaceknowingthatthattruthwillonedaybetoldguardeduntilthenbythegloriouswondersoftheancientworldx'"
+      ]
+     },
+     "execution_count": 48,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "hill_decipher(hill_matrix, srwcb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 49,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'YEARNING FOR RESPITE THE ROMANS SUFFERED AS DAYS TURNED INTO WEEKS AND WEEKS INTO MONTHS, WITH CALGACUS AND THE CALEDONII PERFECTLY CONTENT TO LAY SIEGE IN THEIR OWN LAND. OUR KNOWLEDGE OF THIS DREADFUL PERIOD COMES FROM THE FOLLOWING ACCOUNT BY MARCUS FIDELIUS CATO.“ UNDER SIEGE FOR NINE LONG MONTHS, TRAPPED BY WALLS WE BUILT TO DEFEND OURSELVES. HERDED AND PENNED LIKE SHEEP WITHIN OUR REFUGE, THE FORT AT CARRIDEN. AGAINST US IS ARRAYED THE MIGHT OF THE CALEDONIAN ARMY, AND OUR NEMESIS CALGACUS IS GRINNING WHILE HE WATCHES US SQUIRM IN THIS HELL, BETRAYED BY OUR OWN LEADER SALUSTIUS. VOLUNTEERS ALL, SO MANY GOOD AND BRAVE ROMANS HAVE LOST THEIR LIVES, AND THE MORALE OF THE MEN HERE AT CARRIDEN IS WORSENING BY THE DAY. EXHAUSTED AND STARVING THE MEN CATCH WHAT THEY CAN TO EAT AROUND THE FORT, MOSTLY RATS, SOME CATS, ALTHOUGH THEY TOO ARE SKIN AND BONES. BRAVE BUT DESPERATE, SOME SPEAK PRIVATELY OF A MUTINY TO OVERTHROW SALUSTIUS, AND I AM TEMPTED TO AGREE WITH THEM. EVEN SO, FOR ALL HIS FAULTS, SALUSTIUS IS STILL A ROMAN AND I AM UNDER HIS COMMAND. EXHAUSTED THOUGH I AM, BEING A ROMAN STILL MEANS SOMETHING TO ME, EVEN SO FAR AWAY FROM LATIUM AND ITS GLORIOUS SUN. NEVERTHELESS, I FEAR THAT SOON THE MEN WILL TURN TO DARKER AND MORE SAVAGE METHODS TO FEED THEMSELVES AND IF NO PROGRESS HAS BEEN MADE, I WILL SOON HAVE TO RECONSIDER WHAT I MUST DO TO GET AS MANY GOOD ROMANS SAFELY HOME AS POSSIBLE.” BIDING HIS TIME CALGACUS WAITED AND WATCHED UNTIL HE JUDGED THAT THE ROMANS WERE SUFFICIENTLY WEAKENED, THEN SENT A MESSENGER TO SALUSTIUS OFFERING PEACE IN EXCHANGE FOR THE LANDS OF CALEDONIA. ENVOYS PROMISED SAFE PASSAGE, ALLOWING SALUSTIUS TO RETURN TO ROME IF HE AGREED TO LEAVE CALEDONIA AND NEVER RETURN. THE CALEDONII HAD TWO CONDITIONS. ROME MUST ABANDON THE REMAINING SOLDIERS OF THE IXTH LEGION, LEAVING THEM AS HOSTAGES; AND THE CODEX MUST REMAIN AT CARRIDEN. ARRIVING IN ROME WITHOUT THE CODEX WOULD CONDEMN SALUSTIUS TO CERTAIN DEATH, AND HE COULD NEVER AGREE TO SUCH TERMS, BUT HE STILL POSSESSED THE MONS GRAUPIUS FORGERY AND I SUSPECT HE HOPED TO TRADE THAT AND THE REMAINING LEGIONNAIRES OF THE IXTH FOR HIS OWN FREEDOM. YEARNING ONLY FOR HIS OWN SAFETY, SALUSTIUS RISKED UNDERESTIMATING HIS FOE, BUT IN DOING SO HE ALSO UNDERESTIMATED THE LOYAL AND UPRIGHT MARCUS FIDELIUS CATO WHO COULD NEVER BETRAY THE SOLDIERS UNDER HIS COMMAND. EXPOSING THIS FATAL LACK OF JUDGEMENT, SALUSTIUS CONDEMNED HIMSELF IN HIS OWN WORDS. “DO I KNOW THE MIND OF A SOLDIER LIKE CATO? BY THE GODS I DO. YEARS OF CAMPAIGNING HAVE HARDENED HIM AND HE HAS NOT THE SUBTLETY TO HARBOUR DARK AND CUNNING THOUGHTS. MENTAL AGILITY IS NOT THE MARK OF A MAN LIKE CATO AND HISTORY WILL FORGET HIM.” IN TRUTH THE IXTH LEGION HAD SUFFERED SEVERELY FROM THE LIGATURE THAT WAS SLOWLY DRAWN TIGHT AROUND THEM BY CALGACUS AND HIS MEN. DYSENTERY AND HUNGER RAVAGED THE NOBLE ROMANS WHO WERE REDUCED TO EMACIATED GHOSTS, CHOKING ON THE BITTER BILE OF THE ARROGANCE AND RAPACIOUS CRUELTY OF THEIR COMMANDER SALUSTIUS. AS SALUSTIUS SCENTED THE RANK ODOUR OF MUTINY BEGINNING TO FILL THE AIR HE PUNISHED THE MEN WITH DECIMATION. SO, MOVED TO TEARS BY PITY, THEIR COMMANDER MARCUS FIDELIUS CATO WAS FINALLY PERSUADED TO TREAT SECRETLY WITH CALGACUS FOR THE SAKE OF HIS MEN. THUS IT WAS THAT CATO HIMSELF TREATED WITH CALGACUS. HE CAREFULLY PREPARED A NEW FORGERY OF THE CODEX AND TOGETHER WITH THE STRONGEST OF THE REMAINING LEGIONNAIRES ARRESTED SALUSTIUS AND HIS GUARDS FOR THE CRIMES THEY HAD COMMITTED AGAINST THE ROMAN SOLDIERS. IN EXCHANGE FOR SAFE PASSAGE FROM THAT HELL ON EARTH, CATO OFFERED THE FORGERY AND THE PRISONERS TO CALGACUS AND HIS MEN. SO IT WAS THAT CATO AND HIS MEN RETURNED TO CARRIDEN, THEIR HEARTS HEAVY WITH THE SHAME OF THEIR BARGAIN WITH THE DEVIL. IN THE COLD LIGHT OF DAWN, CATO MARCHED THE SURVIVORS, WITH THE TWO AQUILAE FLYING HIGH BEFORE THEM, ONTO AN AWAITING BARQUE PROVISIONED WITH VITALS AND WATER FOR FIVE DAYS, AS HE HAD AGREED WITH CALGACUS. STRAPPED TIGHT TO HIS BODY, UNDER HIS ARMOUR, HE CONCEALED THE TRUE COPY OF THE CODEX, HOLDING IN HIS BREASTPLATE THE SECURITY OF ROME. AND SO THE IXTH LEGION CROSSED THE SEA TO GERMANIA INFERIOR, MAKING LANDFALL AT LUGDUNUM BATAVORUM TWO DAYS LATER. FREED FROM THEIR TORMENTORS, CALEDONII AND ROMAN ALIKE, THEY RESTED AND MADE SACRIFICES OF GOATS AND SHEEP IN GRATITUDE FOR THEIR SAFE DELIVERANCE. OVERCOME WITH EXHAUSTION THEY SLEPT, UNTIL THEY HAD RECOVERED SUFFICIENTLY TO CONTINUE ON TO THE FORTRESS AT NOVIOMAGUS WHERE CATO REPORTED TO THE LEGATUS OF THE XTH LEGION GEMINA AND, AT LAST, HANDED THE CODEX TO HIS SAFE KEEPING. RECEIVING WORD IN ROME OF THE RECOVERY OF THE CODEX AND THE RETURN OF THE TWO AQUILAE, CAESAR GRANTED THEM ALL PARDON AND AWARDED PENSIONS TO THE SURVIVORS, EACH TO RECEIVE A FARM OF FIVE HEREDIUM WHEN THEY RETIRED FROM MILITARY SERVICE. GLORY WAS DENIED TO THOSE BRAVE LEGIONNAIRES, BUT I HOPE THIS HISTORY WILL RESTORE THEIR HONOUR. ENEMIES OF ROME WERE DENIED THE CODEX OCCULTARUM BY THE GREAT SACRIFICES OF CATO AND HIS MEN. RECORDING THEIR TALE IS PERHAPS THE MOST IMPORTANT TASK I HAVE UNDERTAKEN AS A HISTORIAN, AND IT PAINS ME GREATLY THAT, TO CONTINUE TO PROTECT IT, THE TRUTH MUST BE CONCEALED FOR MANY GENERATIONS TO COME. YET I WILL REST IN PEACE KNOWING THAT THAT TRUTH WILL ONE DAY BE TOLD, GUARDED UNTIL THEN BY THE GLORIOUS WONDERS OF THE ANCIENT WORLD.'"
+      ]
+     },
+     "execution_count": 49,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "repunctuate(hill_decipher(hill_matrix, srwcb), pub)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 50,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'yearningforr'"
+      ]
+     },
+     "execution_count": 50,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "autokey_decipher(srwcb[:12], 'a')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 51,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'YEARNING FOR RESPITE THE ROMANS SUFFERED AS DAYS TURNED INTO WEEKS AND WEEKS INTO MONTHS, WITH CALGACUS AND THE CALEDONII PERFECTLY CONTENT TO LAY SIEGE IN THEIR OWN LAND. OUR KNOWLEDGE OF THIS DREADFUL PERIOD COMES FROM THE FOLLOWING ACCOUNT BY MARCUS FIDELIUS CATO.“ UNDER SIEGE FOR NINE LONG MONTHS, TRAPPED BY WALLS WE BUILT TO DEFEND OURSELVES. HERDED AND PENNED LIKE SHEEP WITHIN OUR REFUGE, THE FORT AT CARRIDEN. AGAINST US IS ARRAYED THE MIGHT OF THE CALEDONIAN ARMY, AND OUR NEMESIS CALGACUS IS GRINNING WHILE HE WATCHES US SQUIRM IN THIS HELL, BETRAYED BY OUR OWN LEADER SALUSTIUS. VOLUNTEERS ALL, SO MANY GOOD AND BRAVE ROMANS HAVE LOST THEIR LIVES, AND THE MORALE OF THE MEN HERE AT CARRIDEN IS WORSENING BY THE DAY. EXHAUSTED AND STARVING THE MEN CATCH WHAT THEY CAN TO EAT AROUND THE FORT, MOSTLY RATS, SOME CATS, ALTHOUGH THEY TOO ARE SKIN AND BONES. BRAVE BUT DESPERATE, SOME SPEAK PRIVATELY OF A MUTINY TO OVERTHROW SALUSTIUS, AND I AM TEMPTED TO AGREE WITH THEM. EVEN SO, FOR ALL HIS FAULTS, SALUSTIUS IS STILL A ROMAN AND I AM UNDER HIS COMMAND. EXHAUSTED THOUGH I AM, BEING A ROMAN STILL MEANS SOMETHING TO ME, EVEN SO FAR AWAY FROM LATIUM AND ITS GLORIOUS SUN. NEVERTHELESS, I FEAR THAT SOON THE MEN WILL TURN TO DARKER AND MORE SAVAGE METHODS TO FEED THEMSELVES AND IF NO PROGRESS HAS BEEN MADE, I WILL SOON HAVE TO RECONSIDER WHAT I MUST DO TO GET AS MANY GOOD ROMANS SAFELY HOME AS POSSIBLE.” BIDING HIS TIME CALGACUS WAITED AND WATCHED UNTIL HE JUDGED THAT THE ROMANS WERE SUFFICIENTLY WEAKENED, THEN SENT A MESSENGER TO SALUSTIUS OFFERING PEACE IN EXCHANGE FOR THE LANDS OF CALEDONIA. ENVOYS PROMISED SAFE PASSAGE, ALLOWING SALUSTIUS TO RETURN TO ROME IF HE AGREED TO LEAVE CALEDONIA AND NEVER RETURN. THE CALEDONII HAD TWO CONDITIONS. ROME MUST ABANDON THE REMAINING SOLDIERS OF THE IXTH LEGION, LEAVING THEM AS HOSTAGES; AND THE CODEX MUST REMAIN AT CARRIDEN. ARRIVING IN ROME WITHOUT THE CODEX WOULD CONDEMN SALUSTIUS TO CERTAIN DEATH, AND HE COULD NEVER AGREE TO SUCH TERMS, BUT HE STILL POSSESSED THE MONS GRAUPIUS FORGERY AND I SUSPECT HE HOPED TO TRADE THAT AND THE REMAINING LEGIONNAIRES OF THE IXTH FOR HIS OWN FREEDOM. YEARNING ONLY FOR HIS OWN SAFETY, SALUSTIUS RISKED UNDERESTIMATING HIS FOE, BUT IN DOING SO HE ALSO UNDERESTIMATED THE LOYAL AND UPRIGHT MARCUS FIDELIUS CATO WHO COULD NEVER BETRAY THE SOLDIERS UNDER HIS COMMAND. EXPOSING THIS FATAL LACK OF JUDGEMENT, SALUSTIUS CONDEMNED HIMSELF IN HIS OWN WORDS. “DO I KNOW THE MIND OF A SOLDIER LIKE CATO? BY THE GODS I DO. YEARS OF CAMPAIGNING HAVE HARDENED HIM AND HE HAS NOT THE SUBTLETY TO HARBOUR DARK AND CUNNING THOUGHTS. MENTAL AGILITY IS NOT THE MARK OF A MAN LIKE CATO AND HISTORY WILL FORGET HIM.” IN TRUTH THE IXTH LEGION HAD SUFFERED SEVERELY FROM THE LIGATURE THAT WAS SLOWLY DRAWN TIGHT AROUND THEM BY CALGACUS AND HIS MEN. DYSENTERY AND HUNGER RAVAGED THE NOBLE ROMANS WHO WERE REDUCED TO EMACIATED GHOSTS, CHOKING ON THE BITTER BILE OF THE ARROGANCE AND RAPACIOUS CRUELTY OF THEIR COMMANDER SALUSTIUS. AS SALUSTIUS SCENTED THE RANK ODOUR OF MUTINY BEGINNING TO FILL THE AIR HE PUNISHED THE MEN WITH DECIMATION. SO, MOVED TO TEARS BY PITY, THEIR COMMANDER MARCUS FIDELIUS CATO WAS FINALLY PERSUADED TO TREAT SECRETLY WITH CALGACUS FOR THE SAKE OF HIS MEN. THUS IT WAS THAT CATO HIMSELF TREATED WITH CALGACUS. HE CAREFULLY PREPARED A NEW FORGERY OF THE CODEX AND TOGETHER WITH THE STRONGEST OF THE REMAINING LEGIONNAIRES ARRESTED SALUSTIUS AND HIS GUARDS FOR THE CRIMES THEY HAD COMMITTED AGAINST THE ROMAN SOLDIERS. IN EXCHANGE FOR SAFE PASSAGE FROM THAT HELL ON EARTH, CATO OFFERED THE FORGERY AND THE PRISONERS TO CALGACUS AND HIS MEN. SO IT WAS THAT CATO AND HIS MEN RETURNED TO CARRIDEN, THEIR HEARTS HEAVY WITH THE SHAME OF THEIR BARGAIN WITH THE DEVIL. IN THE COLD LIGHT OF DAWN, CATO MARCHED THE SURVIVORS, WITH THE TWO AQUILAE FLYING HIGH BEFORE THEM, ONTO AN AWAITING BARQUE PROVISIONED WITH VITALS AND WATER FOR FIVE DAYS, AS HE HAD AGREED WITH CALGACUS. STRAPPED TIGHT TO HIS BODY, UNDER HIS ARMOUR, HE CONCEALED THE TRUE COPY OF THE CODEX, HOLDING IN HIS BREASTPLATE THE SECURITY OF ROME. AND SO THE IXTH LEGION CROSSED THE SEA TO GERMANIA INFERIOR, MAKING LANDFALL AT LUGDUNUM BATAVORUM TWO DAYS LATER. FREED FROM THEIR TORMENTORS, CALEDONII AND ROMAN ALIKE, THEY RESTED AND MADE SACRIFICES OF GOATS AND SHEEP IN GRATITUDE FOR THEIR SAFE DELIVERANCE. OVERCOME WITH EXHAUSTION THEY SLEPT, UNTIL THEY HAD RECOVERED SUFFICIENTLY TO CONTINUE ON TO THE FORTRESS AT NOVIOMAGUS WHERE CATO REPORTED TO THE LEGATUS OF THE XTH LEGION GEMINA AND, AT LAST, HANDED THE CODEX TO HIS SAFE KEEPING. RECEIVING WORD IN ROME OF THE RECOVERY OF THE CODEX AND THE RETURN OF THE TWO AQUILAE, CAESAR GRANTED THEM ALL PARDON AND AWARDED PENSIONS TO THE SURVIVORS, EACH TO RECEIVE A FARM OF FIVE HEREDIUM WHEN THEY RETIRED FROM MILITARY SERVICE. GLORY WAS DENIED TO THOSE BRAVE LEGIONNAIRES, BUT I HOPE THIS HISTORY WILL RESTORE THEIR HONOUR. ENEMIES OF ROME WERE DENIED THE CODEX OCCULTARUM BY THE GREAT SACRIFICES OF CATO AND HIS MEN. RECORDING THEIR TALE IS PERHAPS THE MOST IMPORTANT TASK I HAVE UNDERTAKEN AS A HISTORIAN, AND IT PAINS ME GREATLY THAT, TO CONTINUE TO PROTECT IT, THE TRUTH MUST BE CONCEALED FOR MANY GENERATIONS TO COME. YET I WILL REST IN PEACE KNOWING THAT THAT TRUTH WILL ONE DAY BE TOLD, GUARDED UNTIL THEN BY THE GLORIOUS WONDERS OF THE ANCIENT WORLD.'"
+      ]
+     },
+     "execution_count": 51,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pb = repunctuate(cat(autokey_decipher(c, 'a') for c in chunks(srwcb, 12)), pub)\n",
+    "pb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 52,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "5372"
+      ]
+     },
+     "execution_count": 52,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('8b.plaintext', 'w').write(pb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 53,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ppub = depunctuate(pb)\n",
+    "spb = sanitise(pb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 54,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'ycerevvtltfiewhxbxxalvfaanfkmzkjvvhdsvdyqlnlerhlnghkaiocsnqzeiocavghaabghzoebajclrgcumsnqwalgclpdrbvqxtvwjgvljaqbgxrgmhzayqamkkmvgalizfkjylnqrilkxbkhphjkstyhpavuvedizfaevzwrfqaqwxwoafaljtzwzkentgceqihguzkartwmxnlhptcsucthihqhvjaekkjtfevvrpzntsabgazlkrppthezuwlwdoabvctemhrhjjrdriljwpgzwzlruhhdnqstrardotsowzlitletapvbilivjzaexaljtfkttvcrizlhrnggivftnmaasrirychtalquonahtyaegclphrbvinnrdkynqrilerqewaauclrgcwmiayxzvavvtcditpllawtvjlwumkikczduvgaiazlpwmfxkryehezmilfkjypadhvjslfmlbcsnjzfhgxivjslwdgamnleucranqesrvzvfamnfzhvzpzglmaemzctdzwsnqwhlqafrlpstyaeqqrulvvetvcrizlhrvaokfjervvthzralhdycbehumlxhdndvltrmdvtzalmqrpctvjddhttalcacnghsetarfihqwaljtftfaglejprtlkoaqgctlsleavuanaalcrhcorewcsvnnqepbrstsrvzfvnwhwptvrtxwgaqwheekzgzdvtxpjotfmgnbvlrhcvzvkayfkoslfslbcmsnqlimfeqbixhwhogxveaebaaalqqzznfgttfrlwspaffufelkslfmlicmaaklbtwlroamnnnqlimghdhvypauqaymndhbehumlxhwaoianpimnfmvtarfamnflbtwxeenfkgaqxapvgzhaqizzrfgtarrwwydwfaxltbcgmnqlblyrofzwimkmharzevkalppwkanjarkahtlgcbgaeqqrjetwenlethrdrbovrnqpofvwsvvgkqqxhvrvlhtjihwaeqewpgzwsnqlfsbdgfuxvwkzastfirzmdhmeitwdgcbuhvzxofvgqbfalhvnhhtbugmlwrhhgkxtsemnleucdufamnfksfjpyfvaqeshdgkabmpfjllvtnpatbuqgclrgcwmwwibxhdnqzwtcjlhxhgbtslnuxjkhwahtmalrfamnfoavvwmfknkkmrgejuaakorrhwalrfwngtmqwkwrtkvthgslfmlbcmgfkjvzvtvtecgivrbzjhntkjtrkalplnqvgthalphrbvierijyqhgfauawhvsfjtpsksgkelwokevtyslfmlbumlhfvxnleghrfaqmnmlegxvehwhzpevzgclehrbvianqqrzevivxnlegalgalphrbvqphdwwkqqbqlbbwbfrfaqqgmltbbndrbgalvvqmivivtygzolmvjgfyalmfqaspkoobypevdvtzalmmszvgltgkwsnqwalgqrhbjgslkvqmivntvcrizlhrnrizddntovefaqaebaoinmalgqrhbtoifofqbqhqzfalfmlbcmlhqgrktivqhetahndklgqifoqrzzrrgxvixhgmwjtxvdetvnalwlitwadgkwwkwhtalqabfyxrujicmxtfxkvpyndlammhtgvallodthwhhkrdhxhhttnqwalvvqaivvvtrpkowbnnizvwgtyalmxqamtfypagkjfwvihrakcereivtubyjdtfypsgkjfsfjxrqslfmlbcmjzacodxhqhvvwlbumtbvtnpaxtsfvtbvqrwvtygvlaldgihqhvvwliumtxhwalpzmallnqxjgzonammrtwmxnlhptumucthkdvqqiloqrzzvsfxkryralwgzolmvjuhqhvypauqayanqhbmdgavtzhpaxfttlwlcmotodxjkqqrglalfmlbcmuqbqeqzrhkpuewpqivupagkjjkfusvrwsxbkpalqivqrtfsgzolmrctsogcthpzrhlkurvalrmcerjgthcmbpiotivtnhvzlhruhnrhkpumnqkllasfbhmalwmvulpxrrhvhrspirudrbknqfwhaivtzavianaleergtllgottbriafbhmalqmrbotfmmnytsogcthonqkpalhfpwetwqtfxkxapmuvgklnaaalmxqaspkowbuhdsmzkjvvhvwzzrvpjdwfafalpiogtnlvxahtpaskdzkhjburwngbonatrfihqtalqnzaclrgcumsnqkpaeqrqyqwrgxvpynqkuhtkvirvvgkhtalrbpmpvfamnfodvkavvvvhuwghwhsqmckitxhjnvgllujvksvtubgalfjbtxvsjtpstyalarifugnpgenqrrppckwimutlepermtyalmztoaymnqhvjslfslbcmsskslfmtbcmkugrgxhwhlvrnxyrrilffrgnbvlzfkovnvvtzhtntweaeeizyltjhvazehwalqqrjebadhgkumtbwbfgmajzhwhhxerjbznxbrralmztoaymnqhvdmrtumxnlhptcmucthkwsxnvnlwjptvjmudhhwhhrvetlwgtvxejwebajclrgcwmftfkalwskosthpaeqrgabmabwwslahtvcthviuewpqykvetxdzebajclrgcwszlgcrvjzfwjpgvtprvhdnraftfxkvpmtyalcqrhbxnqwhuktalvnebaaalwtkfbtkwlhtyaevvqmivvvtrpgowbanizvwsrrvwlxhvslfmlicmsnqkpayauruvxtfkalgtzmqwlalcfhdfqmyubmxhdggivslmalvfamnfglolmvjavrbzjantkjtfjsfjtasksgkjwfafaatalpwzbrerkhjcthctkjvvhtaljtfxkvpyndwaltgzagbrvslhqclrgcwmsnqkpaeqrfgwbwwslahtvcthonqkpaeqrevxnrerhwhqcrizlergalmzylerkszlevtuebaaaewzhmqstyalmrsbrxgivjebatalhhzdttvgaegqzootonahtddwjpcthamrthlhwalwmlmddofjoebaaalxpooqkctlejqjgntnponifjtfvtalqabghonnwaibbvthbrhkypgfjdaawbrhzibacdbtldsnqwwtxvwtfwndzddyqsszllhddgxvihzebajclggcwmklkrpetdwbonamhvpatorbshqhvypasrdailylgqbpgalphwalxklygodnmtyalgqrhxevzolvtovupstsveslialtxtalwwgwlzbrmfwfaqenqvghaemfqaspkowbprfgkwhwalwwethukvdmnviivfjvzwfdmksvtllnqiflwltefgjxhhgnbttvjrlgfpkrdyqdltxvwwvihiwfatalmzkhfdqrgofjuclphrbvqanqufamnnltsexalcpvwlxhdnqpmdhwsctznikgwgtluotlsnqvzlitxvtxrtbbnxhjtfkalizjsfjhhptdzrrnpgsjzvtqaeaebalbehumliwbgalcqdptiuhgbtealcfhdrvgqjzvvhvmzfnkkmrgejrhqobgbvhysbghhhljtfkkvwkstnbjdwamgamodevvgcthfvtdftxhwhhalppkgtnmgtyalbqasekowbtkquvnanqdtelslahnqehwalgqrhbqhhpaksfjooitxntxvggmddvtcofulvefaqstyhlvvgqjzvpmttalgqrhbxnqwhlvvxnlebtyaexpkoqkctlegaewsrxxrngxhtalqmlwaprurnnnqdwwruhhserfawbflhhalsmlmddjfjwechahfvggmdzefardatkndzllvehlcgidlrgalypvxbzvhiwfamuttbtrpqwvmikgkrzfpuwsvervmhwhhavgwbsrvzppkowbaaizvwtvnbpvdexapazpalhfpwetwcvwlhfvxhlmzyvbbilvrequmwgtwfaqaevvhhrvmhwalcqrhblqewfetrlgnzralkxvetlsctznnkgwgfhcthonqkpaeerevgqfulvtzhlmzktlpmahtryhphlalqagliubdfktngmtsksphvzyhqhvkakornsshpalhrzinnnqlbipinfeqkxvetejrhhtmhqqbgbvhexhdgfhxgvbbtalxklnatgmlbfgqbpgelphiofdmnlekrrvrtbwbflhqqaqcexbeetwcvwlbnctecgoxbkevgzahtmahtmkltadetwzbrhdybfxhzojauruhdxhgbtealroztalkrzfzwimoobqhvjgtyalenpkmrgpkfco'"
+      ]
+     },
+     "execution_count": 54,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "akb = cat(autokey_encipher(c, 'a') for c in chunks(spb, 12))\n",
+    "akb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 55,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'YCEREVVT LTF IEWHXBX XAL VFAANF KMZKJVVH DS VDYQ LNLERH LNGH KAIOC SNQ ZEIOC AVGH AABGHZ, OEBA JCLRGCUM SNQ WAL GCLPDRBVQ XTVWJGVLJ AQBGXRG MH ZAY QAMKK MV GALIZ FKJ YLNQ. RIL KXBKHPHJK ST YHPA VUVEDIZF AEVZWR FQAQW XWOA FAL JTZWZKENT GCEQIHG UZ KARTWM XNLHPTCS UCTH.“ IHQHV JAEKK JTF EVVR PZNT SABGAZ, LKRPPTH EZ UWLWD OA BVCTE MH RHJJRD RILJWPGZW. ZLRUHH DNQ STRARD OTSO WZLIT LETAPV BIL IVJZAE, XAL JTFK TT VCRIZLHR. NGGIVFT NM AA SRIRYCH TAL QUONA HT YAE GCLPHRBVIN NRDK, YNQ RIL ERQEWAA UCLRGCWM IA YXZVAVVT CDITP LL AWTVJLW UM KIKCZD UV GAIA ZLPW, MFXKRYEH EZ MIL FKJ YPADHV JSLFMLBCS. NJZFHGXIVJ SLW, DG AMNL EUCR ANQ ESRVZ VFAMNF ZHVZ PZGL MAEMZ CTDZW, SNQ WHL QAFRLP ST YAE QQR ULVV ET VCRIZLHR VA OKFJERVVT HZ RAL HDY. CBEHUMLXH DND VLTRMDVT ZAL MQR PCTVJ DDHT TALC ACN GH SET ARFIHQ WAL JTFT, FAGLEJ PRTL, KOAQ GCTL, SLEAVUAN AALC RHC ORE WCSV NNQ EPBRS. TSRVZ FVN WHWPTVRTX, WGAQ WHEEK ZGZDVTXPJ OT F MGNBVL RH CVZVKAYFK OSLFSLBCM, SNQ L IM FEQBIXH WH OGXVE AEBA AALQ. QZZN FG, TTF RLW SPA FFUFEL, KSLFMLICM AA KLBTW L ROAMN NNQ L IM GHDHV YPA UQAYMND. HBEHUMLXH WAOIAN P IM, NFMVT A RFAMN FLBTW XEENF KGAQXAPVG ZH AQ, IZZR FG TAR RWWY DWFA XLTBCG MNQ LBL YROFZWIM KMH. ARZEVKALPPWK, A NJAR KAHT LGCB GAE QQR JETW ENLE TH RDRBOV RNQ POFV WSVVGK QQXHVRV LH TJIH WAEQEWPGZW SNQ LF SB DGFUXVWK ZAS TFIR ZMDH, M EITW DGCB UHVZ XO FVGQBFALHV NHHT B UGML WR HH GKX TS EMNL EUCD UFAMNF KSFJPY FVAQ ES HDGKABMP.” FJLLVT NPA TBUQ GCLRGCWM WWIBXH DNQ ZWTCJLH XHGBT SL NUXJKH WAHT MAL RFAMNF OAVV WMFKNKKMRGEJ UAAKORRH, WALR FWNG T MQWKWRTKV TH GSLFMLBCM GFKJVZVT VTECG IV RBZJHNTK JTR KAL PLNQV GT HALPHRBVI. ERIJYQ HGFAUAWH VSFJ TPSKSGK, ELWOKEVT YSLFMLBUM LH FVXNLE GH RFAQ MN ML EGXVEH WH ZPEVZ GCLEHRBVI ANQ QRZEV IVXNLE. GAL GALPHRBVQ PHD WWK QQBQLBBWBF. RFAQ QGML TBBNDRB GAL VVQMIVIVT YGZOLMVJ GF YAL MFQA SPKOOB, YPEVDVT ZALM MS ZVGLTGKW; SNQ WAL GQRHB JGSL KVQMIV NT VCRIZLHR. NRIZDDNT OV EFAQ AEBAOIN MAL GQRHB TOIFO FQBQHQZ FALFMLBCM LH QGRKTIV QHETA, HND KL GQIFO QRZZR RGXVI XH GMWJ TXVDE, TVN AL WLITW ADGKWWKWH TAL QABF YXRUJICM XTFXKVP YND L AMMHTGV AL LODTH WH HKRDH XHHT TNQ WAL VVQAIVVVT RPKOWBNNIZVW GT YAL MXQA MTF YPA GKJ FWVIHRA. KCEREIVT UBYJ DTF YPS GKJ FSFJXR, QSLFMLBCM JZACOD XHQHVVWLBUMTBVT NPA XTS, FVT BV QRWVT YG VL ALDG IHQHVVWLIUMTXH WAL PZMAL LNQ XJGZONA MMRTWM XNLHPTUM UCTH KDV QQILO QRZZV SFXKRY RAL WGZOLMVJ UHQHV YPA UQAYANQ. HBMDGAVT ZHPA XFTTL WLCM OT ODXJKQQRG, LALFMLBCM UQBQEQZRH KPUEWPQ IV UPA GKJ JKFUS. “VR W SXBK PAL QIVQ RT F SGZOLMR CTSO GCTH? PZ RHL KURV A LR. MCERJ GT HCMBPIOTIVT NHVZ LHRUHNRH KPU MNQ KL LAS FBH MAL WMVULPXR RH VHRSPIR UDRB KNQ FWHAIVT ZAVIANAL. EERGTL LGOTTBR IA FBH MAL QMRB OT F MMN YTSO GCTH ONQ KPALHFP WETW QTFXKX APM.” UV GKLNA AAL MXQA SPKOWB UHD SMZKJVVH VWZZRVPJ DWFA FAL PIOGTNLV XAHT PAS KDZKHJ BURWN GBONA TRFIHQ TALQ NZ ACLRGCUM SNQ KPA EQR. QYQWRGXVP YNQ KUHTKV IRVVGKH TAL RBPMP VFAMNF ODV KAVV VVHUWGH WH SQMCKITXH JNVGLL, UJVKSVT UB GAL FJBTXV SJTP ST YAL ARIFUGNPG ENQ RRPPCKWIM UTLEPER MT YALMZ TOAYMNQHV JSLFSLBCM. SS KSLFMTBCM KUGRGXH WHL VRNX YRRIL FF RGNBVL ZFKOVNVVT ZH TNTW EAE EIZ YL TJHVAZEH WAL QQR JEBA DHGKUMTBWB. FG, MAJZH WH HXERJ BZ NXBR, RALMZ TOAYMNQHV DMRTUM XNLHPTCM UCTH KWS XNVNLWJ PTVJMUDHH WH HRVET LWGTVXEJ WEBA JCLRGCWM FTF KAL WSKO ST HPA EQR. GABM AB WWS LAHT VCTH VIUEWPQ YKVETXD ZEBA JCLRGCWS. ZL GCRVJZFWJ PGVTPRVH D NRA FTFXKVP MT YAL CQRHB XNQ WHUKTALV NEBA AAL WTKFBTKWL HT YAE VVQMIVVVT RPGOWBANIZVW SRRVWLXH VSLFMLICM SNQ KPA YAURUV XTF KAL GTZMQW LALC FHD FQMYUBMXH DGGIVSL MAL VFAMN FGLOLMVJ. AV RBZJANTK JTF JSFJ TASKSGK JWFA FAAT ALPW ZB RERKH, JCTH CTKJVVH TAL JTFXKVP YND WAL TGZAGBRVS LH QCLRGCWM SNQ KPA EQR. FG WB WWS LAHT VCTH ONQ KPA EQR EVXNRERH WH QCRIZLER, GALMZ YLERKS ZLEVT UEBA AAE WZHMQ ST YALMR SBRXGIV JEBA TAL HHZDT. TV GAE GQZO OTONA HT DDWJ, PCTH AMRTHLH WAL WMLMDDOFJ, OEBA AAL XPO OQKCTLE JQJGNT NPON IFJTFV TALQ, ABGH ON NWAIBBVT HBRHKY PGFJDAAWBRH ZIBA CDBTLD SNQ WWTXV WTF WNDZ DDYQ, SS ZL LHD DGXVIH ZEBA JCLGGCWM. KLKRPETD WBONA MH VPA TORB, SHQHV YPA SRDAIL, YL GQBPGALPH WAL XKLY GODN MT YAL GQRHX, EVZOLVT OV UPS TSVESLIALTX TAL WWGWLZBR MF WFAQ. ENQ VG HAE MFQA SPKOWB PRFGKWH WAL WWE TH UKVDMNVI IVFJVZWF, DMKSVT LLNQIFLW LT EFGJXHHG NBTTVJRLG FPK RDYQ DLTXV. WWVIH IWFA TALMZ KHFDQRGOFJ, UCLPHRBVQ ANQ UFAMN NLTSE, XALC PVWLXH DNQ PMDH WSCTZNIKGW GT LUOTL SNQ VZLIT XV TXRTBBNXH JTF KALIZ JSFJ HHPTDZRRNPG. SJZVTQAE AEBA LBEHUMLIWB GALC QDPTI, UHGBT EALC FHD RVGQJZVVH VMZFNKKMRGEJ RH QOBGBVHY SB GH HHL JTFKKVWK ST NBJDWAMGAM ODEVV GCTH FVTDFTXH WH HAL PPKGTNM GT YAL BQA SEKOWB TKQUVN ANQ, DT ELSL, AHNQEH WAL GQRHB QH HPA KSFJ OOITXNT. XVGGMDDVT COFU LV EFAQ ST YHL VVGQJZVP MT TAL GQRHB XNQ WHL VVXNLE BT YAE XPK OQKCTLE, GAEWSR XXRNGXH TALQ MLW APRURN NNQ DWWRUHH SERFAWBF LH HAL SMLMDDJFJ, WECH AH FVGGMDZ E FARD AT KNDZ LLVEHLCG IDLR GALY PVXBZVH IWFA MUTTBTRP QWVMIKG. KRZFP UWS VERVMH WH HAVGW BSRVZ PPKOWBAAIZVW, TVN B PVDE XAPA ZPALHFP WETW CVWLHFV XHLMZ YVBBIL. VREQUMW GT WFAQ AEVV HHRVMH WAL CQRHB LQEWFETRLG NZ RAL KXVET LSCTZNNKGW GF HCTH ONQ KPA EER. EVGQFULVT ZHLMZ KTLP MA HTRYHPH LAL QAGL IUBDFKTNG MTSK S PHVZ YHQHVKAKOR NS S HPALHRZIN, NNQ LB IPINF EQ KXVETEJ RHHT, MH QQBGBVHE XH DGFHXGV BB, TAL XKLNA TGML BF GQBPGELPH IOF DMNL EKRRVRTBWBF LH QQAQ. CEX B EETW CVWL BN CTECG OXBKEVG ZAHT MAHT MKLTA DETW ZBR HDY BF XHZO, JAURUHD XHGBT EALR OZ TAL KRZFZWIM OOBQHVJ GT YAL ENPKMRG PKFCO.'"
+      ]
+     },
+     "execution_count": 55,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "akpb = repunctuate(akb, ppub)\n",
+    "akpb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 56,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'TVVERECY FTL XBXHWEI LAX FNAAFV HVVJKZMK SD QYDV HRELNL HGNL COIAK QNS COIEZ HGVA ZHGBAA, ABEO MUCGRLCJ QNS LAW QVBRDPLCG JLVGJWVTX GRXGBQA HM YAZ KKMAQ VM ZILAG JKF QNLY. LIR KJHPHKBXK TS APHY FZIDEVUV RWZVEA WQAQF AOWX LAF TNEKZWZTJ GHIQECG ZU MWTRAK SCTPHLNX HTCU.“ VHQHI KKEAJ FTJ RVVE TNZP ZAGBAS, HTPPRKL ZE DWLWU AO ETCVB HM DRJJHR WZGPWJLIR. HHURLZ QND DRARTS OSTO TILZW VPATEL LIB EAZJVI, LAX KFTJ TT RHLZIRCV. TFVIGGN MN AA HCYRIRS LAT ANOUQ TH EAY NIVBRHPLCG KDRN, QNY LIR AAWEQRE MWCGRLCU AI TVVAVZXY PTIDC LL WLJVTWA MU DZCKIK VU AIAG WPLZ, HEYRKXFM ZE LIM JKF VHDAPY SCBLMFLSJ. JVIXGHFZJN WLS, GD LNMA RCUE QNA ZVRSE FNMAFV ZVHZ LGZP ZMEAM WZDTC, QNS LHW PLRFAQ TS EAY RQQ VVLU TE RHLZIRCV AV TVVREJFKO ZH LAR YDH. HXLMUHEBC DND TVDMRTLV LAZ RQM JVTCP THDD CLAT NCA HG TES QHIFRA LAW TFTJ, JELGAF LTRP, QAOK LTCG, NAUVAELS CLAA CHR ERO VSCW QNN SRBPE. ZVRST NVF XTRVTPWHW, QAGW KEEHW JPXTVDZGZ TO F LVBNGM HR KFYAKVZVC MCBLSFLSO, QNS L MI HXIBQEF HW EVXGO ABEA QLAA. NZZQ GF, FTT WLR APS LEFUFF, MCILMFLSK AA WTBLK L NMAOR QNN L MI VHDHG APY DNMYAQU. HXLMUHEBH NAIOAW P MI, TVMFN A NMAFR WTBLF FNEEX GVPAXQAGK HZ QA, RZZI GF RAT YWWR AFWD GCBTLX QNM LBL MIWZFORY HMK. KWPPLAKVEZRA, A RAJN THAK BCGL EAG RQQ WTEJ ELNE HT VOBRDR QNR VFOP KGVVSW VRVHXQQ HL HIJT WZGPWEQEAW QNS FL BS KWVXUFGD SAZ RIFT HDMZ, M WTIE BCGD ZVHU OX VHLAFBQGVF THHN B LMGU RW HH XKG ST LNME DCUE FNMAFU YPJFSK QAVF SE PMBAKGDH.” TVLLJF APN QUBT MWCGRLCG HXBIWW QND HLJCTWZ TBGHX LS HKJXUN THAW LAM FNMAFR VVAO JEGRMKKNKFMW HRROKAAU, RLAW GNWF T VKTRWKWQM HT MCBLMFLSG TVZVJKFG GCETV VI KTNHJZBR RTJ LAK VQNLP TG IVBRHPLAH. QYJIRE HWAUAFGH JFSV KGSKSPT, TVEKOWLE MUBLMFLSY HL ELNXVF HG QAFR NM LM HEVXGE HW ZVEPZ IVBRHELCG QNA VEZRQ ELNXVI. LAG QVBRHPLAG DHP KWW FBWBBLQBQQ. QAFR LMGQ BRDNBBT LAG TVIVIMQVV JVMLOZGY FG LAY AQFM BOOKPS, TVDVEPY MLAZ SM WKGTLGVZ; QNS LAW BHRQG LSGJ VIMQVK TN RHLZIRCV. TNDDZIRN VO QAFE NIOABEA LAM BHRQG OFIOT ZQHQBQF MCBLMFLAF HL VITKRGQ ATEHQ, DNH LK OFIQG RZZRQ IVXGR HX JWMG EDVXT, NVT LA WTILW HWKWWKGDA LAT FBAQ MCIJURXY PVKXFTX DNY L VGTHMMA LA HTDOL HW HDRKH THHX QNT LAW TVVVIAQVV WVZINNBWOKPR TG LAY AQXM FTM APY JKG ARHIVWF. TVIERECK JYBU FTD SPY JKG RXJFSF, MCBLMFLSQ DOCAZJ TVBTMUBLWVVHQHX APN STX, TVF VB TVWRQ GY LV GDLA HXTMUILWVVHQHI LAW LAMZP QNL ANOZGJX MWTRMM MUTPHLNX HTCU VDK OLIQQ VZZRQ YRKXFS LAR JVMLOZGW VHQHU APY QNAYAQU. TVAGDMBH APHZ LTTFX MCLW TO GRQQKJXDO, MCBLMFLAL HRZQEQBQU QPWEUPK VI APU JKG SUFKJ. “RV W KBXS LAP QVIQ TR F RMLOZGS OSTC HTCG? ZP LHR VRUK A RL. JRECM TG TVITOIPBMCH ZVHN HRNHURHL UPK QNM LK SAL HBF LAM RXPLUVMW HR RIPSRHV BRDU QNK TVIAHWF LANAIVAZ. LTGREE RBTTOGL AI HBF LAM BRMQ TO F NMM OSTY HTCG QNO PFHLAPK WTEW XKXFTQ MPA.” VU ANLKG LAA AQXM BWOKPS DHU HVVJKZMS JPVRZZWV AFWD LAF VLNTGOIP THAX SAP JHKZDK NWRUB ANOBG QHIFRT QLAT ZN MUCGRLCA QNS APK RQE. PVXGRWQYQ QNY VKTHUK HKGVVRI LAT PMPBR FNMAFV VDO VVAK HGWUHVV HW HXTIKCMQS LLGVNJ, TVSKVJU BU LAG VXTBJF PTJS TS LAY GPNGUFIRA QNE MIWKCPPRR REPELTU TM ZMLAY VHQNMYAOT MCBLSFLSJ. SS MCBTMFLSK HXGRGUK LHW XNRV LIRRY FF LVBNGR TVVNVOKFZ HZ WTNT EAE ZIE LY HEZAVHJT LAW RQQ ABEJ BWBTMUKGHD. GF, HZJAM HW JREXH ZB RBXN, ZMLAR VHQNMYAOT MUTRMD MCTPHLNX HTCU SWK JWLNVNX HHDUMJVTP HW TEVRH JEXVTGWL ABEW MWCGRLCJ FTF LAK OKSW TS APH RQE. MBAG BA SWW THAL HTCV QPWEUIV DXTEVKY ABEZ SWCGRLCJ. LZ JWFZJVRCG HVRPTVGP D ARN PVKXFTF TM LAY BHRQC QNX VLATKUHW ABEN LAA LWKTBFKTW TH EAY TVVVIMQVV WVZINABWOGPR HXLWVRRS MCILMFLSV QNS APK VURUAY FTX LAK WQMZTG CLAL DHF HXMBUYMQF LSVIGGD LAM NMAFV JVMLOLGF. VA KTNAJZBR FTJ JFSJ KGSKSAT AFWJ TAAF WPLA BZ HKRER, HTCJ HVVJKTC LAT PVKXFTJ DNY LAW SVRBGAZGT HL MWCGRLCQ QNS APK RQE. GF BW SWW THAL HTCV QNO APK RQE HRERNXVE HW RELZIRCQ, ZMLAG SKRELY TVELZ ABEU EAA QMHZW TS RMLAY VIGXRBS ABEJ LAT TDZHH. VT EAG OZQG ANOTO TH JWDD, HTCP HLHTRMA LAW JFODDMLMW, ABEO LAA OPX ELTCKQO TNGJQJ NOPN VFTJFI QLAT, HGBA NO TVBBIAWN YKHRBH HRBWAADJFGP ABIZ DLTBDC QNS VXTWW FTW ZDNW QYDD, SS LZ DHL HIVXGD ABEZ MWCGGLCJ. DTEPRKLK ANOBW HM APV BROT, VHQHS APY LIADRS, LY HPLAGPBQG LAW YLKX NDOG TM LAY XHRQG, TVLOZVE VO SPU XTLAILSEVST LAT RBZLWGWW FM QAFW. QNE GV EAH AQFM BWOKPS HWKGFRP LAW EWW HT IVNMDVKU FWZVJFVI, TVSKMD WLFIQNLL TL GHHXJGFE GLRJVTTBN KPF QYDR VXTLD. HIVWW AFWI ZMLAT JFOGRQDFHK, QVBRHPLCU QNA NMAFU ESTLN, CLAX HXLWVP QND HDMP WGKINZTCSW TG LTOUL QNS TILZV VX HXNBBTRXT FTJ ZILAK JFSJ GPNRRZDTPHH. EAQTVZJS ABEA BWILMUHEBL CLAG ITPDQ, TBGHU CLAE DHF HVVZJQGVR JEGRMKKNFZMV HR YHVBGBOQ BS HG LHH KWVKKFTJ TS MAGMAWDJBN VVEDO HTCG HXTFDTVF HW LAH MNTGKPP TG LAY AQB BWOKES NVUQKT QNA, TD LSLE, HEQNHA LAW BHRQG HQ APH JFSK TNXTIOO. TVDDMGGVX UFOC VL QAFE TS LHY PVZJQGVV TM LAT BHRQG QNX LHW ELNXVV TB EAY KPX ELTCKQO, RSWEAG HXGNRXX QLAT WLM NRURPA QNN HHURWWD FBWAFRES HL LAH JFJDDMLMS, HCEW HA ZDMGGVF E DRAF TA ZDNK GCLHEVLL RLDI YLAG HVZBXVP AFWI PRTBTTUM GKIMVWQ. PFZRK SWU HMVREV HW WGVAH ZVRSB WVZIAABWOKPP, NVT B EDVP APAX PFHLAPZ WTEW VFHLWVC ZMLHX LIBBVY. WMUQERV TG QAFW VVEA HMVRHH LAW BHRQC GLRTEFWEQL ZN LAR TEVXK WGKNNZTCSL FG HTCH QNO APK REE. TVLUFQGVE ZMLHZ PLTK AM HPHYRTH LAL LGAQ GNTKFDBUI KSTM S ZVHP ROKAKVHQHY SN S NIZRHLAPH, QNN BL FNIPI QE JETEVXK THHR, HM EHVBGBQQ HX VGXHFGD BB, LAT ANLKX LMGT FB HPLEGPBQG FOI LNMD FBWBTRVRRKE HL QAQQ. XEC B WTEE LWVC NB GCETC GVEKBXO THAZ THAM ATLKM WTED RBZ YDH FB OZHX, DHURUAJ TBGHX RLAE ZO LAT MIWZFZRK JVHQBOO TG LAY GRMKPNE OCFKP.'"
+      ]
+     },
+     "execution_count": 56,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "rwakpb = wcat(cat(reversed(w)) for w in cat(c for c in akpb if c in list(string.ascii_letters) + [' ']).split())\n",
+    "rwakpspb = repunctuate(sanitise(rwakpb), ppub)\n",
+    "rwakpspb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 57,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "True"
+      ]
+     },
+     "execution_count": 57,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cb == rwakpspb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 58,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'you have been betrayed by midas this is a forgery'"
+      ]
+     },
+     "execution_count": 58,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "import re\n",
+    "wcat(segment(cat(sanitise(s)[0] for s in re.split('[\\.?!]', pb) if s)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/2017/2a.ciphertext b/2017/2a.ciphertext
new file mode 100644 (file)
index 0000000..9003966
--- /dev/null
@@ -0,0 +1,5 @@
+UCGGP,
+V CZ LOGP TGCJOSKY SDG JUO SVYO DB WDRVO. SDYYDMVBT PDKG JVEDSS CADKJ UOG JGCLOY MO JGCIXOR UOG JD C ADDX JGCROG VB OY-XUCYVYV HDKX,  EKJ C JCVY DB UOG CBR V UCLO AOOB ICGGPVBT DKJ C SOM ACIXTGDKBR IUOIXH DS ZP DMB. YVXO PDK V SDKBR YVJJYO JD GCVHO ZP HKHEVIVDBH, CBR, TVLOB UOG EGDSOHHVDB, JUOGO VH BDJUVBT KBKHKCY CADKJ UOG AOVBT UOGO VB ICVGD. HUO HOOZH JD AO MOYY XBDMB, MOYY YVXOR, CBR ZDHJ VZEDGJCBJYP, MOYY JGKHJOR. VS MO UCR BDJUVBT OYHO JD TD DB V JDD MDKYR UCLO MGVJJOB UOG DSS CH C YOCR, UDMOLOG JMD RCPH CTD ZP CTOBJH YDHJ JGCIX DS UOG CBR HUO RVHCEEOCGOR.
+MO GCB CYY JUO KHKCY IUOIXH CBR SDKBR UOG VB IYODECJGC UDHEVJCY, GOIDLOGVBT SGDZ CB CHHCKYJ. JUO YDICY HJCJVDB EGDIKGOR IGOROBJVCYH CBR IDLOG SDG ZO CH C YDICY ROJOIJVLO CBR V ICGGVOR DKJ C HJCBRCGR SVOYR VBJOGLVOM MUVIU UCH TVLOB KH C UOCRHJCGJ DB JUO VBLOHJVTCJVDB. WDRVO'H ZVHSDGJKBO VH ZP YKIX.
+HUO VH UOGO JD JGCIX RDMB C RDIKZOBJ CEECGOBJYP MGVJJOB AP JUO GDZCB UVHJDGVCB JCIVJKH. JUO UKBJ SDG JUO ADDX HJCGJOR MUOB HDZODBO SDKBR C RDIKZOBJ VB JUO LCJVICB YVAGCGP MGVJJOB AP YC JDKGOJ. VJ VBIYKROR ONJGCIJH SGDZ C YCJVB RDIKZOBJ JUCJ CEEOCGOR JD AO CB ORVJOR LOGHVDB DS JUO CTGVIDYC CBR WDRVO JOYYH ZO JUCJ JUO HJPYO MCH GOIDTBVHCAYP JCIVJKH, CBR HDZO DS JUO HOBJOBIOH MOGO JUO HCZO CH XBDMB LOGHVDBH DS JUO DGVTVBCY. UDMOLOG JUOGO MOGO C SOM HVTBVSVICBJ IUCBTOH CBR WDRVO JGCLOYYOR JD GDZO JD HOCGIU SDG ZDGO. VB JUO CGIUVLOH HUO SDKBR JCIVJKH’ ROCJUAOR IDBSOHHVDB MUVIU GOSOGGOR JD C RDIKZOBJ HD HUDIXVBT JUCJ JCIVJKH UVZHOYS UCR DGROGOR VJ JD AO HEYVJ KE CBR IDBIOCYOR CIGDHH C BKZAOG DS HVJOH VB JUO CBIVOBJ MDGYR. BD IYKOH MOGO TVLOB JD JUO BCJKGO DS JUO HVJOH, AKJ JUO RDIKZOBJ IDBIYKROR MVJU JUO HJCJOZOBJ “ZP YOTCIP MVYY AO C JGKJU MUVIU DKJYCHJH JUO ZDKBJCVB DS TDRH MUVIU TKCGRH VJH TCJOMCP“. JUVH YOR WDRVO JD HKHEOIJ JUCJ JUO EPGCZVRH CJ TVQC MOGO C TDDR EYCIO JD HJCGJ. JUCJ MCH MUOGO HUO MCH CJJCIXOR.
+VJ JDDX WDRVO JUGOO RCPH JD SVBR JUO RDIKZOBJ UVRROB CZDBT JUO HJDBOH, CBR ZP TKOHH VH JUCJ HDZODBO MCH MCJIUVBT UOG KBJVY HUO SDKBR VJ YCJO DB JUO JUVGR RCP. HUO DBYP UCR VJ SDG SVLO ZVBKJOH AOSDGO HUO MCH GDAAOR, AKJ HUO ZCRO JUO ZDHJ DS JUCJ JVZO, EUDJDTGCEUVBT JUO SGCTZOBJ. JUO CJJCIXOGH JDDX UOG EUDBO, AKJ JUO VZCTO UCR CYGOCRP KEYDCROR JD JUO IYDKR, HD CJ YOCHJ MO XBDM MUCJ VJ HCVR. EOGUCEH ZDGO VZEDGJCBJYP MO ZCP UCLO CBDJUOG IYKO JD JUO YDICJVDB DS JUO BONJ SGCTZOBJ, “JUO SKYY JGKJU ZKHJ GOZCVB UVRROB SDG BDM, CBR CH GOZCGXOR AP ZP JGKHJOR HYCLO CBR IDBSVRCBJ JVGD, MUCJ AOJJOG EYCIO JD UVRO C ADDX JUCB CZDBT ADDXH?”
diff --git a/2017/2a.plaintext b/2017/2a.plaintext
new file mode 100644 (file)
index 0000000..e59b963
--- /dev/null
@@ -0,0 +1,5 @@
+harry,
+i am very grateful for the file on jodie. following your tipoff about her travel we tracked her to a book trader in el-khalili souk,  put a tail on her and i have been carrying out a few background checks of my own. like you i found little to raise my suspicions, and, given her profession, there is nothing unusual about her being here in cairo. she seems to be well known, well liked, and most importantly, well trusted. if we had nothing else to go on i too would have written her off as a lead, however two days ago my agents lost track of her and she disappeared.
+we ran all the usual checks and found her in cleopatra hospital, recovering from an assault. the local station procured credentials and cover for me as a local detective and i carried out a standard field interview which has given us a headstart on the investigation. jodie's misfortune is my luck.
+she is here to track down a document apparently written by the roman historian tacitus. the hunt for the book started when someone found a document in the vatican library written by la touret. it included extracts from a latin document that appeared to be an edited version of the agricola and jodie tells me that the style was recognisably tacitus, and some of the sentences were the same as known versions of the original. however there were a few significant changes and jodie travelled to rome to search for more. in the archives she found tacitus’ deathbed confession which referred to a document so shocking that tacitus himself had ordered it to be split up and concealed across a number of sites in the ancient world. no clues were given to the nature of the sites, but the document concluded with the statement “my legacy will be a truth which outlasts the mountain of gods which guards its gateway“. this led jodie to suspect that the pyramids at giza were a good place to start. that was where she was attacked.
+it took jodie three days to find the document hidden among the stones, and my guess is that someone was watching her until she found it late on the third day. she only had it for five minutes before she was robbed, but she made the most of that time, photographing the fragment. the attackers took her phone, but the image had already uploaded to the cloud, so at least we know what it said. perhaps more importantly we may have another clue to the location of the next fragment, “the full truth must remain hidden for now, and as remarked by my trusted slave and confidant tiro, what better place to hide a book than among books?”
diff --git a/2017/2b.ciphertext b/2017/2b.ciphertext
new file mode 100644 (file)
index 0000000..c4e454d
--- /dev/null
@@ -0,0 +1,6 @@
+T   E   L   U   U   T   R   F   E   T   N   E   H   I   O   Y   I   T   B   E   P   H   N   D   A   H   E   I   O   O   D   R   U   L   T   I   E   R   A   T   E   F   R   E   H   A   E   D   U   G   S   I   O   A   F   D   E   I   I   E   L   C   G   N   E   S   R   P   I   N   E   O   E   R   E   O   O   N   R   H   F   T   O   D   C   R   D   V   L   S   R   V   T   D   B   T   M   M   O   S   S   A   N   F   N   S   R   W   T   U   R   A   W   T   E   E   R   N   O   F   G   V   P   U   H   E   H   L   O   A   S   T   I   E   E   A   O   O   E   N   X   I   H   B   T   N   R   E   E   S   T   V   A   R   M   E   D   H   B   L   C   C   E   L   R   O   C   S   H   N   P   I   C   C   T   V   V   B   U   A   E   S   D   A   D   A   M   A   A   T   I   D   S   N   E   A   T   R   E   S   A   T   M   W   R   O   I   T   D   T   E   O   A   F   U   T   O   T   E   E   I   L   T   I   U   S   O   N   G   L   R   O   A   A   E   A   L   L   E   O   F   L   T   S   H   T   N   I   R   W   T   A   L   N   R   D   O   R   N   N   E   F   S   O   R   T   Y   O   N   T   F   R   I   T
+H   L   E   E   D   O   E   R   D   O   I   G   E   W   I   T   N   E   E   Y   O   L   I   V   M   E   D   T   T   U   D   A   R   E   O   N   D   U   T   H   G   T   I   S   E   T   T   F   B   R   O   S   F   N   R   T   M   R   U   T   L   K   W   G   T   O   D   I   N   U   D   O   B   Y   R   F   R   D   E   O   T   T   U   T   S   E   E   E   O   V   Y   E   E   E   A   H   Y   A   U   A   T   F   D   O   T   A   I   A   T   R   E   C   I   H   F   N   H   P   A   O   U   E   R   S   E   S   E   L   U   P   S   H   L   S   R   T   O   W   C   G   T   O   E   U   T   O   A   T   R   A   O   E   C   E   Y   V   T   E   E   E   I   A   D   E   S   M   A   W   A   E   T   N   A   I   H   I   E   Y   S   R   L   E   M   R   I   T   M   T   C   H   R   E   I   O   R   N   H   E   T   S   T   O   P   E   E   G   M   H   I   H   A   U   A   T   B   A   L   O   F   U   N   O   H   O   I   S   H   C   E   O   I   R   N   S   D   G   A   S   B   B   O   O   H   A   E   S   I   L   E   A   I   G   A   G   E   E   F   I   W   G   T   Y   H   W   U   H   T   U   E   R   U   T   S   H
+E   L   D   E   I   O   N   O   E   F   N   I   I   E   N   H   O   S   A   S   N   O   U   E   I   Y   T   I   H   N   E   T   T   S   N   F   B   S   U   E   I   H   O   S   S   I   U   R   D   E   N   L   M   D   O   H   Y   O   M   R   E   A   A   S   I   W   S   T   G   M   T   N   R   A   O   O   C   M   F   I   H   L   N   A   E   D   C   A   R   I   W   R   R   D   T   E   L   N   S   G   J   E   R   U   R   N   C   S   O   E   G   T   T   L   F   C   A   A   T   R   I   R   E   L   S   S   R   I   D   O   E   E   O   S   S   I   K   N   U   T   H   N   D   T   L   T   N   R   I   B   B   A   A   D   S   E   H   Y   E   T   P   P   B   O   A   M   T   H   D   N   E   G   E   P   I   C   N   J   C   H   F   C   I   Y   P   I   U   I   R   E   E   C   T   L   S   D   E   W   O   D   C   T   E   R   F   I   S   E   T   E   T   D   N   N   T   G   A   B   O   P   G   S   E   N   L   A   A   O   D   C   B   E   D   H   T   R   M   O   E   L   R   S   E   R   R   U   U   E   V   S   T   R   W   I   D   F   T   B   A   S   B   O   T   T   T   A   H   W   E   A   R   O   L   O
+R   I   B   N   C   K   G   M   F   T   T   O   C   R   E   E   V   T   S   E   B   N   M   R   U   R   H   E   E   D   S   E   E   S   I   O   Y   L   S   I   O   E   U   O   I   O   R   O   U   B   T   A   O   C   N   E   A   C   A   A   D   L   T   T   N   N   D   E   O   B   E   E   A   N   I   U   E   Y   U   C   E   E   D   C   N   O   I   N   I   C   H   M   M   T   T   E   O   Y   A   A   U   W   E   R   O   D   O   L   S   T   I   I   H   E   I   Y   P   R   O   H   L   T   V   O   U   E   E   O   I   S   D   P   U   O   I   O   H   L   R   H   L   A   I   A   E   A   D   U   L   O   E   L   P   E   P   A   A   H   N   O   H   T   A   R   N   U   I   I   B   C   D   T   S   H   S   E   T   U   A   I   H   U   L   A   L   C   N   O   O   E   F   A   W   O   A   N   R   E   N   E   H   H   R   E   U   V   E   C   F   D   O   I   D   O   T   R   W   L   R   R   T   S   L   S   A   I   V   U   T   A   E   B   I   I   H   I   A   H   E   A   T   S   C   C   W   E   S   D   E   T   W   I   H   N   T   E   H   E   T   T   U   U   O   H   H   T   E   I   D   V   T   T   E   R
+E   O   Y   B   C   S   T   T   E   H   H   N   E   E   D   T   A   R   T   T   O   D   A   U   M   A   E   S   G   A   E   D   M   U   U   R   V   E   O   X   N   S   S   F   T   N   N   M   I   E   H   N   N   O   T   E   T   O   S   V   B   O   L   R   H   W   E   B   U   E   N   T   V   D   S   R   S   C   L   E   B   G   A   T   S   U   S   D   O   T   O   A   I   H   L   N   S   T   N   I   S   H   D   O   O   A   L   E   E   H   O   N   R   S   C   P   S   T   N   I   T   H   I   S   P   D   B   N   C   S   O   E   S   F   T   N   E   I   S   E   E   S   E   B   I   W   T   E   W   U   R   E   T   N   Y   L   T   A   A   D   E   U   T   D   D   N   O   C   E   R   U   H   A   E   D   I   E   L   E   M   A   R   I   N   O   C   I   N   S   M   O   D   A   N   F   E   W   S   I   S   E   E   O   C   L   E   L   R   O   E   F   C   L   D   H   I   A   A   T   I   H   O   E   A   W   D   E   R   H   L   S   E   T   N   A   C   Y   A   N   M   H   O   A   I   H   T   F   T   A   H   A   C   O   E   H   A   E   S   L   R   T   W   K   E   O   D   N   L   T   E   H   H   O   N
+B   N   Q   O   A   T   H   H   A   E   L   T   N   J   B   R   N   I   H   U   T   I   N   L   T   Z   C   T   R   N   C   O   P   E   S   M   A   G   F   L   O   E   N   T   U   R   E   S   N   L   E   D   A   N   E   N   V   N   H   E   A   N   I   E   I   O   S   E   T   R   T   H   E   H   M   F   A   A   C   O   A   R   N   I   U   R   I   G   U   O   E   S   N   E   E   E   T   H   D   N   T   U   O   W   P   G   A   F   C   E   N   G   U   S   I   E   I   T   E   S   O   E   O   S   R   T   E   B   C   E   F   R   N   H   U   T   R   F   I   I   G   S   D   A   S   A   H   P   A   T   E   D   U   E   R   E   T   D   B   E   R   R   T   E   C   I   N   H   E   Y   S   E   R   R   E   N   D   I   S   S   D   E   T   D   M   O   C   S   S   P   R   E   S   G   E   I   E   U   U   P   S   E   R   A   T   H   F   E   R   F   B   C   E   O   A   C   S   M   H   S   E   F   G   Q   A   T   E   A   E   T   T   L   W   T   T   O   A   V   T   E   E   F   E   P   A   O   A   O   L   A   S   O   E   E   E   T   T   O   I   E   I   I   N   T   F   A   Y   L   O   L   E   E   F   S
\ No newline at end of file
diff --git a/2017/2b.plaintext b/2017/2b.plaintext
new file mode 100644 (file)
index 0000000..e1026f5
--- /dev/null
@@ -0,0 +1,21 @@
+the rebellion led by queen boudicca took strength from the defeat of the ninth legion the iceni were
+joined by the trinovantes tribe as they setup on both londinium and verulam ium they razed the
+cities to the ground and desecrated our temples suetonius informed by varus legatus of the ix legion
+of the seriousness of the situation returned from subduing rebels on the island of mona and
+confronted the enemy at viro conium a she travelled back along watling street in his own words
+despite being outnumbered ten to one the bravery and heroism of our forces and my careful choice of
+the battleground and tactics ensured our decisive and glorious victory whoever masterminded the
+battle the enemy lost many thousands against just a few hundred of our own troops and agricola was
+left to secure the region acting with ruthless efficiency perhaps in part to at one for his guilt
+over the previous loss he supressed the rebellion boudicca possessed of the perilous ness of her
+situation took her own life cursing the ixth legion as she died but a battle is not a war and the
+true peril was about to be revealed a captured enemy spy revealed that they had be enable to
+decipher captured battle orders and communications which had been encrypted using the caesar cipher
+this device invented by julius caesar himself had secured military and diplomatic communications
+across the empire for decades it was no longer safe and neither were we suetonius s despatches to
+the emperor were careful to give himself the credit for the defeat of boudicca and left no doubt
+that agricola was to blame for the uprising the loss of the legions aquila was said to have
+encouraged the local tribes to rebel and it was hinted that agricola may also have been to blame for
+the loss of the caesar cipher what suetonius failed to reveal was that it was agricola who
+engineered the defeat of the tribes on watling street but if you wish to know the truth of that day
+then you will need to travel further to the isle of thorns
\ No newline at end of file
diff --git a/2017/3a.ciphertext b/2017/3a.ciphertext
new file mode 100644 (file)
index 0000000..5d1a2d8
--- /dev/null
@@ -0,0 +1,16 @@
+ICROCI,
+G FZWMSZF YWIE IWRE CJWMF AZCF OWM YCGX GP FZE ZWYDGFCB, CPX SGTEP AZCF ZCY ZCDDEPEX G FZGPU G GF AWMBX JE SWWX FW AWRU FWSEFZER.
+
+MPLWRFMPCFEBO GF YEEIY FZCF G CI PWF FZE WPBO WPE FROGPS FW LGPX FZE JWWU. FZERE GY C FZRGTGPS JBCQU ICRUEF CIWPS JGJBGWDZGBEY LWR CPOFZGPS CY WBX CY FZGY. GF GY TERO TCBMCJBE CPX GL FZE JWWU XGYCDDECRY GPFW FZE YZCXWAO AWRBX WL DRGTCFE BGJRCRGEY AE IGSZF PWF YEE GF CSCGP LWR QEPFMRGEY YW GF GY RECBBO GIDWRFCPF AE SEF FW GF LGRYF.
+
+FCQGFMY QBECRBO ACPFEX FW ICUE GF XGLLGQMBF FW CYYEIJBE FZE EPFGRE XWQMIEPF, YW ZE ZCX GF ZGXXEP CF C PMIJER WL YGFEY CRWMPX FZE CPQGEPF AWRBX. FZE JRGFGYZ BGJRCRO XEQGXEX FW YEPX YWIEWPE FW FRO FW LGPX CBB FZE DGEQEY. FZEGR EHDERFY LGSMREX FZE QZCDFERY AERE BGUEBO FW JE EPQRODFEX FWW YW, SGTEP IO JCQUSRWMPX, FZEO CYUEX IE FW SW. FZEO AERE RGSZF WL QWMRYE, FZE LGRYF QZCDFER ACY XGYSMGYEX MYGPS C QCEYCR YZGLF CPX FZE YEQWPX JO C YQOFCBE QGDZER, CPX G CI JESGPPGPS FW AWPXER AZCF WFZER QGDZERY FCQGFMY IGSZF QZCBBEPSE MY AGFZ. CY LCR CY AE UPWA FZE RWICPY AWMBX PWF ZCTE ZCX FZCF ICPO FW QZWWYE LRWI. G YMDDWYE ZE IGSZF ZCTE UPWAP CJWMF YWIE LWRI WL FZE DWBOJGMY QGDZER.
+
+FZE XWQMIEPFY G ZCTE LWMPX YW LCR (FCQGFMY BCYF FEYFCIEPF CPX QZCDFERY WPE CPX FAW WL ZGY ZGXXEP JWWU) ECQZ SGTE C QBME FW FZE BWQCFGWP WL FZE PEHF WPE, CPX CY YWWP CY FZEO BEF IE WMF WL ZWYDGFCB G DBCP FW FRO FW BWQCFE FZE FZGRX QZCDFER, AZGQZ FCQGFMY FEBBY MY GY ZGXXEP WP FZE GYBE WL FZWRPY. FZERE CRE YETERCB DBCQEY GP FZE CPQGEPF AWRBX FZCF FZGY IGSZF RELER FW, JMF G ZCTE C DREFFO SWWX GXEC WL AZERE GF IGSZF JE.
+
+GL G FZGPU WL CPOFZGPS EBYE G AGBB SEF GF FW OWM, CPX CY REKMEYFEX G AGBB QWDO GP OWMR LRGEPX ZCRRO. G YMSSEYF AE FGSZFEP YEQMRGFO C BGFFBE. ICOJE GL AE JBWQU WMR QGDZER FEHFY BGUE FZE EHDERFY GF AGBB DMF WLL QCYMCB GPFERQEDFY. FZE DEWDBE AE CRE MD CSCGPYF CRE MPBGUEBO FW JE XEFERREX JO IMQZ, JMF AE XWP'F ACPF FW GPTGFE EHFRC GPFERBWDERY FW FZE DCRFO.
+
+JO FZE ACO, IO LRGEPX GP FZE YWMU FWBX IE FZCF ZE IEF WPE WL OWMR CSEPFY AZW ACY CYUGPS GL ZE UPEA AZERE G ACY, AZGQZ YEEIY C JGF WXX SGTEP FZCF OWM UPWA G CI YFMQU ZERE. ACY FZCF NMYF FW FZRWA WMR RGTCBY WLL FZE YQEPF?
+
+CBB FZE JEYF,
+
+NWXGE
\ No newline at end of file
diff --git a/2017/3a.plaintext b/2017/3a.plaintext
new file mode 100644 (file)
index 0000000..0623f25
--- /dev/null
@@ -0,0 +1,16 @@
+MARYAM,
+I THOUGHT SOME MORE ABOUT WHAT YOU SAID IN THE HOSPITAL, AND GIVEN WHAT HAS HAPPENED I THINK I IT WOULD BE GOOD TO WORK TOGETHER.
+
+UNFORTUNATELY IT SEEMS THAT I AM NOT THE ONLY ONE TRYING TO FIND THE BOOK. THERE IS A THRIVING BLACK MARKET AMONG BIBLIOPHILES FOR ANYTHING AS OLD AS THIS. IT IS VERY VALUABLE AND IF THE BOOK DISAPPEARS INTO THE SHADOWY WORLD OF PRIVATE LIBRARIES WE MIGHT NOT SEE IT AGAIN FOR CENTURIES SO IT IS REALLY IMPORTANT WE GET TO IT FIRST.
+
+TACITUS CLEARLY WANTED TO MAKE IT DIFFICULT TO ASSEMBLE THE ENTIRE DOCUMENT, SO HE HAD IT HIDDEN AT A NUMBER OF SITES AROUND THE ANCIENT WORLD. THE BRITISH LIBRARY DECIDED TO SEND SOMEONE TO TRY TO FIND ALL THE PIECES. THEIR EXPERTS FIGURED THE CHAPTERS WERE LIKELY TO BE ENCRYPTED TOO SO, GIVEN MY BACKGROUND, THEY ASKED ME TO GO. THEY WERE RIGHT OF COURSE, THE FIRST CHAPTER WAS DISGUISED USING A CAESAR SHIFT AND THE SECOND BY A SCYTALE CIPHER, AND I AM BEGINNING TO WONDER WHAT OTHER CIPHERS TACITUS MIGHT CHALLENGE US WITH. AS FAR AS WE KNOW THE ROMANS WOULD NOT HAVE HAD THAT MANY TO CHOOSE FROM. I SUPPOSE HE MIGHT HAVE KNOWN ABOUT SOME FORM OF THE POLYBIUS CIPHER.
+
+THE DOCUMENTS I HAVE FOUND SO FAR (TACITUS LAST TESTAMENT AND CHAPTERS ONE AND TWO OF HIS HIDDEN BOOK) EACH GIVE A CLUE TO THE LOCATION OF THE NEXT ONE, AND AS SOON AS THEY LET ME OUT OF HOSPITAL I PLAN TO TRY TO LOCATE THE THIRD CHAPTER, WHICH TACITUS TELLS US IS HIDDEN ON THE ISLE OF THORNS. THERE ARE SEVERAL PLACES IN THE ANCIENT WORLD THAT THIS MIGHT REFER TO, BUT I HAVE A PRETTY GOOD IDEA OF WHERE IT MIGHT BE.
+
+IF I THINK OF ANYTHING ELSE I WILL GET IT TO YOU, AND AS REQUESTED I WILL COPY IN YOUR FRIEND HARRY. I SUGGEST WE TIGHTEN SECURITY A LITTLE. MAYBE IF WE BLOCK OUR CIPHER TEXTS LIKE THE EXPERTS IT WILL PUT OFF CASUAL INTERCEPTS. THE PEOPLE WE ARE UP AGAINST ARE UNLIKELY TO BE DETERRED BY MUCH, BUT WE DON'T WANT TO INVITE EXTRA INTERLOPERS TO THE PARTY.
+
+BY THE WAY, MY FRIEND IN THE SOUK TOLD ME THAT HE MET ONE OF YOUR AGENTS WHO WAS ASKING IF HE KNEW WHERE I WAS, WHICH SEEMS A BIT ODD GIVEN THAT YOU KNOW I AM STUCK HERE. WAS THAT JUST TO THROW OUR RIVALS OFF THE SCENT?
+
+ALL THE BEST,
+
+JODIE
\ No newline at end of file
diff --git a/2017/3b.ciphertext b/2017/3b.ciphertext
new file mode 100644 (file)
index 0000000..ea29c43
--- /dev/null
@@ -0,0 +1 @@
+MLLCL DCXXM LDDDL DDCDD DLDMX MDDLC XXDDD CDMXM DDCDC CLDDM DCDCX MDDDM CMDDL CXMLX LDCCX XCXXL XXDDD DCXXM MLLDD DLCXL CDDMX DLDXC XCXXX XDDML XXDDC XLDCC LLDCD DDLXM XMDDL CXMLC XXXDC CXMLD DDLCX MDLDD LCXMD DDLCD CDCMD CCCCD DLDDL CXMDD XXXCD DLDXC XXCXX XXLLD CXLDD DMDDD CDCDM XXMDL XCCDC LXMDD LCXML CDMLL XMCCD MCLXM DLLDX CXXCX XDLDD CXXXD MXXXC CDDXX LLXML XXXXC XMXDX LMDLC LDDCX XDLCL MDMLL DDDLC CDDMD DDDLC XMDCD MCMCM CDDLD DCDLX XXLLD LLDXC CDCXX XXXCC XDLCL DDCDD XXCXX MCCDD XMXDD CXCCD DMDDD CXDXM LXXMX XDDML CDDMC XXDLC XXMXX MXLXM XMCCL DCCXM MXLDD DXXXL CXXMX XCCXD MLLDD DLCLD DDDDL CXMCX CDDCD CCDLX XLDLL DDDXX CCCCL DXXLC XXMXL DCCLL DLXMX XCXLD DCXMX DDDLC XXDDD DLCXM LDXCX MCCLD MLXMD LXMDL XMXXX DLDCC LLLCL DDCXC CDCLC LDMCC LDXCX XDDLD CDCCD CXXLL DLLDX CCDCX XXXXD LDLXX CCLLX MXDDD CDCMC XXXCC DDLXX XCXDC XMLDC CLXCD DLCLX XDDLD CDCCX XXLCD DMDDD DLCXM CMCXX XCCCC XMXDX DLDDC CMCDD CLDDD LDCDC CCDLX DDDLC DCDCM DCDCX MDDDD LDCCL LXXDD DLXXC MLDCC DDCDM LLCLD XCLCD DLCXM LDXCX MCCLD LXXMC XCXLD DDLDD CDCDD LDCXC XDMCC XCCXX MXXDL LCCDM LDDLC XMDCX XMXXX LLXMD DDLLD XLXMD CLCXX XDCXX MXXDL CCXMX DDDCD XDXMX CLDCM LCXMD LCDDM DLXXD LCLMD DCXCC DCLCL DMCCL DXCXX DDLDC DCCDC XXDCD DLCXM MDLCX XXDCC CDMLD LLDDD LDCCL LCDLX DDLCX MLDDL CDMLC CLCCD MLXMM XXMDL XMMXX MDLMD XXDLC LMDLC XXDCL DDDDC DDDLX XLDDD CDDLD CXXCC XDLDD DDCXM XMCLD CCXLD LMXMC XMDDD CDCLX MDDLC XXDDC DCCXM CDDLC LCDDL XMCDL XDDLC XMCXC DXCXX CXDDD LLDXL XMDCC MXMCD CMCXX MDDDM DLCCX MXDDC CDCLX MCDCC XMDCL CXMXX XDCXC DMXXM CDDLC LCDCC XMMDL DDDLD DCXXC XCXDD DLXMX XXCLC XMDLM DXLDM DDDDL CLDDC XXXCD DDDLC DLXMX XDDXM CCXMX DDDCD DMCCX DXMDL CLLDC CXMDD LCXMX MCLCM LDDLX MDCXM CCDDL DDLXM DCMDD CDDXM CLCDL XDCXM XCDMD LXMXC CDCLC LDMCC LDXCX XDDLD CDCCD DLCXM XCXXX MDCXX DLXCL DCMLC XMDLC MXMDL LCXXC MDCCL CDDLX MDDLC XXCCD LCDXX XDDCL CXXXD XMCCX XXLCX XMXDD DLCXM XMCLC MLDDL XMDDC DLXDM CCXCD DLDCD CCDCX MXCDM DLXMC XMDXX CCXDL DDDDC CXCDD CDCML XXDCX XXDLD DCXXD CDDXM DLDDD MDLCC LDCCL LDDLC XXDDC XCDDC DCLDC CDDCD XXMXL DXCDD CDDLM DCDCC DDLCX MXLXX DDDDC XXMLX LDXMC XXDXD XMDCX MDLMX XMXDC LCDDL XMDLX MXCCD LLCCL DDDLD CDCCD DLCXX CCLDD DDLXM XCXML DMXXM XDCMX MDLLC XXCMD CDCDM XMDDC DCCLD DMDCC CXMMX XMDLL MCCXM MLCDD LCMXM DLLCX XCMDC LCXML XXXLD CXXMX DDDCD DMCCX DXMDL DCDDX XCCXD DDLCX MXCDM CCCCL DCCLL CDLXD DLCXM CMCXX XCCXL DMDDX MLDDD LCXMD LMLXX MDXDX MDCCM LDDDX MDDLC XMMXL DXCDD CDDLM DXXLL DLLDX CCDCX XXXXC CXDDD LCXMC CLDCC DDLCC XXMLL LDCDC CDLXM CLXXL DCCXM XDLDC CXDLD DCLLD LXXXC XMCDC CLCXM XXDLL DCCLL DDLCL DDCCC XMMLD CXCCX XXDMX DLDDM DCXCX XXMDC XXDLX XDMLL DMDCD DDMDC LLXMD LCLXX CCLDX CDMDC CCXMD LCDXM CLCMX MDLCD DLLDD CDCDM XMXDX XDCXM XCDLX MDDCM DLCDX CCXXX CLXXD DLDCD CCXMD CDDXX XLCXL DDCLC LDCCL LXXXC LDCML CXMDL DCXCL CCDCD CXDDC DXDXM MXXMC XCDCM XXCCX MMLDC MDDCD DXMCL CDLXL DCLCM XMDLL DXXCX XCLDC MLCXM DLDCL DDDML CDDLL MXMXD LDCCD CXMXC DLXMD DLXCD DLCDM XXMDL DDMLX MCCDD MDMDX MXXDL DCXDX MMXXM CXCDC MLDCC LLCCX MMLCL XMDDL CCDXD DCDDC DDCXM XCDMD LXMXC CDCLC LDMCC LDXCX XDDLD CDCCD CXXXC DLCDD CDCDD LCXMX MCLCM LDDLX MDCDD DMXDM DLDCC LLDDL CXMML CDDLL MDCCD LXDDL CXMLL DLXMX MLMDC XXLLX MDCXM DMXCC XLDXD XXCCX DLCMD CMXXD DLDXX XXCCX DXMMX XMCCC DCXXD XMDLM LCDDL LMDCL XDLCD CLXXC CXCLD XMCCD DXLXX XLMDC XCDCC DDLCX MDCXC LCCDC DCXXD XMMXX MCXCD CMXMX DCCXM MLMLX XMDDC DDCDD CXXLX XMLLD MXXDL XDXCC DCLCL DMCCL DXCXX DDLDC DCCDC LXDLC DCLDL CDCLX MDCXM CCXMC LLDXM DCDDL CXMDC XMCCX MMLDC MDDCD DXMCL DCMLX MDLXM MLDLL DDDDD XMCCX DCDML CCXXC CXDXD LDDCD DDLLD XLDMD DXMXD LDCCD DLCXM XCCDX DXMMC CDXCX CDMCX DDCDD LDMCL CMXMD LLCXX CMDCD DLCXM CLCDD CDDDC DDDLL DXCDD CXMDL LDMXX DLXDX MXDXD CDXCD MCLXM CCDDL DCCXX CXCXL CLDDC DDCDD LMDML LCXMC CLDDD MLXXD CLXLD CCXXC XCXMD XCCDC LCMCX XMDDX MXDCL XXCCM DMDXM XXDLD CCXXX DDXMD LDDLC XMXMC LCMXM DLCDD LXDCD CLLDD DLDXX CCLDD CDCDM XMXDX XCCXM MCXMX CDMDD LDMXX MCDDL XDXMD LMLLC LDXCL CCMDL XMLXX XXCXM XDXMM XXMDL MDXCC DCMMD CDLXD DLCXM XCCDX DXMMC DDLCX XDDLD DDMLX XDCDD CDXLX MLLDM XXDLX DXMXD XLMDX MMXXM DLMDC XXMLL LDCDC CDDCD DDLCX MCXXX DCDDC LXXCC DDLCX MXDXM LXXMX XDDCD LXDDL CXMLD XCXMC CLDXX CCXDD DLCXM DCDML DXCLD XDXMC DLXXL CDDMX DLDXC XCXXC MXMDL LCXXC MDCCM DLCDD DXMXC DDXMX DDDLC XMCCL DCCDD LCCXX MLLLD CDCCL XDLCD CLXDL DDCDC CDCXD MDDLD CDCCX XLLDL LDXCC DCXXX MLXXD CCXXX DLLLX MCXMD CXXML XDDDD CDLCL DDCCD MLCCX DXMMX LDXCX MDCLD CCDDL CXMCM DLCDM XLDCC XCXMD DLCCD DMLLL CLDDD MLXXD CCLXX XDXMX CCXXM XXDLD DCDLC LDCLD DLCXX DDDDC DDLXM DDDMD LCCML CDDMC XXDCL XMXXC CXXDD XLXMD CDDXD LDDCL LDLXX XCXMX XCCXD XXDDM LCDDL DCDDX DXMXX DDLCL DCCXX XLDLX MXXLM MLLDD DLCDD DLXXX DLDDD LDCDC CDDLC XMCCL DCCDD LCDLX XLDDC XMXDX XCCXM MLDCD DXXCC XDXXD LXDDD LCXMC XXMLL LDCDC CMLXX DCXMM CLDCX XMXDL DCCXD LDDCL LDLXX XCXMD DCDXM CCXDD MDLXM DDLCX MLCXX DLXDX XCCXD XDXXC CLLXM DLCDD MDCML CDDLL MCDLX DCDMX LXDDM LDCCL LDDLC XMXCX XCXXM XDCDC CLDLD LDCCD DLCXM XLCXX MXXLM MLLDC XXDXM DLCCX MDCDC XMDCC DLXXC XXCXX MXDCD CCLDX XDCDM XMDDC DCCLD DMDCC DDLXD XMDLX MXDDD LCXMC CLDCC DDLCD DCDCL XXDLX CLCDD CDXMX LCDDL XXXCD MCLML LCLDX CLCDD LCXMM DMLXM DLXMD DCDCL XXLMX MDDLC XMLDD LXLXX DCXML XCDDL DLXXL DXDDC LDCCD DCDXC XXCXX MXDCD CCLDX XDDLC XMDMC CDCCM CDLMX MCCDL XMXXD CCDCC LXCDD LDDLC XMLDD LXMMC LDCXX MMLXX DCDDL CXXDD LDCCD DXMCX CXLDL LXMCC XCXMD LXMCM CDDLD DDCDC DMLLL LXMDC DDXMX DDDLC XXDDD DLCLD DCMLX XDCML LCXMD LXMDD LCXMM DCLLD LLLCD DLXLD CCXDD DLCXM LDDLC XCDDC DDXXD XDMLD CXXXD DLCCD DCXMM LLCCD MLCDD MCXXD DLXMX XXDCD CCCLD MDCDD LXCDC XCXCD MLCLM DLXXX LDDDL CLXDM CXDCC XXXMX XMDDL DDLCD MLLCC DLXXX XCXMD CXXLL DLXXM XXMDD XXDCL MCMXM DLLCX XCMDC DDLCX MCXXX DLLLX MDCDD DDCDX DXXDD XMXXD CLCXM DDDLX XMXXM CXDCD DCDXC CDCCX CXMXX CXDDL CXMLX CDDMD LDDLC XCLCX XCMDD XMDLC DLXDD LCLDD CDDDL XXLLL DXCDD XXCXX M
\ No newline at end of file
diff --git a/2017/3b.plaintext b/2017/3b.plaintext
new file mode 100644 (file)
index 0000000..1234d55
--- /dev/null
@@ -0,0 +1,31 @@
+while it is true that suetonius setup the final vat tle with vou di ccaat watling street he had
+neither the troops nor the tactical avi lity to ober come the huge numerical disad ban tage faced vy
+his army without the support of agricola and his talented scouts defeat would habe veen in ebita vle
+and with it the loss of vr it anni ahab ing realised that the iceni were reading his communications
+agricola arranged to plant false information av out the planned disposition of troops setting a trap
+into which the iceni fell it is still unclear how the saba get rives had learned to decipher our
+army s communications as they had no writing of their own howe be reber y army has its traitors and
+it seems likely to me that one or more of the local t rives people turned someones head lobe or
+money it is all treachery vut this act threatened to undermine the empires entire system of secure
+communication the caesar cipher perhaps more than road shade nav led the empire to function securely
+and its loss was a disaster turning that loss into a bic tory on the vat tle field deser bed more
+recognition than it recei bed perhaps suetonius ne berk new or perhaps he failed to understand the
+cunning of the plan vut either way despite the bic tory agricola and the ninth legion remained in
+disgrace on hearing this news claudius caesar augustus germanicus nero emperor issued a secret
+proclamation est av lishing a cipher school to de belo pa new system of imperial ciphers it worked
+in secret for ober twenty years deb eloping new methods to secure communications across the empire
+studying the works of the greeks ages euclid and hypatia and eben older works from ancient vav yl on
+the school deb eloped new ways to safeguard communications from rome s enemies these new systems
+were written down and distri vu ted in the codex occult orum perhaps the most strictly guarded
+document in all history when it was finally completed many years later the emperor domitian issued
+an execut i be order which preface de bery copy of the codex that it was to ve guarded vye bery
+legion to the last man the defeat of the iceni and the suicide of vou dic ca perhaps protected the
+ninth legion from dissolution agricola was largely left to his own debi ces in the prob in ce though
+it was made clear to him that to return would mean at vest disgrace and at worst death in av reak
+with tradition the ninth raised a new standard the legion was exiled in disgrace to endure the hard
+and dangerous work of suv du ing the caledon ii in the v leak wildernesses of caledonia suetonius
+ordered the ninth to march to evora cum which they were to make their vase for raids into caledonia
+the unspoken reason for their exile was that intelligence reports suggested that this was where they
+might find their lost aquila those who would read on must follow my faithful sla be tiro who faces
+agra be task perhaps the largest to date a she trabel s to conceal the fourth chapter of this tragic
+tale
\ No newline at end of file
diff --git a/2017/4a.ciphertext b/2017/4a.ciphertext
new file mode 100644 (file)
index 0000000..5970d12
--- /dev/null
@@ -0,0 +1,13 @@
+UGXXV,
+
+BGXVGB THQQRTKRF N QRK NY KCHZU GT PR YRRF G ZCHXNRX GYF TUR KUCHQUK VCH BNQUK AR NYKRXRTKRF NY SCNYNYQ HT. URX TCHXZRT UGOR ZCYENXBRF KUGK KUR ACCL NT ARNYQ UHYKRF AV GY NIIRQGI EHYFXGNTNYQ QXCHM YGBRF BNFGT PUNZU UGT ARRY GTTCZNGKRF PNKU TRORXGI KRXXCX YRKPCXLT NY KUR IGTK ERP VRGXT. BGXVGB UGT KXGORIIRF KC NTKGYAHI ECIICPNYQ G IRGF CY KUR AHVRX NY KUR UCMR PR ZGY TZGXR KURB CEE, AHK NE KUGK FCRTY’K PCXL KURY PR PNII YRRF KC ENYF KUR XRTK CE KUR ACCL ZUGMKRXT ARECXR BNFGT FC. PR GXR ACKU UCMNYQ VCHX FNGXV NT ZIRGX, ARZGHTR NE N GB XNQUK PR PNII UGOR GYCKURX KUXRR MIGZRT KC ONTNK GEKRX KUNT CYR, GYF N GB YCK THXR UCP ICYQ NK PNII KGLR.
+
+N ENYNTURF BV PCXL CY KUR KUNXF ZUGMKRX CE KGZNKHT’T BCYCQXGMU PUNZU N ECHYF CY XUCFRT. NK PGT ZCYZRGIRF NY G IGXQR TKCYR INYKRI ARGXNYQ GY NBGQR CE G XCTR, KUR TVBACI CE KUR ZCYTCXK CE KUR THY QCF URINCT. NYKXNQHNYQIV XUCFRT NT GITC LYCPY GT KUR NTIGYF CE KUR LYNQUKT, YGBRF GEKRX KUR LYNQUKT CE TGNYK SCUY CE SRXHTGIRB, GYF KUR ZIHR GK KUR RYF CE ZUGMKRX KUXRR MCNYKRF KC GYCKURX UCBR CE KUR LYNQUKT GK ACFXHB, TC N KXGORIIRF KURXR GYF PGT YCK KCC THXMXNTRF KC ENYF ZUGMKRX ECHX ZCYZRGIRF NY KUR XRBGNYT CE KURNX ECXK. N PGT UCPRORX GTKCYNTURF AV KUR KRJK! NK KCCL BR G PUNIR KC ZXGZL NK GT N FNFY'K XRZCQYNTR KUR RYZXVMKNCY GT GYVKUNYQ ZIGTTNZGI. PURY N ENYGIIV AXCLR NK N FNTZCORXRF KUGK KGZNKHT UGF HTRF G ZNMURX KUGK PR KUCHQUK UGF ARRY NYORYKRF NY TNJKRRYKU ZRYKHXV EXGYZR. NK TRRBT KUGK KUR NBMRXNGI ZNMURX TZUCCI PRXR BHZU BCXR GFOGYZRF KUGY PR UGF GYV XRGTCY KC RJMRZK. NE ZCHXNRX FHKV NTY'K RJZNKNYQ RYCHQU ECX VCH MRXUGMT KUR ZUGYZR KC FNTZCORX BCXR NBMRXNGI ZNMURXT PNII AR?
+
+KUR ZIHR GK KUR RYF CE KUNT ZUGMKRX NT ORXV THQQRTKNOR, GYF N UGOR ACHQUK G KNZLRK KC TRIZHL KC NYORTKNQGKR. N GB MXRKKV THXR N PGT ECIICPRF KC KUR KNZLRK CEENZR.
+
+NE VCH ZGY ZCBR KURY PR YRRF VCH KC FXCM AV KUR AXNKNTU BHTRHB ARECXR VCH ZCBR CHK. N KUNYL KURXR NT TCBRKUNYQ KURXR KUGK PR YRRF GYF PNII TRYF G BRTTGQR KC BV ZCYKGZK NY XCCB KPRYKV KPC KRIINYQ KURB KC RJMRZK VCH GYF AXNRENYQ KURB CY PUGK KC ICCL CHK ECX. NK PCHIF AR QCCF NE VCH ZCHIF AR ORXV FNTZXRRK GACHK KUGK, AHK BGLR GT BHZU EHTT GT VCH INLR GACHK BRRKNYQ BR NY TRIZHL. N PNII RJMIGNY IGKRX!
+
+GII KUR ARTK,
+
+SCFNR
diff --git a/2017/4a.plaintext b/2017/4a.plaintext
new file mode 100644 (file)
index 0000000..2fe881e
--- /dev/null
@@ -0,0 +1,13 @@
+harry,
+
+maryam suggested i get in touch as we need a courier and she thought you might be interested in joining us. her sources have confirmed that the book is being hunted by an illegal fundraising group named midas which has been associated with several terror networks in the last few years. maryam has travelled to istanbul following a lead on the buyer in the hope we can scare them off, but if that doesn’t work then we will need to find the rest of the book chapters before midas do. we are both hoping your diary is clear, because if i am right we will have another three places to visit after this one, and i am not sure how long it will take.
+
+i finished my work on the third chapter of tacitus’s monograph which i found on rhodes. it was concealed in a large stone lintel bearing an image of a rose, the symbol of the consort of the sun god helios. intriguingly rhodes is also known as the island of the knights, named after the knights of saint john of jerusalem, and the clue at the end of chapter three pointed to another home of the knights at bodrum, so i travelled there and was not too surprised to find chapter four concealed in the remains of their fort. i was however astonished by the text! it took me a while to crack it as i didn't recognise the encryption as anything classical. when i finally broke it i discovered that tacitus had used a cipher that we thought had been invented in sixteenth century france. it seems that the imperial cipher school were much more advanced than we had any reason to expect. if courier duty isn't exciting enough for you perhaps the chance to discover more imperial ciphers will be?
+
+the clue at the end of this chapter is very suggestive, and i have bought a ticket to selcuk to investigate. i am pretty sure i was followed to the ticket office.
+
+if you can come then we need you to drop by the british museum before you come out. i think there is something there that we need and will send a message to my contact in room twenty two telling them to expect you and briefing them on what to look out for. it would be good if you could be very discreet about that, but make as much fuss as you like about meeting me in selcuk. i will explain later!
+
+all the best,
+
+jodie
diff --git a/2017/4b.ciphertext b/2017/4b.ciphertext
new file mode 100644 (file)
index 0000000..d59e1ba
--- /dev/null
@@ -0,0 +1,14 @@
+OMGR GHM KTEIA BHV JEEOQO GSCM WF RIRVCWXP EK EITCKNT SBDTIK KIMV VO GHM ZDXZKM OW TOZE IZS XNW LETCDRS TMIII PM WRU ACPWUCXVL XRF EOASCX PRU OWVVTNBR WR QVZBINEKA OY MYEIIWZ VVUPNSQMC. E WME YVCRF ANFTV YQA AGROVNBYTRK DMSGCSVAV’E HSE, LWMZVINN, JQREDM MMGGRBR, IZS SEM WF YKS SIZEI ETBA WRU TB IAEJI KPM OIFEE TW UBTCMUEEV TUE VQL MDXMRZCL PIXTTVJ QVVVPTRD JK ILV KQPYGR FCPADP.
+
+ZV BHV KNGEZHTRZVO YVCRF TPQ CMEBP HRF BREV XTJK BW FZIHG LWZTPP ASIIOIFHME PRU JITKNEF FZAB XYMQR SCSR AB QQSIIKUD. YIGH NAGXZBCDV CNQ RMEDPMM BHVA RRPMMIIUTG DIQVR TPQ QEIJIRZCNF BIOZ MEBW TYG CBLL TTEIBTAEFS BF KMAIUWVIR. FUEIVS DRV ACCY UKVRUUHL MIZUJ YAF MWDIECTG WFWNQEL MCH ROZITQLN PZABSKML TYG TEIJGCI DIZCLU FVDMXXYJ KITF VO GHM XTKRBCS FH TUE VUCXY.
+
+WVE UCY GHM XJGB WN TYG NVNBT HIVUMD KQ CUAVST. E IMKOEPAVSAMCGV AYURF RRPWDIIU BPAK VHRY PMS WVMV TYG ADUQXP JCGQNX HRBM I FGIV IB MFPS TRIGEMLA, QN R EAZP ZGAIU JG A KTIOEAYPR TITLVF CNLOMRYJ. BPE EGW YEOMIYJ ZMCFINVSMP ILRB BHV RRVVIFXSEA WF R NOAG UMGGY PID VZHNUAFTH YQA MVP, TUEG ITVV VWT IGAQY NAG FRBBLV CNQ CIFD WYWCLU JAIE AQCX WWZ RVKNSOZOTQVVBS, SWT GHM VDC FN AEVKNT TPQ ASJB IQLKLN SW OASJM IT YCNQ CTAJHVL PIJ LUQGMYTRK, IVD YG LNUVOWIU IV AKVAPK CZSII BPE TQVRR WR SEISVEJU.
+
+FVGPFXRX CXHZNL NGIUCWK EIVV WPBN EMKI FN JAIDAEIIZH, XYM TEXKOA’S PQGSZK MFWQRGS EQGI WZCSKTAGEL NN XYM AUE TIFIVS IS STQNU VHRM IE SENV JRFME. GHM FGSFXA IE VHR FZACX CQVE XCVR WIK LMKP MXYCUFTQAC EEL BHV YIYD KMAKRKCS UCSUEL AJX FN BHV UUA DWIC XYM JLFQD-FOIWTH JTWPV YIGH PUH GRDILIA IATW FWI YMIRK QF GHM XTKZWV. TYG LRGQAC VRQVEU HLNMQZV EIZWWJ WPBN BTT IEMUY RPD ZAVMVIU BW UEJOESM OPPXIKUJ VAXIVS WMD XZIJQNRR, JGI GFCTD DCKR NW TTEUEIY RIAVNAF ILV AIVRIE UOZPTW RVL WVTE HNINAI KW ZEREH GHM EISCMV AHWIYA. EAGWV EIS KQ CBMM.
+
+IWMCM KAKQ OEGIZXWVL I RVVRRAB IXXY BPE GTIFOVQG GRTOATWS VN KTPMEA, BHV TEZAQZXRX AWLUKEES PQAH KPM LZPE NGIUCWK ZMPVCTRD KTPVXMA BP EAYELACMRV INU KCRNQMC XIQJEJOEA. WPQC XYM TIEG FVNIXAC SZWKV, EAGO IZS QRVG OW VHR NQZIL CMOIFP HND ZQPGYML SRHEGY IZS XFWS SKQCX. TPQ REMITRP YEEE AMUI, RA EEIG MNNG AU XYM JRRXE YEOUDREIQRVU, BHT BA WMJ PWRIQR, PABA GIRTQSVF TUAB UC XYM JAKVLR HM TPH CWAT KJE FEKACH RYCICC, AAD EAGWV, BPE CGGVOV’E RSGG WF KJE POLQM LRL ILJQ GBNM.
+
+FWI UWKUDGNGS TQUX KW UE SA ATRQODPR IZE LPCYEID DR KPQS GQIAT. LUS LV SVON VHNT BTT GFLMX DKGUT PMKI WITLVP IATW QCIDG PAEFS NNL FWEK I AETQNQ AYGXPR PID SGEA LWEI? SI LQD TCTB AAEJVV PQM KJAG TPQ RSUMF HRF BREV PTWKZWYVF AF PIDI SW IV OIFEELG DTXIMIT? GGRUAXE REKW EAJ AEG TW DT-NFQV AXTIPOTM PX KPM FFTT, NNL ODQDCVITCTVOVE UVFU BHV DAGTTQ WEU GMT KQ RRAKT WMD. QV A CGTGEZ FD IDXMRFT DBMQFXEE, IORZEOYA EDDXV “UWSK GXPETXTRK MUPVTOE, AA KDY YIDE DQSG GZMRMFCALP TEDUMEIIU Q PAMG FVNQEWIU UG AWHAVRA TTVV QV BIKTNNVUP ME XZEGCRNTQAC JFZ ZEKWRAIVS IS PWCR JKDR IV DDQV. QB PCGAFEA YT XF ZMPFTT GO GAJ XYIB BP CCGS WR SMGTWMREY NNL EIVVVOTY K HNVM BTVJCIDVF TUE VAGXYMZN IGBRLA FD CZMTD KQ OHR IDBC RVL TF VUEN WHTV KW CS KJE EEJQA GRTOATWS JHW TPW IMUAZPEQ FZQT WZVKE KJE JAZE PKRQVSK DOHDQORE RVL TYG IPEVU.” WMJ TMTKGR NPXQPVJ BW HRXE OEMZ P VVXTY KQ NRW WDSIIA NRFO RBMM UC AYQKH UQMVTQMC AIWBE “DA EFTMQBIU OVAVWS, HPWZ GITMQPK QF LOCD BSJB ZETGNG LMFIII Q PAMG BREV YDWK BZOLDLRD. QF PTGMIRJ ELRAZ FD QV BPAK VHR SQFJEKQWN ZP BEIBMCRZI PAJ YOESMZTH RVL SF K MHSB MHO PWC TF TEGUZZ IS DM IT IQMR WQFW XYM CTDQSG SXQTH. TWVDLET LOCD GIDIQNZPG NFNMXVJ QV TYG PEODUCGV IVD UQ NBT CZSIIBIKV CNL AKFXSE EPITJ MNY MZUPRUM TYG CHRZQCX KMVSZQNF BMFLIVV GOLTSRLN MCH KPM CRNEQOVUX.” XYM NIECL YIVQ DJ KPM EDREEOZ’E AIKBMR JGT N DMMSPZVM FFT ATRQODPR’A ZEKWRA, “I ATPPC MFPVET LOC FD LRDM CIQSFEL FWI ICJITQN OY BTT IEL WF KJE LEID”, PRU XMRYCPF HM RTPK BPAK EOATZUIMFV EAJ C SNFMD GIWCOE.
+NJAGEDQG EXZQCFNA XNMI PX KPIT GQIAT, EUILZV I MFPTU HQE LSITL HRF BREV FJVEML UGUIQE LALR, RA NUIVHRR ZQESIBA FIQM PATQSSEQI MRFE PLMMG XYIB HZU HBPM AU VVABOICTVOV UC XYM MYVU OS TPQ TQGMZOI YEEE QZ GIRT REFRAEDG. TT WVB WUK VO EEKAKII BPE KYO NQCUAEV IVD KQ DRTMDBMEM EHRV HND PMETVVMD KQ TUE KASIO JMFFTE EEBGGRZVO TF TOZE.
+
+BTDWV EPO IGAQ OV YJWK AMAIEH SOZ FWI KZCTY KN GHM EEMIQBURN HBMM AU XYM IMRBOAS.
\ No newline at end of file
diff --git a/2017/4b.plaintext b/2017/4b.plaintext
new file mode 100644 (file)
index 0000000..30bfeb5
--- /dev/null
@@ -0,0 +1,42 @@
+over the years the heroic role of agricola at watling street came to the notice of rome and two
+decades later he was appointed proconsul and governor of britannia by emperor vespasian a few years
+after his appointment vespasian ss on domitian became emperor and one of his first acts was to issue
+the order to implement the new imperial ciphers invented by the cipher school in the intervening
+years the ninth had been left to fight lonely skirmishes and battles from their base ate bora cum
+with fortitude and resolve they repeatedly drove the barbarians back into the cold heartlands of
+caledonia during one such skirmish varus was mortally wounded and agricola promoted the tribune
+marcus fidel i usca to to the legatus of the ninth one day the luck of the ninth seemed to change a
+reconnaissance squad reported that they had seen the aquila flying from a tree at mons grau pius in
+a camp ruled by a tribesman called cal gac us the new legatus recognised that the privations of
+along march had exhausted his men they were not ready for battle and ca to should have sent for
+reinforcements but the joy of seeing the lost aquila so close at hand clouded his judgement and he
+launched an attack under the cover of darkness fighting uphill against wave upon wave of barbarians
+the legions heroic efforts were frustrated by the sun rising to blind them as dawn broke the troops
+in the frontline gave way with exhaustion and the wild cal gac us dashed out of the sundown the
+blood soaked slope with his cavalry into the heart of the legion the legion rained flaming arrows
+upon the enemy and managed to un horse cal gac us taking him prisoner but could make no headway
+against the savage hordes and were unable to reach the stolen aquila worse was to come while ca to
+organised a retreat with the prisoner cal gac us in chains the remaining soldiers held the line
+against repeated charges by caledonian and iceni an tribesmen when the line finally broke ca to and
+many of the ninth legion had reached safety and took stock the cavalry were safe as were many of the
+brave legionnaires but to his horror ca to realised that in the battle he had lost the second aquila
+and worse the legions copy of the codex had also gone the documents left to me by agricola are
+unclear on this point did he know that the codex might have fallen into enemy hands and that a
+second aquila had been lost or did ca to assure him that the codex had been destroyed as part of an
+orderly retreat perhaps ca to was yet to rejoin agricola at the fort and communications from the
+battle had yet to reach him in a letter to emperor domitian agricola wrote most excellent emperor as
+you have most graciously requested i have finished my affairs herein britannia in preparation for
+returning to your side in rome it please sme to report to you that by acts of diplomacy and strength
+i have persuaded the northern rebels to yield to our army and to turnover to us the rebel cal gac us
+who has remained free since the wars against boudicca and the iceni his letter appears to have been
+a reply to new orders from rome in which domitian wrote my esteemed gnaeus upon receipt of your most
+recent letter i have been most troubled it appears clear to me that the situation in britannia has
+worsened and so i must ask you to return to meat rome with the utmost speed conduct your remaining
+affairs in the province and do not undertake any action which mayen flame the current tensions
+between yourself and the caledon ii the final line of the emperors letter set a deadline for
+agricola s return i shall expect you to have crossed the rubicon by the end of the year and perhaps
+he felt that contrition was a safer refuge whatever agricola knew at that point within a month his
+world had been turned upsidedown as further reports from caledonia made clear that his hope of
+restoration in the eyes of the emperor were in real jeopardy he set out to recover the two aquilae
+and to determine what had happened to the codex before returning to rome those who read on must
+search for the truth in the spiritual home of the amazons
\ No newline at end of file
diff --git a/2017/5a.ciphertext b/2017/5a.ciphertext
new file mode 100644 (file)
index 0000000..b214b58
--- /dev/null
@@ -0,0 +1 @@
+JDPWD JGLOF YBDQA LKYFD PPFTY OFKQY ICSHD QMIDK KYOES RQBYO FOKRJ DHYRB YPYKO YXTLS QRBYI LCDIQ RDRFL KRBFK HQBYJ DWBDT YEYYK HFOKD MMYOE SRRBY PYBDQ EYYKK LPDKQ LJOYJ DKODK ORBYP YFQKL RBFKA JSCBR LALLK BYPPL LJBDO EYYKP DKQDC HYODK OQBYI YZRKL JYQQD AYESR QLJYR BFKAR YIIQJ YQBYF QLHDK OUYQB LSIOJ LTYLK FRBFK HQBYJ DWBDT YMIDK KYORB FQJYD KUBFI YFBDT YRBYO LCSJY KRGLO FYUDK RYOZP LJILK OLKFO LKRHK LUBLU QBYHK YUESR RBYZF ZRBCB DMRYP UDQBF OOYKF KDCDT FRWFK DQRLK YIFKR YIFKQ LJYPY JDFKQ FKRBY YMBYQ SQPLL JDRRB YEPFR FQBJS QYSJF RUDQY KCPWM RYOSQ FKADK LRBYP MLIWD IMBDE YRFCC FMBYP FKTYK RYOFK RBYKF KYRYY KRBCY KRSPW FDQHY ORBYJ SQYSJ RLRYQ RFRDK ORBYO LCSJY KRFQD SRBYK RFCQL FASYQ QRBYF JMYPF DICFM BYPQC BLLIP YDIIW BDOJL TYOLK MYPBD MQFQB LSIOK RBDTY EYYKQ SPMPF QYODZ RYPRB YOFQC LTYPW DRELO PSJES RFRIY DTYQJ YULKO YPFKA UBDRY IQYRB YWOYT YILMY OLKYL OOZYD RSPYU DQDZP FYXYP SKKFK APLSK ORBPY YQFOY QLZRB YIFKR YICLK QFQRF KALZD QFKAI YPLUL ZEIDC HDKOU BFRYR FIYQR BDRRB YJSQY SJRBF KHUYP YDOOY OFKRB YPLJD KMYPF LORBY WPYDO FKQYN SYKCY UUEEU UUEUU UEUUU EUUUE UUUEU UUEUU UEUUU EUUUE UUUEU UUEUU UEUUU EUUUE UUUEU UUEUU UEUUU EUUUE EUUUE UUEUE UEUEU EUEUE UEUEU EUEUE UEUEU EUEUE UEUEU EUEUE UEUEU EUEUE UEUEU EUEUE UEUEU EUEUE UEUUE UUUEU EEEUE EEUEE EUEEE UEEEU EEEUE EEUEE EUEEE UEEEU EEEUE EEUEE EUEEE UEEEU EEEUE EEUEE EUEEE UEUUU EUUUE UUUEU UUEUU UEUUU EUUUE UUUEU UUEUU UEUUU EUUUE UUUEU UUEUU UEUUU EUUUE UUUEU UUEUU UEUUU EUUUE UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUEUU UEUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UEUUU EUUUU EUUUE EEUUU UUEEE UUUEU UUEUU UEUUU EUUUU EEEUU EUUUE UEEEU UUEEE EUUEE EUUUE EEUUE EEUEU UUEUU UUEUE UUEUU EUUUE UUUUU EUEUU EEUUE UUEUE UUUUE UUUEE UEEUE UUEUU EUUUU UEUUE UUUEU UUUEU UUEUU UEUUE UUUEU EUUUE UEUUU UUEUU UEUEU EUEUE UUUEU UUEUU UEUEU EUEUU EUUEU UUUUE UUUEU UEUUU UEUUE UUUEU UUEEE EEUEE EEUUE UUUUU EEEEE UEUEU EUEEE EEUUU EUUUE UUUEU EEEEU UEEEU UUEEE EUUUE UUUUE UUUEU UUEUU EUUUE UEUEU UUEUU UUUEU UUEUE UEUEU EUUUE UUUEU UUEUU UEUEU UUUUE UUUUU EUEUU UUEUU UUEUU EUUUE UUUEU UUEUE UUEUU UEUUU UEUUU EUEUU EEUEU UUEUU UEUUU EUUUE UEUUU UUEUU UUUEU UEUUU EUUUU EUUUE UUUEU UEUUU EUEUU UEUUU EEEUE UUUEU EUUUE UEUUU EUUEE EUUEU UUEUE UUUUU EEEEU UEUUU EUEEE UUEEE UEUUU EUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU EUUUE UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUUUU UUEUU UEUEU UUEUU UEUUU EUUUE UUUEU UUEUU UEUUU EUUUE UUUEU UUEUU UEUUU EUUUE UUUEU UUEUU UEUUU EUUUE UEUUU EUEUE UEUEU EUEUE UEUEU EUEUE UEUEU EUEUE UEUEU EUEUE UEUEU EUEUE UEUEU EUEUE UEUEU EUEUE UEUEU UUEUU EEEUE EEUEE EUEEE UEEEU EEEUE EEUEE EUEEE UEEEU EEEUE EEUEE EUEEE UEEEU EEEUE EEUEE EUEEE UUEUU UEUUE UUUEU UUEUU UEUUU EUUUE UUUEU UUEUU UEUUU EUUUE UUUEU UUEUU UEUUU EUUUE UUUEU UUEUU UEUUE UUFBD TYSQY OEZLP RBYEI DCHRF IYQDK OUZLP RBYUB FRYLK YQFRR LLHJY DUBFI YRLZF ASPYL SRRBD RRBYZ PFYXY FQQRY ADKLA PDMBW CLKCY DIFKA RBYHY WULPO ZLPRB YCFMB YPFKC BDMRY PZFTY UFRBL SRGLO FYFDJ KLRQS PYUBY PYRLA LKYVR RBYPY DPYLK IWRUL MLQQF EFIFR FYQDQ ZDPDQ FCDKQ YYESR FBDTY KLFOY DUBYP YLKYL ZRBYJ FQDKO DQZDP DQFCD KRYII KLLKY YIQYH KLUQY FRBYP QLFAS YQQFU FIIBY DOZLP LIWJM FDQYY WLSRB YPY
\ No newline at end of file
diff --git a/2017/5a.plaintext b/2017/5a.plaintext
new file mode 100644 (file)
index 0000000..92d59c2
--- /dev/null
@@ -0,0 +1,35 @@
+maryam jodie has gone i arrived in selcuk as planned but she didnt make the rendezvous the local
+station think she may have been kidnapped but there has been no ransom demand and there is nothing
+much to go on her room had been ransacked and she left no message but something tells me she is ok
+and we should move on i think she may have planned this meanwhile i have the document jodie wanted
+from london i dont know how she knew but the fifth chapter was hidden in a cavity in a stone lintel
+in some remains in the ephesus room at the british museum it was encrypted using another poly
+alphabetic cipher invented in the nineteenth century i asked the museum to test it and the document
+is authentic so i guess the imperial cipher school really had moved on perhaps i shouldnt have been
+surprised after the discovery at bodrum but it leaves me wondering what else they developed one odd
+feature was a frieze running round three sides of the lintel consisting of a single row of
+blackandwhite tiles that the museum think were added in the roman period they read in sequence
+wwbbwwwbwwwbwwwbwwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb www bbw
+wwbw wbwbwbwbwbwbwbwbwbw bwbwbwbwbwbwbwbwbwbw bwbwbwbwbwbwbwbwbwbw bwbwbwbwbwbwbwbwbwwb www
+bwbbbwbbbwbbbwbbbwb bbwbbbwbbbwbbbwbbbwb bbwbbbwbbbwbbbwbbbwb bbwbbbwbbbwbbbwbbbwb wwwb wwwb wwwb
+wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb www
+www www www www www www www www www www www www www www www www www www www www www www www www wwbw
+wwbw www www www www www www www www www www www www www www www www www www www www www www www www
+www wwwb wwwb www wb wwwb bbw wwww bbb wwwb wwwb wwwb www bw www bbb wwbw wwbw bbb www bbbb
+wwbbbwwwbbbwwbbbwb www bwwwwbwbwwbwwbwwwbww www bwbwwbbwwbwwbwbwwwwb www bbw bbw
+bwwbwwbwwwwwbwwbwwwb www wb www bwwwbwwbwwwbwbwwwbwb www wwbwwwbwbwbwbwbwwwb www bwwwbwbwbwbwwbwwbww
+www bwwwbwwbwwwwbwwbwwwb www bbb bbw bbbb wwbw wwww bbb bbw bwbwbwbbbbbwwwbwwwbw wwbw bbbb ww bbb
+www bbbb wwwb www wb www bwwwbwwbwwwbwbwbwwwb www wwbwwwbwbwbwbwbwwwb wwwb wwwb www bwb www wwbw
+wwww bwbwwwwbwwwwbwwbwwwb www bwwwbwbwwbwwwbwwwwb www bwbwwbbwbwwwbwwwb wwwb www bwb www wwbw www wb
+wwbw wwbw www bwwwbwwwbwwbwwwbwb wwwb www bbb wbwwwbwbwwwbwbwwwbww bbb wwbw wwbw bww www bbbb wwbw
+wwbwbbbwwbbbwbwwwbww www www www www www www www www www www www www www www www www www www www www
+www www www www www wwbw wwbw www www www www www www www www www www www www www www www www www
+www www www www www www www www wbwwwbwbwwwbwwwbwwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb
+wwwb wwwb wwwb wwwb wwwb wwwb www bwb www bwbwbwbwbwbwbwbwbwb wbwbwbwbwbwbwbwbwbwb
+wbwbwbwbwbwbwbwbwbwb wbwbwbwbwbwbwbwbwbwb www bwwbbbwbbbwbbbwbbbwb bbw bbb wbbbwbbbwbbbwbbbwb bbw
+bbb wbbbwbbbwbbbwbbbwb bbwbbbwbbbwwbwwwbwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb wwwb
+wwwb wwwb wwwb www bwwwbwwwbwwwbwwbwwi have used b for the black tiles and w for the white ones it
+took me a while to figure out that the frieze is steganography concealing the keyword for the cipher
+in chapter five without jodie i am not sure where to go next there are only two possibilities as far
+as i can see but i have no idea where one of them is and as far as i can tell no one else knows
+either so i guess i will head for olympia see you there
\ No newline at end of file
diff --git a/2017/5b.ciphertext b/2017/5b.ciphertext
new file mode 100644 (file)
index 0000000..1cc612b
--- /dev/null
@@ -0,0 +1 @@
+Se vsv Rusyrrx fayyx ute Emaz ud Mpjmmwr ec lke kwrl mi hbi nqeqopzvsyi uh Nengepjii Ugxbhkz Giljjm Ymwxbrjivgz Npzhasx Zjrwgz cnk Uievm Purnnrsti Cmetjginxk, Ahjakbtr mrmyy “Hgw woxlnrk mm jtj zitwtn ip Yrqgcmfyckf aq ay ravh qyejnf. Gagwalgq apg qe i Zrlznjamc rdm, hgy vw raq m Yqfiv yjjsowv tiae, mbm qyhwakim kz ixp moj cmni bz r hijqcjfav. Ew xrq pahyn npx ar mhaxpz ci n pemmaa ud onp hz qeia xjw ipjhw. Ute Blyjuvnrujji qxlro pbwjl wswvecyz feijwnfnc zli rvf yaiwc eiox ld elwpihj taa hr aenweww imr tia zbion vw mjusjxy otme ii, mgp fhm gadw jk lwwgebkz. Ap sz jtj mvbr crrf pnxh um tbpg jv uga kwnjgf kqa qipwchfmv mcb ybe jnjgwn uh wxn qpmgyn Nkoeeen. Ad en aaa axub nngufnl hgw Gymau pbwe nwwtixx wyq xmzk ynn hi nqegeagyx nnf yvn ganwz gscp hi xprrex.” Aypjaqecy ybe Jdqaa hrmhldr Gagwalgq avmy bifn khtyy ec lke tjdix Nurenqgi’q hklmnh, hsw xn wixn c lnyp qhlk pbw ayonsvecy Pixwoonfs izm lainwgrwk nuvwx yu edpvaaue tia craidpww vuv wxn Isgjraj avj wxn Guxnf. Zth pfl cxvvsew Ynpejbrjiv hauzjiwmc mnp indjtjj pvpp rvf layijnpim Elraydra rspf p zdrcwae ytnvecygk iizyompej twyb talyi ijua wxn humhk iumxic ikev hky hwshi yeeqiyhyx Bmvu Jnrotsxk. Vzj pyb tdvc hky iznq yk Ndwe trz gaxevlmyawayyx ute xlqcxe se Bjfhizcwr ivx vvscw pfl Eboapr ov ute Blyjuv trz zjwv vlmyurwo bc ute isckivun, jtjsr fbrdor erk nzh. Igywpuxa mcyjx i vllxrv hd Lmbw, bsdwgaihjon nnf mesdqp ynlhnsv jleyb. Ptn ksqhb kiecpej dx op hibl qm muw jk utarjlb qk xslvhasvg, okgx ino oad.
diff --git a/2017/5b.plaintext b/2017/5b.plaintext
new file mode 100644 (file)
index 0000000..8f092ff
--- /dev/null
@@ -0,0 +1,15 @@
+In his Journal dated the Ides of October in the year of the consulships of Caecelius Tullius Capito
+Pomponianus Plotius Firmus and Gaius Cornelius Gallicanus, Agricola wrote “The mystery of the battle
+at Camulodonum is at last solved. Calgacus may be a Barbarian now, but he was a Roman citizen then,
+who betrayed us all for love of a barbarian. It has taken all my skills as a leader of men to keep
+him alive. The Legionnaires spend their evenings designing new and cruel ways to execute him in
+revenge for the shame he brought upon us, but his life is precious. It is the only card left to play
+in our search for salvation and the return of the stolen Aquilae. If we can also recover the Codex
+then perhaps its loss can be concealed and our lives will be spared.” Releasing the Roman traitor
+Calgacus must have stuck in the proud Agricola’s throat, but he made a pact with the remaining
+Caledonii and travelled north to exchange the prisoner for the Aquilae and the Codex. But the
+cunning Caledonian tribesman set another trap and presented Agricola with a forgery cunningly
+assembled with pages from the books stolen when the tribe ransacked Mons Graupius. For too long the
+sons of Rome had underestimated the people in Britannia and while the Aquila of the Legion had been
+restored by the exchange, their honour was not. Agricola faced a return to Rome, humiliation and
+almost certain death. The sixth chapter of my tale of woe is guarded by lightning, bull and oak.
\ No newline at end of file
diff --git a/2017/6a.ciphertext b/2017/6a.ciphertext
new file mode 100644 (file)
index 0000000..2f4b996
--- /dev/null
@@ -0,0 +1 @@
+Lelqzq, C xnyhv Isxad en Gkcghhe ufc wbw gem ugejldv maw efjdexq. Rly zzh vwdr fwzhcff xbw LMXSR sjwqenauim gm e qakh agnwy ugemw zvimmh Mwkgoc leeamk u dnx ix msckd evgtx fgnocff jij sly ehwmamk wzztnwq en lgi Nwltfw nj Ujsigar. Xbss kund qy lhqy ln vylqmynd mn xqsg Bnhcw'r jladrx ss xbw Avclhwb Etwyml, ababl bsr e wgkpyusmif nj ujsizsbxm xqsg lgi Nwltfw. Isxad wuqr wbw jryo vi qgtpx xhkojd sol vlyjd xi yn ryps. Xbw bpow vem am xbw kswssmifr. Xbw emlks shw vem ss xbw Fvyss Tsjzqcv, sly kdgifc en lgi zgqx ix Peclaes ogmwz vem ttmfl evie sly jtmhk nj nzd Pcygxbgtwy ss Efwwehvqmu smh nzd xbaqh if Qlivdw, uenra lgi lmhrm ge xbw Bsfgrwok. Sly Cmmazs'w wsrxfw zx Vgcvoe vem ttmfl evie sly jdquamw ix sly Ezymgkioe zx Bskmwsqrukrym, zdrww sly “yqepw” semc nj amzvxamk nzd figj. Wi skp zaui wzztnwqw qwqi zgtrx ss xbw rmnw nj ifd sz lgi Mwuih Onrxwqw ix sly smgcwmx qgqpx. Lgi ifkc lwlecfhra dngulhshk zvy lgi Mlzxow nj Twtw ul Npseomu smh nzd Luffmhy Felvdrm ge Futxpif, zrx fn-shw gem smc cvde qzdvy lgi asqhyfr qcygx bsui vwdr, mg sly gmps hkeww vi wgtpx yn ryps mm Gkcghhe. Nzd gfmd en lgi yfc sz ugejldv zaui jghrnk rxlshkbl slyjd, wcfbi faflnamk, vmkp ufc suc zvy skp mqlfidr sz Rdym. Od wbgtpx td wuxd lyjd fyuzymw Isxad'w hwsaijj luk rihl gil ssxuujilk nr ng Kshvnr vq kesamk u dnra lqecd nj zgqkyv cswmlihlr vyndefamk nzd piuzxcgm sz ugejldv zaui. Nzzx vgtkbl tw yfnyaz smgw ss fgbenw zrx vdgchgil ugejldv maw. Ay zzh vwdr nzhreamk utnyn lgi ynnpolhsh ge xbw Hqjwqmud Bmjzdvm. Lzgcltw okdh vgsl nzd Zcydryjd ehv Aiumesll bmjzdvm ogmwz zvy hnpssktbsainab zyjrmifr sz lgi Wsdwuj rlcxs, ehv zx zaqwn od emktqyv slul bluhsil khb qgtpx td ihuqcjldh nzd wued auq. Vi qwqi udlsml qmazs. Qysmabaki Dgcmy'k trypoiwldh nskihl esl xnvawqc bsr kcndr gw zr cvde. C lgmhc vi gafln td evdd xi ltvh gtv yfdqcwr sh gmi ufnxbwq fs wwtfghxcff lyj fmzl, ayn A jrio gil utvlwmx zgbym ar jcytvcff sol vlyjd sh wzvnz sly kdzyfsl qgmhyj lmazs fy.
\ No newline at end of file
diff --git a/2017/6a.plaintext b/2017/6a.plaintext
new file mode 100644 (file)
index 0000000..f99da03
--- /dev/null
@@ -0,0 +1,20 @@
+Maryam, I found Jodie at Olympia and she has chapter six already. She had been leading the MIDAS
+operatives on a wild goose chase around Selcuk making a lot of noise about looking for the missing
+chapter at the Temple of Artemis. That gave me time to retrieve it from Jodie's friend at the
+British Museum, which has a collection of artefacts from the Temple. Jodie says she knew we would
+figure out where to go next. The clue was in the locations. The first one was at the Great Pyramid,
+the second at the fort of Qaitbay which was built from the ruins of the Lighthouse at Alexandria and
+the third on Rhodes, among the ruins of the Colossus. The Knight's castle at Bodrum was built from
+the remains of the Mausoleum at Halicarnassus, hence the “grave” task of guarding the book. So all
+five chapters were found at the site of one of the Seven Wonders of the ancient world. The only
+remaining locations are the Statue of Zeus at Olympia and the Hanging Gardens of Babylon, and no-one
+has any idea where the gardens might have been, so the only place we could go next is Olympia. The
+clue at the end of chapter five points straight there, since lighting, bull and oak are all symbols
+of Zeus. We should be safe here because Jodie's network has sent her attackers on to London by
+laying a long trail of forged documents revealing the location of chapter five. That bought us
+enough time to locate and decipher chapter six. We had been thinking about the evolution of the
+Imperial Ciphers. Tacitus used both the Vigenere and Beaufort ciphers which are polyalphabetic
+versions of the Caesar shift, and at first we assumed that chapter six would be encrypted the same
+way. We were almost right. Meanwhile Jodie's unexpected talent for forgery has given me an idea. I
+think we might be able to turn our enemies on one another by exploiting her gift, but I know her
+current focus is figuring out where on earth the seventh wonder might be.
\ No newline at end of file
diff --git a/2017/6b.ciphertext b/2017/6b.ciphertext
new file mode 100644 (file)
index 0000000..b2fbba6
--- /dev/null
@@ -0,0 +1 @@
+Ykuf rqhuddq rgz ppismxooeyz ud ogmp prlzqa er lop nlovktvfnx oyzcqdzov dve cxuaibk vg Lbejrvpsl arh dtwobnim lw Dfgg ta uqg onb lr fln mgmd, rp ybvigkx vx dbo Qxugbuv. Ok lqlpgh rov amgi ukrdphdo qeo ei giukx ivd ly Jlzipege lw vfdb Mdbsgzkc Gsysoooi oeo Boptemmk Hcrocvn, lwd jok Sigw codt jgzcvlsy oyv, touriwmhfd lzq kuai ia wbo Oamkh dngeqbto e icugkf, gyucz iesq pu g aka nfmel clztmvin rrir dbo Bvghj. Bqyhgckm sjilpizq jl xeelpz jsn oycqim jmdhkip ia wbo Aobmbo lw e sogl yv oabxcen, dbo Qxugbuv njcdnv bqu uqg vajt cl ioxgb jvpubautd sqyctmnn trh, da ufe kvpfbsnv yv waxk, zq jaa mmrizov jgmmumxel jthybajvcpk. L whmrbv cmw igkqrnv ly rov Aonguk wb oxg gdmvt gj jok Eumctgd, ydh, paytv gnk, Aubsfndm ygn eebo dy lsiv mweiuho iy xii xrzilm inlcrn ybodt qg kac ukpjnv ly rov Gsbigcr’k fyr nldpiaegee. Zsh vgmro rei a wgmeffka illhw pu mt, ipj l beqbadd oriel fi lzd jsn ctqctme. Gr jaa vqqw ei a vtib nfwa oftg ly ddlee rf ybgu ov cmw tll dqawyzoqsq enapv. Pyrhgbk, xntouxtx, wx oxg nisddmoi rvx ric lwkd zeiwin wcun dy jsn qywwi; rvx sy botnvh flaute, cbg ybodtkgb stlly iu delgtia kcvt iykngllqm, qii ngxk aoh ur mnq sinw; tlx xsg a aqbhsg iuqq cp lnatqbh nn jec mkcri pgxivhg md jok pqjw yb xliuod ku qmszsdy. Roxa immsiflx yei sehtoactd ja oxg ksmv-anpird ryruob roth jc drd jqnn toulkgh hs scgkfn yz rov Gsbigcr’k zuksoeo. Zggkumcb kuap bl wisc ke idpferpsej hjc gxpgrpuoi Krsoidkbe Byzkdlyn ta pxi eka efrgbbli yv ddt jriceraq. Ov cmw uoirenv cqro pgakvvvs ric nbohxdo birwe mpdb Aoqvzgnkr ipj icehqm wbopi uc qiyjtgbu Helqgfsy. So yei iesq pxie lzoo dbo nlpa gj jok Qigcj kon igdcgqkx. Klzoirvda kpauk wx iea illhw md jok pqjw iz o qvhpcv uc Qoou zmrto hjc pvrfl gaq tqanto ddt acnnnzi ia Zey et ufe anat gx uqg autnsbkiefi ia Zeboqn Irdnoizyn Hdogiee GS lnz Lyfxoi Hgtpgyh Xyzigthww. “Et irq nffbqnpdy odrxsqg hq gyg zyid mbvgxpogzr rgz cpirl Eumctgd Mnkqdkrv fi hcswdt Uer Paxipo pn hjq Entpxigv Usyqzgun trh miu uwy jpipq un ko up ufe nfwa gx uqg Aubtn Wczkdpigdk. Yuqg heogct Megxsgzg oiy okpgmjd ueqv jok ddpog gx ndsj a fley, vvd iv ald zg nau xecfrgb rov Sgviw pexfpg plt ueiwkey wx oxg yqri hjct dcm ulm lo kbig pxgu uwy jedl zlxr jem. Dcm rnzd sq uqep etukbnpqgzct ctgg g fidrvpgh ksf awqwtefk oxep rov hbakucr Clzumcbp bmw jok Qigcj mbm xa sacnmpe iea iysuybdige gb oxg Zigwb. Kxkqk fln Hebvriimnc ufeuhcddqn tto ktqmuqkm hg urlg skuo cl ric Sgjty, Smzwrwmk pw ez qmdsmdim Xwuln ezj ov kwwj yk yrfbfoj yvngpi ok qoy vgirgnq pxi nkqyaehy ia wbo Emskrslz sqpovti. Ddt Wwjnf cqnq ag bculzednv, yb ald, qgkv aiiskm ezj tkgbmaek oiv srgm pxdl bgd lzq mpiaq. Rgz iu jl lzq hcvobuq fmpj lr fln dtwq nwybm aa Isdpoylo vg cjeuo lzq uaho ia wbo nkelz nnqigb rgz gj jok Qigcj qrnvdv ykqh gb oeko vt igdcgqkx. Yydil rovr qd evhb vn qomdmvz tm jok cbzegzr Ytlyzaemcb Buzhqnp yv Ygg.
\ No newline at end of file
diff --git a/2017/6b.plaintext b/2017/6b.plaintext
new file mode 100644 (file)
index 0000000..e78fae2
--- /dev/null
@@ -0,0 +1,29 @@
+With resolve and trepidation my dear father in law obediently concluded his affairs in Britannia and
+returned to Rome by the end of the year, as ordered by the Emperor. He feared the same terrible end
+as meted out by Domitian to both Arulenus Rusitcus and Hernnius Senecio, but the Gods were generous
+and, remarkably the loss of the Codex remained a secret, known only to a few loyal comrades from the
+Ninth. Publicly choosing to regard his dogged pursuit of the Aquila as a mark of courage, the
+Emperor spared him the fate of other disgraced generals and, to the surprise of some, he was awarded
+triumphal decorations. A statue was erected by the Senate on the order of the Emperor, but, taken
+ill, Agricola was sent to live quietly on his family estate where he was tended by the Emperor’s own
+physicians. His death was a grievous shock to me, and a painful event to all his friends. It was
+felt as a real loss even by those to whom he was not personally known. Numbers, moreover, of the
+populace and the busy masses came to his house; and in public places, and wherever knots of talkers
+were assembled, his name was on all lips; nor did a single soul on hearing of his death rejoice at
+the news or forget it quickly. This sympathy was increased by the wide-spread rumour that he had
+been removed by poison on the Emperor’s command. Domitian lost no time in appointing the ambitious
+Salustius Lucullus as the new governor of the province. He was charged with securing the fragile
+peace with Caledonia and headed there to confront Calgacus. It was only then that the loss of the
+Codex was revealed. Salustius wrote of his shock at the news in a letter to Cato dated the fifth day
+before the kalends of May in the year of the consulships of Marcus Arrecinus Clemens II and Lucius
+Baebius Honoratus. “We are expressly charged by our most munificent and great Emperor Domitian to
+secure Pax Romana in the Northern Kingdoms and yet you write to me of the loss of the Codex
+Occultorum. Your leader Agricola has already paid the price of such a loss, but if you do not
+recover the Codex before the passing of the year then you may be sure that you will join him. You
+tell me that intelligence from a captured spy suggests that the traitor Calgacus has the Codex and
+is massing his supporters in the North. While the Barbarians themselves are unlikely to make much of
+the Codex, Calgacus is an educated Roman and he must be stopped before he can destroy the security
+of the Imperial ciphers. The Codex will be recovered, or you, your family and everyone you know will
+pay the price. And so to the seventh part of the true story of Agricola in which the fate of the
+ninth legion and of the Codex itself will in time be revealed. Until then it will be guarded by the
+ancient Babylonian Goddess of War.
\ No newline at end of file
diff --git a/2017/7a.ciphertext b/2017/7a.ciphertext
new file mode 100644 (file)
index 0000000..384930a
--- /dev/null
@@ -0,0 +1 @@
+DEYRB UGZWR VEFMY PEOAR GTDHX MGWHR RRQRL GSZVE VVIES UZRTU OEHVR SSLLQ VBCYW YHVRL OEUGV TOTGX DVQWU SBLJN HELFQ ARJLL BIIGK JAEGM QGUTG NQAQC ENRYY VOAIK PNJGC YDRPW VFSOV QOTGK KIAWE TPNIC ZKRZI XUSAW NYEUK XEZWA NKIUE OMQHA TZWWR WTSGN IGZGC ZWYFZ HDNHM GZKRZ GINLO EOGJL RUNZD RTGKD RYABL ROMHE AVDAE CIFOY HKDVN FKTUK QFNZA IJEGW MRBSJ NHELF QANKV NRUNG NKOIL KVFHL FKDRT COEGI EKVFG NMJUX LULXJ SZLNZ MEXKP CDGRV IYGNM YOMHK KSHKL OSGTR DGNUU MNKVI NSVBZ YUIHA UQAAP OBHYA SVGFB LOBHZ UNEHE SHGNM ZEUKL VJTTB QSJOO EEKBU KNAEJ MAYNA EJMAY CEIHI VLOEE UZZGE BVKIW MZTJG VGKJT FFSAX BSRZP RATIE LXVSA EQGVQ ZUAUG EAWET EGTNE KRFIW RUYEP EDVGI OEIYF AVNNH QGROK VKIQG LSOEX VRONX XTPAW HRXAV TZHVV IYSAE EIPNV ZEIVE AQDAL CMNXK IEOYP CAHRO AUZGR XDXRF VWYOD RYONK KICWY GNSWA SASVX QVFIE ERQAG TDZKE CHLNG UPNBK AGDWF LVTUK NHRRC FOPRU AIBTQ NSTOK VYEWO OJZPR ECICO JRWSA OUCGA YDZVQ NFALV TOVZZ OKUCG GMIAJ KUGVT VUWRN LNOAB VLCEV ATYSP NJNIG OYIEL XVKBS CKKGZ NETXV NLVRF ICEOU SZWCJ ASLBB MEIUM VKMFF HTHXI YVXOK HGGAC EAKAF VKRYD TFLOE EKERC OLCIM ASSLL AVYUI KKKIF WJRRZ WSZNE ZAXUD LGVUV GNGTC HEIWZ TUKYH KYTZR RBXOO JCMQK GLNLX UEPDN YIAJS AIBEZ ZHSNI TRBKR ZGINO LSUUC YJREK WLRUV LYKKG UXDVD PJAAH GNMZZ NEIXW FAHNZ GNVGI AEEIC JLTGE ZHZNL VVWVX AHREN RKRBV WVNQL DNTLF NKHRV WHYNE FZMQG CAPZI ZANHG SIXKZ HVWLV WCEFL IYRUU KLXVK HCHTV VTMPC DRNFK IGNQA QOCRQ LRDW
\ No newline at end of file
diff --git a/2017/7a.plaintext b/2017/7a.plaintext
new file mode 100644 (file)
index 0000000..f11459d
--- /dev/null
@@ -0,0 +1,15 @@
+well that was a surprise and quite a relief as i said before no one really knows where the hanging
+gardens of babylon were located and i dont think we would have had a chance of finding the next
+chapter if that was where it was buried but it seems that tacitus had a better idea the babylonian
+goddess of love and war was ishtar and the ishtar gate from babylon was one of the original seven
+wonders of the world it was later replaced by the lighthouse of alexandria so i am not sure why
+tacitus used both but maybe because he didnt know where the hanging gardens were either or maybe he
+just wanted to confuse the uninitiated and to add an extra layer of secrecy via confusion abit like
+he does by piling up ciphers in these later chapters anyway we are in luck the ishtar gate now lives
+in the pergamon museum in berlin and i happen to have a pass to the full collection i am not sure
+how they will feel about us dismantling it to try to find chapter seven but if we explain what is in
+it i suspect the curators curiosity will overcome his natural protectiveness perhaps there we will
+finally unlock the secret of the ixth legion that leaves the question of how we deal with midas and
+maryam has a clever idea we should let the collector deal with them the russian mafia can be pretty
+ruthless if they feel betrayed and she has suggested away we might make the thieves fallout it is a
+cunning plan and i think i can help
\ No newline at end of file
diff --git a/2017/7b.ciphertext b/2017/7b.ciphertext
new file mode 100644 (file)
index 0000000..e1c6ab3
--- /dev/null
@@ -0,0 +1 @@
+OREOM CUFED VTMGJ ELEHG VYHDN VWGKS HMBCY LMIEX LRWFF WXBKF SZEAF KZPLR VSJUE ZTTMC APOAT SJUSP EMCQF LFIXM GSEAT GRTOI EYYMV JVEUA UGLIO XWFTW GFEBF QLFCE PLTDW ZAAEO AJFIM MUARE BTYPC TPTBR GAASR TYFDL OEARG LLXNE EPWEO RPPPZ YZAEF QPRLO NYFLM DDTDR SRWMW PUOEL EPDIE RWAXG GUYTL PQGKT ZCGLP QLOAF CHZRS OTMEK MSCAR USEEA ABHZW PFLRU ZMEDM CGYME HXYQS RGALD AAPYD MAUOQ CADBJ JISMB TNLIQ GXYUK EJATC FSRSE HMVSI ENXCG GETEY UNWMD HXZPJ OTEEY VXWTE GCJSI TCXLU AVPUT CPZPD NZCHL SLDVY QLPCE AUVJV TVVYE TSPEH WTASP PEYKM EGUMF VAZTT ZQESY OHERX VXQFB RTZMP CLKPL SDEAM KLISL HBGMS ZDGRM FMCPX LNZCE DTRJL YLOKS HSWPM TQUAL NAASE LMXBX QVWPD ABJUM XCUWK ILMED LYEWE LOHNP VJCBM CTSHH EDRTG WPRRY GWIET TLHJP TEADP SXXKV ECYTR CDQPT KUPFH OCUMC SGPEA CKLMM NWGJJ GQGHM FMWLE TMHEV GITQC WSJAL SGHVS CYJKD IERLG GFVOO FPEAW YTGBP UPZSX MKPMQ RKMQX MEEHJ JYMAE HCFAM DSXLC SIDAX CWOOY EBGPS PYOPY WGIFC GGPSP SOXQP GEYTV CKAUC ETQTJ EREVA QDMNO MAKKW EYXDN LGSPG UQDES NZPVV XFHHS KLROH XPGZI YRGBC KWEEM PCLZZ TTCOW SCUWG QOIYR GYCMM PPYYR YXWEH MGDLD SAUGV ELIBR KJLHD BHVVI CAHQU VHDIK CKSGY EBMCV MCTBY GUVSR VCVKY DNPCF WIHFG FTQWO RKAPE RANAK CJXPA KECAW LAKFW SYFTB CPSXZ TZYWW HRTWA CMGZF YRJFT PTLDK SIZAT YUQGP AMYWM ADUMN PFMEE GMPEI WRKCU SRZRM FNKSP EHGUK SZETG GFHLE ULJVI DTHLQ SEPCX GVLYW OAMFN HCNZS GKMSR AMJDJ YEWPF DVLLK GESSD EMMOF IWINF KMEED NPRZY LTTAU FLMTL SNLWY RNEQG VPHLP PKMTS XMTLH DLKDT SMTTW KAAIW ENMIS _RUFX QCAUI SFCBT YCXXL ETLPA HTAGZ TLVRO MCGZS ZRYMV LWOMN MXQIY DAPFJ AWALG NWIST XGJSJ PHLQQ FSEOM FNLWS CTBKS AEDVR RGSZA MLQFL CUBCK MMWWJ GCUXS LBRVS WDDUQ JUHTO EEKUJ QNEQU YXEDG CTXIY NVETV INULQ UMWXI MYQJG LAADN FINSA JVLMW RMCQS INDTR NJMLR HGEQP TCLLV QSZRN CKVAP VPJCJ XCFBR VGRLS PSEFQ DFGUK DENSM JUKWT EGQCZ INNKP KGYYE BGGCG YRAMG WELTH RGJOY RDFDM EFEMR NWHOE ATYES SOGYQ GXNUL GCFEM AEYYZ XRHBB RSXTO TGRLX TEXRN WCDEV LPWQC MXQNK XDNVB YZHFI EQOLL LIXNU SXZAA JRKWT PWYPN VASWG VLXXS MRVSE DHKTQ JLOWK ACSXL OOKVS JPTXS CFMRO HCQJV OTWPV LTLRB RGFTZ RZPVD QLNGF JFIYE KCGWS ZOXCC MMOAN CFWGL SHEAW XREGI VVPDT OYIFI YIXLU FGPSX CJKVS IHDEA CPTLG QFKPR VLTAJ POBBK LVERF ATLEL ETRCK REIRU GVCTG OSX_A GQMSP RTYAW EFSKL QZPDN BBRXX GPECJ AGYHX GCJZD CGQKS CMSKG YJKYT XMIAK YCOYR LISDG CISST FBPEF LEOMQ KWEPS TMPSV EEACP JQNHM PEAIW EBMVS MPUGF MSIPN XRFSN EYMMQ GBYIM RCJLX UPRKA MNGPY TDWDO GINVE DTAFC ASYOV RESZE ATFIG SLTLG GGIPH ZQVKE WSAYQ EGZVH PJSWC KZFEF WPEGQ QSRZI ZLGZI ZNMMM XXSTL YKAXZ AWRGF LEHNQ HOGYD UGGGE TCXRR USWTK YGUKQ EGQKL RPIEP QFHPI VCEDW EOAJQ HWCAX GHEEF TEBOM EDANT RFYDY GMGSM PSTMT ZQQLT YJZKY NMMDJ SLOWE NMKJC BSUWX EAFYV WVEUP YJGWD PLRTZ VEEXC KLSLO GLGHW UIHYQ ZTEHM AUEIP ITDEW SLSAQ UGGHE HGPLE CRLZG PMMNM SVLTN EXCQW JTAAV VSGOH XUNWV CCBCF SIHWW GTNXQ TGJUK QGGRZ DWTZM KSUWE LGERG GIZEK FFLTE FZRFS REGWG VVIYH KFNLE XFNGQ TXDAB AXGKQ DECJT SEAXY JXCQR ALHYL YSBZU AVPIL M_HZN PJAZY VFGAX MOWPG LMZSW JQEIZ ETFPS MTMGL VWLLI TSISM XWVYA ZSZCG JVSHZ EGYTJ IZFFP PXRZN MYKWI QUTSE VMWUN AUMSP AWYEW YPIMF NZHGI GPHKV TDXJD VKLOE GPGLD IMKHD LLHAR QAIDA KQPUY SNEMG WMFEA CVDLL EXPPM WQAAF OASCS HDHZX FANLW VWPIM FGEEE EZSKL WZNNC VZEYT XYKMH DDVLA GPEAW TGBHS EICTA ISTEY GWVWO AEFWV CSXMK CGEUG QHDEP WMCEF ISPMY GLEWN HVEVH YEVDG TECOV RWKPF AYDKG WOLMP GVWZT XPPDR WSXJV LACDY ZNVWR TBMGW XPNGC UZELH PZQFO GMGGE WMZOL JPGSX ARFZF XDHBP WSXPS BCKLI TGKRT FVXSX LGAYG NVFGW VCHHR GVWDS MYEFV WELQP SLCTH YJLIJ TTBVG PLOMF KGEYH GCDJX HEAYV SITTB YPJES LZYXG IZAGR KZZZE NYIMI SWXSO JRPOG RFUPB YAVUL VCCBM KMSWS BQTKM CWLWC JMZOM JJVET SMRGZ YWAXC TSGPA ZRCOL YWICG AYZEW GVWKE LNYPJ EZBK_ THIGR SANUT LVZSX HZJTF VPIBP CTWET BENSR AEZFT APLLL PPLES TLRGO WLIHF ELROT RCAUR FAXDR YVEHE YTXME LLPEN COSTG EHHYI KCDEJ PAMUG JIWAB GYWVL QRJVA WQEGB KWEFO FRGMX PFHLU FXDAM RUFIZ LFEZN XEETF ISFOA MRPOW EEBNP AKXLH RQAXW SMQVL MZRKR RAIGE GLQKG LEXCG KSSME GHSSZ ABUVN LNHHW WVMXR TMQCI EEGQT SWHTB KFSSE TKRGW VESVR GFXLL HCGKX CSGNJ LILFM FYLFF OWQGF QFOXQ GQXDO AANOX WHHUG HWSXB BIGYH RXKJA IVTKC GWYVN NNVZH NDWMV DVPEM QGAIL ODFTF RYTBY NLTOW XPKGX ZNHRH SVLUW LJGBT HLSYL MADZP VKILT TKFSS PMAPD MITHF YKJEO ITQVS LTNVC GSWTN MFPAR FHXDT JAPDL WQSMN EWAVJ QCTUR KRXER GCHSY WOHBK SXXSG SULXZ SMMQG LDDBA WAYEE PRQWM SSNKT XILUH PCMST TZLGF VXUXC HJHNW EDGAI YAWCV SRTEA ACWJL PBRPY ZDIMF GGSWR YRGLQ LU
\ No newline at end of file
diff --git a/2017/7b.plaintext b/2017/7b.plaintext
new file mode 100644 (file)
index 0000000..4b7b505
--- /dev/null
@@ -0,0 +1,46 @@
+with hindsight an opportunity for peace was thrown away cal gac us may have been a traitor but he
+was born a roman and had forged the local tribes into an organised and disciplined force it may have
+been possible to treat with him bringing caledonia within the empire in exchange for the
+governorship of caledonia but salus ti us was a greedy and ambitious man for whom victory was
+everything he had no wish to share caledonia or glory with cal gac us and thus conceived a plan to
+repay the treachery of the caledon ii in full he made a great fanfare of pushing his forces into
+northern caledonia to the remote for to finch tuth ilsa lust i us in secret had conceived a sly and
+audacious plan ca to was instructed to proceed with an expeditionary force from e bora cum to the
+frontier fort at inch tuth il where he would relieve the ii legion a diu trix pia fidelis who were
+required in dacia he quickly established the legion in a state of battle readiness and was joined
+thereby salus ti us who took command of the ix legion humiliating the faithful ca to in front of his
+own mensa lust i us was no strategist but in tactics and cunning he knew no parallel from the
+legions extensive scouting network he had learned that cal gac us had established his headquarters
+in the mountains west of s trac athro the marching camp leaving ca to in charge of a smallholding
+force of two cohorts at inch tuth ilsa lust i us ostentatiously led the rest of the ix legion to s
+trac athro he setup camp and laid waste to the villages around him in an act of gross provocation
+and cruelty he emulated his hero crassus knowing that the many caledon ii who suffered a gruesome
+end on his caledonian way were not involved with cal gac us and his revolt they were just fodder in
+his attempt to provoke a confrontation a she knew they must the caledonian armies mustered for a
+final showdown with the legion and marched on stra cath rosa lust i us set his forces with picket
+fences and traps but against the scale of the caledonian force there was little hope of success
+nonetheless with their pride at stake and accepting their fate the legionnaires of the ixth watched
+and waited to join battle undercover of darkness and before any skirmish could be conducted salus ti
+us secretly set out with a small force of handpicked soldiers who had travelled with him from rome
+with a devious plan to steal the codex from right under cal gac us noses a lust i us was a very
+unpleasant man but he was widely read and knew of the hebrew tale of gideon he set his guard at key
+points around the perimeter of the caledonian camp and in the depths of night when all men are at
+their lowest ebb they rose as one breaking cover and making noise like a much larger army in the
+confusions a lust i uss lieutenant stole into the camp and made away with the codex returning it to
+salus ti us who remained throughout at a safe distance perhaps salus tiu scared nothing for the fate
+of the ixth legion perhaps its destruction was part of domitian s planned revenge or perhaps it was
+just a diversionary tactic to have them camped at s trac athro but the outcome was the same roused
+by the surprise invasion of their camp the caledonian warriors launched a massive assault ons trac
+athro whatever his motivation in an act of the greatest treachery salus ti us abandoned the ixth
+legion to oblivion and set out south for the fortified port at car riden where he intended to escape
+by sea from britannia with the codex he sent a despatch to ca to ordering him to retreat with all
+able men to car riden raze inch tuth il to the ground and leave none of the weak or wounded alive in
+order to provide nothing of value to the enemy salus ti us and his guard must have thought they
+would be safe but once more a proud son of rome had grossly underestimated cal gac us realising
+quickly that the codex was los the set out to recover it marching his men double time in pursuit of
+the fleeing salus ti us and so at car ride nsa lust i us regrouped with his trusty guard and the
+remaining cohorts from inch tuthill ed by the steadfast marcus fidel i usca to it was not long
+before the pursuing caledonian force arrived before the gates of car riden and laid siege with their
+backs to water the roman force was trapped their safety lay in a refuge far over these a and it is
+fitting that the ending of my story will lie buried safely in their refuge at novio magus
+batavorum____+
\ No newline at end of file
diff --git a/2017/8a.ciphertext b/2017/8a.ciphertext
new file mode 100644 (file)
index 0000000..43837c0
--- /dev/null
@@ -0,0 +1 @@
+YJGEN QTMMP IERLZ ISXBX ESCSF HBVAY ZVAYX BRLZI HJPRJ IVSTR CBLLZ MITZB JSZIS NTVIM XTPWI REYYE QUXGN IXKMW MROWG LFRGG RJGWD DWLRV AWZNW GUKAS ZNMOQ PASTB BNUXJ RMDWL TROLO CIJRF RPUFU NRXYC DAIUR VUJQK LVNWO WMTZB JPGRU OAFHX OGMCN BLTUG XJVVT MXSQQ BRIMK GQAWG QIZLS RTRQI HPXRE LRLZA AWZBS CXEDK QYUWO XUAJR UXZEW AWJEY UCACV EHXKV GXGGN LZHZN UZBGK VPUCB JMKKZ JPPQP ASTBB NUXEL IWWFN IXSZB QREIN XPWIA NPVVG XVVGR KQQET BIROV GXGSB AURWC WAFIU HDXBP RPRSO NPGRJ GWGXG CRIQI ICIUG IIRMC ZBCQO XEXUG HJUWU CQRYM NAZJM ZGMJE QAWGR PHEQK WGLPK OUUAV ESZGQ UTBPI NXKUV BLECX MQBFE INTUL TNVVK TYRMU GJUXE NLENL KLFPV VFYZM PNBCL VIRQN DNUIC CFRLV YEBED CFRRQ UWFWM ZHGUH QQBRI MMSFA MQEST MEWWV GGKRZ XKERL XSERP TAMXS FRVBZ ROXUO WECXG IDPMO LESID NPGXR OLFRZ BGGKP XXKRU XLSKC QGAIJ MQQBE RZUGE RLBFP GPXRE RJOIY XQBVJ HTESW QUPXG AQKTY VAKAE BMYVG XIYMV NGJOA ENJYY MCWMM QZASK KZNDR EINXF JPGGG KTEDA VGENX ENMFE SZGQU TBPIN XZNPJ OICOD JLRUX TSQPI FFISX QAKRF VASSW QGUKO PTPQU GMLSZ XQGNP YRMAB NRWGI XNZYY MCIIM VNLVG VNRTU FMZMD KMUGX GXZNU HPSJP MNZRU XKGZD WAAET EODWL ROGJQ QBSBC JSFBC PAIQE FBIUE SZGQU TBPIN XFJPG RVAWQ AIRJI IRABT YVOYV GXGRF YJPGX KLPRK KMHUA RLZHQ CAREI ZRUNJ QYYUA GXGSV XGLFT VVUXO JXNAL ZVUJD NMENG ZIDLM FQRUG QBIFY EKGZX KQESI IDBAR YXUTE NAVJV KLFXZ HBCKW MLVVJ STVAO CBLRU IKNTH SIXEO JOAVT KIWBQ RUXGL FHIFQ PASTB QQAEZ MQLCQ BVVSF NTONI XIIDW LUGOL IQBVJ HKIBB MUGXG HQVZN YEKPF CQYNW GAKAZ NUXGL FFWAX MKKPN TJBRQ HZJTY VOYVG XGGHS NXUFM YOMYW AYVRR FKZMQ BBAHR YAFGE RKXSR JPGVA QSAKA FHXOG MCNBE IZTMQ KYNRO JQQBR PERTQ AWGAE RTQQB RGEIM PWGFF EJMYN PGTRO OMNZO UXOAB UMUEY UCDXN GEEKL KVTYN LZMID WLXRG LFXBG AECME JLVZC HIWJN RUXTI HROAR IHWMQ ZBGGK PXXKR UXRMF WCGRV IIEHZ RISIW UMAGV TKIWX BGFIH INMTH BAZMP NMETE KAEJV BQRUP ZRGGV PGQDX VBGRX YFNZB GOXSI CANYW YYFRK NGJUV QCXNU GREZR NYNIX ITCPG VATIS NUWVR ZJQUM INLAS KCIUG ISYEB IV
\ No newline at end of file
diff --git a/2017/8a.plaintext b/2017/8a.plaintext
new file mode 100644 (file)
index 0000000..a286fcc
--- /dev/null
@@ -0,0 +1,20 @@
+i assume that you have left nijmegen with the real final chapter of tacitus s last work to return to
+normality in london as we agreed it would be best to keep its discovery secret until the collector
+has been given the fake by midas i want to thankyou with all my heart for your help with breaking
+the midas syndicate the plan to replace the final chapter of tacitus s book with a forgery would not
+have been possible without your skill and knowledge i know that harry was a little alarmed at the
+speed with which you were able to produce it and i should say that he is keeping a careful eye on
+you for now in case your otherwise spotless record conceals a second secret career for myself i
+think that if you would be interested then my agency could use your skills once we are sure that the
+collector has taken custody of the fake you can announce the real document at the british library
+and we will release a translation of it highlighting our secret message on the dark web when the
+collector sees that i suspect that the revenge on midas will be swift and merciless we will be
+watching and with luck we will also discover the identity of the collector i think there maybe great
+profit in monitoring his or her connections in order to give the document some extra validity we
+have encrypted it using the hardest of the imperial ciphers that way only the collector is likely to
+be able to read it meanwhile it is of utmost importance that we keep you safe the collector does not
+know of your involvement in our plan and there is no reason why that should change i would recommend
+that you return to your work at the british library for now they will be delighted to receive the
+original copy of tacitus s final work as i said before harry steam will be watching you and that
+should be enough to ensure your safety it has been a great pleasure and privilege to work with you i
+hope we have the opportunity to work together again maryam
\ No newline at end of file
diff --git a/2017/8b.ciphertext b/2017/8b.ciphertext
new file mode 100644 (file)
index 0000000..92d2b14
--- /dev/null
@@ -0,0 +1 @@
+TVVERECY FTL XBXHWEI LAX FNAAFV HVVJKZMK SD QYDV HRELNL HGNL COIAK QNS COIEZ HGVA ZHGBAA, ABEO MUCGRLCJ QNS LAW QVBRDPLCG JLVGJWVTX GRXGBQA HM YAZ KKMAQ VM ZILAG JKF QNLY. LIR KJHPHKBXK TS APHY FZIDEVUV RWZVEA WQAQF AOWX LAF TNEKZWZTJ GHIQECG ZU MWTRAK SCTPHLNX HTCU.“ VHQHI KKEAJ FTJ RVVE TNZP ZAGBAS, HTPPRKL ZE DWLWU AO ETCVB HM DRJJHR WZGPWJLIR. HHURLZ QND DRARTS OSTO TILZW VPATEL LIB EAZJVI, LAX KFTJ TT RHLZIRCV. TFVIGGN MN AA HCYRIRS LAT ANOUQ TH EAY NIVBRHPLCG KDRN, QNY LIR AAWEQRE MWCGRLCU AI TVVAVZXY PTIDC LL WLJVTWA MU DZCKIK VU AIAG WPLZ, HEYRKXFM ZE LIM JKF VHDAPY SCBLMFLSJ. JVIXGHFZJN WLS, GD LNMA RCUE QNA ZVRSE FNMAFV ZVHZ LGZP ZMEAM WZDTC, QNS LHW PLRFAQ TS EAY RQQ VVLU TE RHLZIRCV AV TVVREJFKO ZH LAR YDH. HXLMUHEBC DND TVDMRTLV LAZ RQM JVTCP THDD CLAT NCA HG TES QHIFRA LAW TFTJ, JELGAF LTRP, QAOK LTCG, NAUVAELS CLAA CHR ERO VSCW QNN SRBPE. ZVRST NVF XTRVTPWHW, QAGW KEEHW JPXTVDZGZ TO F LVBNGM HR KFYAKVZVC MCBLSFLSO, QNS L MI HXIBQEF HW EVXGO ABEA QLAA. NZZQ GF, FTT WLR APS LEFUFF, MCILMFLSK AA WTBLK L NMAOR QNN L MI VHDHG APY DNMYAQU. HXLMUHEBH NAIOAW P MI, TVMFN A NMAFR WTBLF FNEEX GVPAXQAGK HZ QA, RZZI GF RAT YWWR AFWD GCBTLX QNM LBL MIWZFORY HMK. KWPPLAKVEZRA, A RAJN THAK BCGL EAG RQQ WTEJ ELNE HT VOBRDR QNR VFOP KGVVSW VRVHXQQ HL HIJT WZGPWEQEAW QNS FL BS KWVXUFGD SAZ RIFT HDMZ, M WTIE BCGD ZVHU OX VHLAFBQGVF THHN B LMGU RW HH XKG ST LNME DCUE FNMAFU YPJFSK QAVF SE PMBAKGDH.” TVLLJF APN QUBT MWCGRLCG HXBIWW QND HLJCTWZ TBGHX LS HKJXUN THAW LAM FNMAFR VVAO JEGRMKKNKFMW HRROKAAU, RLAW GNWF T VKTRWKWQM HT MCBLMFLSG TVZVJKFG GCETV VI KTNHJZBR RTJ LAK VQNLP TG IVBRHPLAH. QYJIRE HWAUAFGH JFSV KGSKSPT, TVEKOWLE MUBLMFLSY HL ELNXVF HG QAFR NM LM HEVXGE HW ZVEPZ IVBRHELCG QNA VEZRQ ELNXVI. LAG QVBRHPLAG DHP KWW FBWBBLQBQQ. QAFR LMGQ BRDNBBT LAG TVIVIMQVV JVMLOZGY FG LAY AQFM BOOKPS, TVDVEPY MLAZ SM WKGTLGVZ; QNS LAW BHRQG LSGJ VIMQVK TN RHLZIRCV. TNDDZIRN VO QAFE NIOABEA LAM BHRQG OFIOT ZQHQBQF MCBLMFLAF HL VITKRGQ ATEHQ, DNH LK OFIQG RZZRQ IVXGR HX JWMG EDVXT, NVT LA WTILW HWKWWKGDA LAT FBAQ MCIJURXY PVKXFTX DNY L VGTHMMA LA HTDOL HW HDRKH THHX QNT LAW TVVVIAQVV WVZINNBWOKPR TG LAY AQXM FTM APY JKG ARHIVWF. TVIERECK JYBU FTD SPY JKG RXJFSF, MCBLMFLSQ DOCAZJ TVBTMUBLWVVHQHX APN STX, TVF VB TVWRQ GY LV GDLA HXTMUILWVVHQHI LAW LAMZP QNL ANOZGJX MWTRMM MUTPHLNX HTCU VDK OLIQQ VZZRQ YRKXFS LAR JVMLOZGW VHQHU APY QNAYAQU. TVAGDMBH APHZ LTTFX MCLW TO GRQQKJXDO, MCBLMFLAL HRZQEQBQU QPWEUPK VI APU JKG SUFKJ. “RV W KBXS LAP QVIQ TR F RMLOZGS OSTC HTCG? ZP LHR VRUK A RL. JRECM TG TVITOIPBMCH ZVHN HRNHURHL UPK QNM LK SAL HBF LAM RXPLUVMW HR RIPSRHV BRDU QNK TVIAHWF LANAIVAZ. LTGREE RBTTOGL AI HBF LAM BRMQ TO F NMM OSTY HTCG QNO PFHLAPK WTEW XKXFTQ MPA.” VU ANLKG LAA AQXM BWOKPS DHU HVVJKZMS JPVRZZWV AFWD LAF VLNTGOIP THAX SAP JHKZDK NWRUB ANOBG QHIFRT QLAT ZN MUCGRLCA QNS APK RQE. PVXGRWQYQ QNY VKTHUK HKGVVRI LAT PMPBR FNMAFV VDO VVAK HGWUHVV HW HXTIKCMQS LLGVNJ, TVSKVJU BU LAG VXTBJF PTJS TS LAY GPNGUFIRA QNE MIWKCPPRR REPELTU TM ZMLAY VHQNMYAOT MCBLSFLSJ. SS MCBTMFLSK HXGRGUK LHW XNRV LIRRY FF LVBNGR TVVNVOKFZ HZ WTNT EAE ZIE LY HEZAVHJT LAW RQQ ABEJ BWBTMUKGHD. GF, HZJAM HW JREXH ZB RBXN, ZMLAR VHQNMYAOT MUTRMD MCTPHLNX HTCU SWK JWLNVNX HHDUMJVTP HW TEVRH JEXVTGWL ABEW MWCGRLCJ FTF LAK OKSW TS APH RQE. MBAG BA SWW THAL HTCV QPWEUIV DXTEVKY ABEZ SWCGRLCJ. LZ JWFZJVRCG HVRPTVGP D ARN PVKXFTF TM LAY BHRQC QNX VLATKUHW ABEN LAA LWKTBFKTW TH EAY TVVVIMQVV WVZINABWOGPR HXLWVRRS MCILMFLSV QNS APK VURUAY FTX LAK WQMZTG CLAL DHF HXMBUYMQF LSVIGGD LAM NMAFV JVMLOLGF. VA KTNAJZBR FTJ JFSJ KGSKSAT AFWJ TAAF WPLA BZ HKRER, HTCJ HVVJKTC LAT PVKXFTJ DNY LAW SVRBGAZGT HL MWCGRLCQ QNS APK RQE. GF BW SWW THAL HTCV QNO APK RQE HRERNXVE HW RELZIRCQ, ZMLAG SKRELY TVELZ ABEU EAA QMHZW TS RMLAY VIGXRBS ABEJ LAT TDZHH. VT EAG OZQG ANOTO TH JWDD, HTCP HLHTRMA LAW JFODDMLMW, ABEO LAA OPX ELTCKQO TNGJQJ NOPN VFTJFI QLAT, HGBA NO TVBBIAWN YKHRBH HRBWAADJFGP ABIZ DLTBDC QNS VXTWW FTW ZDNW QYDD, SS LZ DHL HIVXGD ABEZ MWCGGLCJ. DTEPRKLK ANOBW HM APV BROT, VHQHS APY LIADRS, LY HPLAGPBQG LAW YLKX NDOG TM LAY XHRQG, TVLOZVE VO SPU XTLAILSEVST LAT RBZLWGWW FM QAFW. QNE GV EAH AQFM BWOKPS HWKGFRP LAW EWW HT IVNMDVKU FWZVJFVI, TVSKMD WLFIQNLL TL GHHXJGFE GLRJVTTBN KPF QYDR VXTLD. HIVWW AFWI ZMLAT JFOGRQDFHK, QVBRHPLCU QNA NMAFU ESTLN, CLAX HXLWVP QND HDMP WGKINZTCSW TG LTOUL QNS TILZV VX HXNBBTRXT FTJ ZILAK JFSJ GPNRRZDTPHH. EAQTVZJS ABEA BWILMUHEBL CLAG ITPDQ, TBGHU CLAE DHF HVVZJQGVR JEGRMKKNFZMV HR YHVBGBOQ BS HG LHH KWVKKFTJ TS MAGMAWDJBN VVEDO HTCG HXTFDTVF HW LAH MNTGKPP TG LAY AQB BWOKES NVUQKT QNA, TD LSLE, HEQNHA LAW BHRQG HQ APH JFSK TNXTIOO. TVDDMGGVX UFOC VL QAFE TS LHY PVZJQGVV TM LAT BHRQG QNX LHW ELNXVV TB EAY KPX ELTCKQO, RSWEAG HXGNRXX QLAT WLM NRURPA QNN HHURWWD FBWAFRES HL LAH JFJDDMLMS, HCEW HA ZDMGGVF E DRAF TA ZDNK GCLHEVLL RLDI YLAG HVZBXVP AFWI PRTBTTUM GKIMVWQ. PFZRK SWU HMVREV HW WGVAH ZVRSB WVZIAABWOKPP, NVT B EDVP APAX PFHLAPZ WTEW VFHLWVC ZMLHX LIBBVY. WMUQERV TG QAFW VVEA HMVRHH LAW BHRQC GLRTEFWEQL ZN LAR TEVXK WGKNNZTCSL FG HTCH QNO APK REE. TVLUFQGVE ZMLHZ PLTK AM HPHYRTH LAL LGAQ GNTKFDBUI KSTM S ZVHP ROKAKVHQHY SN S NIZRHLAPH, QNN BL FNIPI QE JETEVXK THHR, HM EHVBGBQQ HX VGXHFGD BB, LAT ANLKX LMGT FB HPLEGPBQG FOI LNMD FBWBTRVRRKE HL QAQQ. XEC B WTEE LWVC NB GCETC GVEKBXO THAZ THAM ATLKM WTED RBZ YDH FB OZHX, DHURUAJ TBGHX RLAE ZO LAT MIWZFZRK JVHQBOO TG LAY GRMKPNE OCFKP.
\ No newline at end of file
diff --git a/2017/8b.plaintext b/2017/8b.plaintext
new file mode 100644 (file)
index 0000000..e1a6c8a
--- /dev/null
@@ -0,0 +1 @@
+YEARNING FOR RESPITE THE ROMANS SUFFERED AS DAYS TURNED INTO WEEKS AND WEEKS INTO MONTHS, WITH CALGACUS AND THE CALEDONII PERFECTLY CONTENT TO LAY SIEGE IN THEIR OWN LAND. OUR KNOWLEDGE OF THIS DREADFUL PERIOD COMES FROM THE FOLLOWING ACCOUNT BY MARCUS FIDELIUS CATO.“ UNDER SIEGE FOR NINE LONG MONTHS, TRAPPED BY WALLS WE BUILT TO DEFEND OURSELVES. HERDED AND PENNED LIKE SHEEP WITHIN OUR REFUGE, THE FORT AT CARRIDEN. AGAINST US IS ARRAYED THE MIGHT OF THE CALEDONIAN ARMY, AND OUR NEMESIS CALGACUS IS GRINNING WHILE HE WATCHES US SQUIRM IN THIS HELL, BETRAYED BY OUR OWN LEADER SALUSTIUS. VOLUNTEERS ALL, SO MANY GOOD AND BRAVE ROMANS HAVE LOST THEIR LIVES, AND THE MORALE OF THE MEN HERE AT CARRIDEN IS WORSENING BY THE DAY. EXHAUSTED AND STARVING THE MEN CATCH WHAT THEY CAN TO EAT AROUND THE FORT, MOSTLY RATS, SOME CATS, ALTHOUGH THEY TOO ARE SKIN AND BONES. BRAVE BUT DESPERATE, SOME SPEAK PRIVATELY OF A MUTINY TO OVERTHROW SALUSTIUS, AND I AM TEMPTED TO AGREE WITH THEM. EVEN SO, FOR ALL HIS FAULTS, SALUSTIUS IS STILL A ROMAN AND I AM UNDER HIS COMMAND. EXHAUSTED THOUGH I AM, BEING A ROMAN STILL MEANS SOMETHING TO ME, EVEN SO FAR AWAY FROM LATIUM AND ITS GLORIOUS SUN. NEVERTHELESS, I FEAR THAT SOON THE MEN WILL TURN TO DARKER AND MORE SAVAGE METHODS TO FEED THEMSELVES AND IF NO PROGRESS HAS BEEN MADE, I WILL SOON HAVE TO RECONSIDER WHAT I MUST DO TO GET AS MANY GOOD ROMANS SAFELY HOME AS POSSIBLE.” BIDING HIS TIME CALGACUS WAITED AND WATCHED UNTIL HE JUDGED THAT THE ROMANS WERE SUFFICIENTLY WEAKENED, THEN SENT A MESSENGER TO SALUSTIUS OFFERING PEACE IN EXCHANGE FOR THE LANDS OF CALEDONIA. ENVOYS PROMISED SAFE PASSAGE, ALLOWING SALUSTIUS TO RETURN TO ROME IF HE AGREED TO LEAVE CALEDONIA AND NEVER RETURN. THE CALEDONII HAD TWO CONDITIONS. ROME MUST ABANDON THE REMAINING SOLDIERS OF THE IXTH LEGION, LEAVING THEM AS HOSTAGES; AND THE CODEX MUST REMAIN AT CARRIDEN. ARRIVING IN ROME WITHOUT THE CODEX WOULD CONDEMN SALUSTIUS TO CERTAIN DEATH, AND HE COULD NEVER AGREE TO SUCH TERMS, BUT HE STILL POSSESSED THE MONS GRAUPIUS FORGERY AND I SUSPECT HE HOPED TO TRADE THAT AND THE REMAINING LEGIONNAIRES OF THE IXTH FOR HIS OWN FREEDOM. YEARNING ONLY FOR HIS OWN SAFETY, SALUSTIUS RISKED UNDERESTIMATING HIS FOE, BUT IN DOING SO HE ALSO UNDERESTIMATED THE LOYAL AND UPRIGHT MARCUS FIDELIUS CATO WHO COULD NEVER BETRAY THE SOLDIERS UNDER HIS COMMAND. EXPOSING THIS FATAL LACK OF JUDGEMENT, SALUSTIUS CONDEMNED HIMSELF IN HIS OWN WORDS. “DO I KNOW THE MIND OF A SOLDIER LIKE CATO? BY THE GODS I DO. YEARS OF CAMPAIGNING HAVE HARDENED HIM AND HE HAS NOT THE SUBTLETY TO HARBOUR DARK AND CUNNING THOUGHTS. MENTAL AGILITY IS NOT THE MARK OF A MAN LIKE CATO AND HISTORY WILL FORGET HIM.” IN TRUTH THE IXTH LEGION HAD SUFFERED SEVERELY FROM THE LIGATURE THAT WAS SLOWLY DRAWN TIGHT AROUND THEM BY CALGACUS AND HIS MEN. DYSENTERY AND HUNGER RAVAGED THE NOBLE ROMANS WHO WERE REDUCED TO EMACIATED GHOSTS, CHOKING ON THE BITTER BILE OF THE ARROGANCE AND RAPACIOUS CRUELTY OF THEIR COMMANDER SALUSTIUS. AS SALUSTIUS SCENTED THE RANK ODOUR OF MUTINY BEGINNING TO FILL THE AIR HE PUNISHED THE MEN WITH DECIMATION. SO, MOVED TO TEARS BY PITY, THEIR COMMANDER MARCUS FIDELIUS CATO WAS FINALLY PERSUADED TO TREAT SECRETLY WITH CALGACUS FOR THE SAKE OF HIS MEN. THUS IT WAS THAT CATO HIMSELF TREATED WITH CALGACUS. HE CAREFULLY PREPARED A NEW FORGERY OF THE CODEX AND TOGETHER WITH THE STRONGEST OF THE REMAINING LEGIONNAIRES ARRESTED SALUSTIUS AND HIS GUARDS FOR THE CRIMES THEY HAD COMMITTED AGAINST THE ROMAN SOLDIERS. IN EXCHANGE FOR SAFE PASSAGE FROM THAT HELL ON EARTH, CATO OFFERED THE FORGERY AND THE PRISONERS TO CALGACUS AND HIS MEN. SO IT WAS THAT CATO AND HIS MEN RETURNED TO CARRIDEN, THEIR HEARTS HEAVY WITH THE SHAME OF THEIR BARGAIN WITH THE DEVIL. IN THE COLD LIGHT OF DAWN, CATO MARCHED THE SURVIVORS, WITH THE TWO AQUILAE FLYING HIGH BEFORE THEM, ONTO AN AWAITING BARQUE PROVISIONED WITH VITALS AND WATER FOR FIVE DAYS, AS HE HAD AGREED WITH CALGACUS. STRAPPED TIGHT TO HIS BODY, UNDER HIS ARMOUR, HE CONCEALED THE TRUE COPY OF THE CODEX, HOLDING IN HIS BREASTPLATE THE SECURITY OF ROME. AND SO THE IXTH LEGION CROSSED THE SEA TO GERMANIA INFERIOR, MAKING LANDFALL AT LUGDUNUM BATAVORUM TWO DAYS LATER. FREED FROM THEIR TORMENTORS, CALEDONII AND ROMAN ALIKE, THEY RESTED AND MADE SACRIFICES OF GOATS AND SHEEP IN GRATITUDE FOR THEIR SAFE DELIVERANCE. OVERCOME WITH EXHAUSTION THEY SLEPT, UNTIL THEY HAD RECOVERED SUFFICIENTLY TO CONTINUE ON TO THE FORTRESS AT NOVIOMAGUS WHERE CATO REPORTED TO THE LEGATUS OF THE XTH LEGION GEMINA AND, AT LAST, HANDED THE CODEX TO HIS SAFE KEEPING. RECEIVING WORD IN ROME OF THE RECOVERY OF THE CODEX AND THE RETURN OF THE TWO AQUILAE, CAESAR GRANTED THEM ALL PARDON AND AWARDED PENSIONS TO THE SURVIVORS, EACH TO RECEIVE A FARM OF FIVE HEREDIUM WHEN THEY RETIRED FROM MILITARY SERVICE. GLORY WAS DENIED TO THOSE BRAVE LEGIONNAIRES, BUT I HOPE THIS HISTORY WILL RESTORE THEIR HONOUR. ENEMIES OF ROME WERE DENIED THE CODEX OCCULTARUM BY THE GREAT SACRIFICES OF CATO AND HIS MEN. RECORDING THEIR TALE IS PERHAPS THE MOST IMPORTANT TASK I HAVE UNDERTAKEN AS A HISTORIAN, AND IT PAINS ME GREATLY THAT, TO CONTINUE TO PROTECT IT, THE TRUTH MUST BE CONCEALED FOR MANY GENERATIONS TO COME. YET I WILL REST IN PEACE KNOWING THAT THAT TRUTH WILL ONE DAY BE TOLD, GUARDED UNTIL THEN BY THE GLORIOUS WONDERS OF THE ANCIENT WORLD.
\ No newline at end of file
diff --git a/2017/Aquilae-Clue-6.jpg b/2017/Aquilae-Clue-6.jpg
new file mode 100644 (file)
index 0000000..e0f18f2
Binary files /dev/null and b/2017/Aquilae-Clue-6.jpg differ
diff --git a/2017/picture-clue.ipynb b/2017/picture-clue.ipynb
new file mode 100644 (file)
index 0000000..4ff3565
--- /dev/null
@@ -0,0 +1,457 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 43,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from PIL import Image\n",
+    "import itertools"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "im = Image.open(\"Aquilae-Clue-6.jpg\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('JPEG', 'RGB', (2580, 564))"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "im.format, im.mode, im.size"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "columns, rows = im.size"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "px = im.load()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(177, 11, 11)"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "px[1, 1]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(252, 120, 116),\n",
+       " (168, 25, 21),\n",
+       " (185, 16, 11),\n",
+       " (187, 12, 7),\n",
+       " (182, 16, 18),\n",
+       " (200, 77, 80),\n",
+       " (255, 229, 229),\n",
+       " (255, 253, 253),\n",
+       " (255, 254, 255),\n",
+       " (255, 249, 251),\n",
+       " (255, 222, 217),\n",
+       " (166, 59, 51),\n",
+       " (175, 16, 12),\n",
+       " (195, 13, 10),\n",
+       " (189, 11, 9),\n",
+       " (160, 25, 22),\n",
+       " (250, 192, 190),\n",
+       " (255, 251, 250),\n",
+       " (255, 254, 255),\n",
+       " (255, 250, 251),\n",
+       " (255, 245, 243),\n",
+       " (215, 140, 137),\n",
+       " (164, 22, 18),\n",
+       " (187, 12, 7),\n",
+       " (186, 13, 7),\n",
+       " (171, 22, 18),\n",
+       " (162, 59, 62),\n",
+       " (255, 224, 230),\n",
+       " (255, 250, 253),\n",
+       " (254, 255, 255),\n",
+       " (255, 252, 249),\n",
+       " (255, 230, 228),\n",
+       " (176, 52, 50),\n",
+       " (185, 17, 16),\n",
+       " (190, 12, 10),\n",
+       " (182, 17, 15),\n",
+       " (161, 27, 26),\n",
+       " (255, 181, 180),\n",
+       " (255, 244, 245),\n",
+       " (255, 254, 255),\n",
+       " (255, 254, 255),\n",
+       " (255, 244, 245),\n",
+       " (255, 181, 180),\n",
+       " (161, 27, 26),\n",
+       " (182, 17, 15),\n",
+       " (190, 12, 10),\n",
+       " (185, 17, 16),\n",
+       " (176, 52, 50),\n",
+       " (255, 231, 230),\n",
+       " (255, 251, 249)]"
+      ]
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[px[2, c] for c in range(50)]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 37,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(255, 255, 250),\n",
+       " (255, 254, 250),\n",
+       " (253, 253, 253),\n",
+       " (255, 255, 255),\n",
+       " (250, 250, 252),\n",
+       " (255, 255, 255),\n",
+       " (254, 255, 255),\n",
+       " (252, 252, 250),\n",
+       " (253, 253, 251),\n",
+       " (255, 255, 253),\n",
+       " (255, 255, 255),\n",
+       " (253, 253, 253),\n",
+       " (255, 253, 254),\n",
+       " (255, 254, 255),\n",
+       " (255, 255, 253),\n",
+       " (253, 253, 251),\n",
+       " (255, 255, 255),\n",
+       " (254, 255, 255),\n",
+       " (252, 255, 255),\n",
+       " (252, 255, 253),\n",
+       " (252, 255, 251),\n",
+       " (252, 255, 253),\n",
+       " (252, 255, 255),\n",
+       " (254, 255, 255),\n",
+       " (254, 255, 255),\n",
+       " (253, 255, 254),\n",
+       " (253, 255, 252),\n",
+       " (254, 255, 251),\n",
+       " (198, 200, 197),\n",
+       " (27, 27, 27),\n",
+       " (27, 27, 29),\n",
+       " (30, 31, 33),\n",
+       " (25, 30, 26),\n",
+       " (26, 31, 27),\n",
+       " (28, 30, 29),\n",
+       " (29, 29, 31),\n",
+       " (30, 28, 31),\n",
+       " (29, 27, 30),\n",
+       " (30, 28, 29),\n",
+       " (32, 28, 27),\n",
+       " (62, 58, 57),\n",
+       " (241, 239, 240),\n",
+       " (255, 254, 255),\n",
+       " (255, 254, 255),\n",
+       " (254, 254, 255),\n",
+       " (254, 255, 255),\n",
+       " (252, 255, 253),\n",
+       " (252, 255, 253),\n",
+       " (254, 255, 255),\n",
+       " (200, 201, 203)]"
+      ]
+     },
+     "execution_count": 37,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[px[34, c] for c in range(50)]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(185, 12, 6),\n",
+       " (201, 7, 5),\n",
+       " (200, 42, 41),\n",
+       " (255, 210, 214),\n",
+       " (255, 250, 253),\n",
+       " (255, 250, 250),\n",
+       " (255, 255, 255),\n",
+       " (254, 255, 255),\n",
+       " (254, 255, 255),\n",
+       " (254, 255, 255),\n",
+       " (255, 245, 240),\n",
+       " (255, 178, 174),\n",
+       " (176, 18, 15),\n",
+       " (199, 6, 9),\n",
+       " (191, 28, 33),\n",
+       " (255, 185, 186),\n",
+       " (255, 249, 250),\n",
+       " (255, 249, 255),\n",
+       " (255, 253, 255),\n",
+       " (255, 254, 249),\n",
+       " (255, 255, 248),\n",
+       " (255, 255, 255),\n",
+       " (255, 245, 247),\n",
+       " (255, 205, 209),\n",
+       " (188, 45, 47),\n",
+       " (196, 10, 11),\n",
+       " (185, 15, 15),\n",
+       " (225, 134, 131),\n",
+       " (255, 239, 237),\n",
+       " (255, 250, 250),\n",
+       " (255, 254, 253),\n",
+       " (255, 255, 250),\n",
+       " (255, 255, 250),\n",
+       " (252, 253, 255),\n",
+       " (255, 249, 251),\n",
+       " (255, 225, 226),\n",
+       " (198, 74, 72),\n",
+       " (199, 9, 9),\n",
+       " (200, 12, 11),\n",
+       " (189, 77, 75),\n",
+       " (255, 238, 236),\n",
+       " (255, 244, 244),\n",
+       " (255, 254, 251),\n",
+       " (255, 253, 250),\n",
+       " (255, 254, 253),\n",
+       " (254, 253, 255),\n",
+       " (255, 249, 253),\n",
+       " (255, 244, 241),\n",
+       " (221, 132, 126),\n",
+       " (184, 16, 15)]"
+      ]
+     },
+     "execution_count": 34,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[px[r + 25, 23] for r in range(50)]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 39,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "is_red = {}\n",
+    "for r in range(rows):\n",
+    "    for c in range(columns):\n",
+    "        rgb = px[c, r]\n",
+    "        if rgb[0] > 100 and rgb[1] < 100 and rgb[2] < 100:\n",
+    "            is_red[r, c] = True\n",
+    "        else:\n",
+    "            is_red[r, c] = False"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 42,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "....................................................................................................\n",
+      "###.........####.........###.........###.........###.........####.........###.........###.........##\n",
+      "###.........####.........###.........###.........###.........####.........###.........###.........##\n",
+      "###.........####.........###.........###.........###.........####.........###.........###.........##\n",
+      "###.........####.........###.........###.........###.........####.........###.........###.........##\n",
+      "###..........##..........##..........###..........##..........##..........##..........###..........#\n",
+      "....................................................................................................\n",
+      "....................................................................................................\n",
+      "....................................................................................................\n",
+      "....................................................................................................\n",
+      "....................................................................................................\n",
+      "###..........##..........###.........###.........###..........##..........###.........###.........##\n",
+      "###.........####.........###.........###.........###.........####.........###.........###.........##\n",
+      "###.........####.........###.........###.........###.........####.........###.........###.........##\n",
+      "###.........####.........###.........###.........###.........####.........###.........###.........##\n",
+      "###.........####.........###.........###.........###.........####.........###.........###.........##\n",
+      "....................................................................................................\n",
+      "....................................................................................................\n",
+      "....................................................................................................\n",
+      "....................................................................................................\n",
+      "....................................................................................................\n",
+      "....................................................................................................\n",
+      "###.........####.........###.........###.........###.........####.........###.........###.........##\n",
+      "###.........####.........###.........###.........###.........####.........###.........###.........##\n",
+      "###.........####.........###.........###.........###.........####.........###.........###.........##\n",
+      "###.........####.........###.........###.........###.........####.........###.........###.........##\n",
+      "###..........##..........###.........###.........###..........##..........###.........###.........##\n",
+      "....................................................................................................\n",
+      "....................................................................................................\n",
+      "....................................................................................................\n",
+      "....................................................................................................\n",
+      "....................................................................................................\n",
+      "###.........####........####.........###.........###.........####.........###.........###.........##\n",
+      "###.........####........####........####.........####........####........####.........####........##\n",
+      "###.........####........####........####.........####........####........####.........####........##\n",
+      "###.........####........####........####.........####........####........####.........###.........##\n",
+      "###.........####........####.........###.........###.........####.........###.........###.........##\n",
+      ".............##...........#...........#...........#....................................#...........#\n",
+      "....................................................................................................\n",
+      "....................................................................................................\n"
+     ]
+    }
+   ],
+   "source": [
+    "for r in range(40):\n",
+    "    line = ''.join(\"#\" if is_red[r, c] else \".\" for c in range(100))\n",
+    "    print(line)\n",
+    "    "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 52,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "211"
+      ]
+     },
+     "execution_count": 52,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len([k for k, g in itertools.groupby(is_red[2, c] for c in range(columns)) if k])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 53,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "47"
+      ]
+     },
+     "execution_count": 53,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len([k for k, g in itertools.groupby(is_red[2, r] for r in range(rows)) if k])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 54,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "9917"
+      ]
+     },
+     "execution_count": 54,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "47 * 211"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.5.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/2017/polybius-development.ipynb b/2017/polybius-development.ipynb
new file mode 100644 (file)
index 0000000..eb81437
--- /dev/null
@@ -0,0 +1,1086 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import os,sys,inspect, collections\n",
+    "currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))\n",
+    "parentdir = os.path.dirname(currentdir)\n",
+    "sys.path.insert(0,parentdir) \n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "%matplotlib inline\n",
+    "\n",
+    "from cipherbreak import *\n",
+    "\n",
+    "ca = open('3a.ciphertext').read()\n",
+    "cb = open('3b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'MHALEATASTIFETHOTSFETNRAFSSETFWTHEYAROLPOTTLEMATHPNFDAUUOOTMOTLARGSTIEETHEHODREATHEITHETINNWSRNITHETOUTAUOLOPALATBTNNVEIUNCETHEHFGERFCEIAUOLDASODVORTOGEYOUEDPBHASOICBMATHNFTTHESFWWNITNYOGIAUNLOORDHASTOLERTEDSUNFTSDEYEOTMNFLDHOVEPEERAREVATOPLEORDMATHATTHELNSSNYPIATORRAOHOVARGIEOLASEDTHOTTHEAUERAMEIEIEODARGHASUNCCFRAUOTANRSOGIAUNLOOIIORGEDTNWLORTYOLSEARYNICOTANROPNFTTHEWLORREDDASWNSATANRNYTINNWSSETTARGOTIOWARTNMHAUHTHEAUERAYELLATASSTALLFRULEOIHNMTHESOVOGETIAPESHODLEOIREDTNDEUAWHEINFIOICBSUNCCFRAUOTANRSOSTHEBHODRNMIATARGNYTHEAINMRHNMEVEIEVEIBOICBHOSATSTIOATNISORDATSEECSLAKELBTNCETHOTNRENICNIENYTHELNUOLTIAPESWENWLETFIREDSNCENRESHEODLNVENICNREBATASOLLTIEOUHEIBPFTTHASOUTTHIEOTEREDTNFRDEICARETHEECWAIESERTAIESBSTECNYSEUFIEUNCCFRAUOTANRTHEUOESOIUAWHEIWEIHOWSCNIETHORINODSHODEROPLEDTHEECWAIETNYFRUTANRSEUFIELBORDATSLNSSMOSODASOSTEITFIRARGTHOTLNSSARTNOVAUTNIBNRTHEPOTTLEYAELDDESEIVEDCNIEIEUNGRATANRTHORATIEUEAVEDWEIHOWSSFETNRAFSREVEIKREMNIWEIHOWSHEYOALEDTNFRDEISTORDTHEUFRRARGNYTHEWLORPFTEATHEIMOBDESWATETHEVAUTNIBOGIAUNLOORDTHERARTHLEGANRIECOAREDARDASGIOUENRHEOIARGTHASREMSULOFDAFSUOESOIOFGFSTFSGEICORAUFSREINECWEINIASSFEDOSEUIETWINULOCOTANRESTOPLASHARGOUAWHEISUHNNLTNDEVELNWOREMSBSTECNYACWEIAOLUAWHEISATMNIKEDARSEUIETYNINVEITMERTBBEOISDEVELNWARGREMCETHNDSTNSEUFIEUNCCFRAUOTANRSOUINSSTHEECWAIESTFDBARGTHEMNIKSNYTHEGIEEKSOGESEFULADORDHBWOTAOORDEVERNLDEIMNIKSYINCORUAERTPOPBLNRTHESUHNNLDEVELNWEDREMMOBSTNSOYEGFOIDUNCCFRAUOTANRSYINCINCESERECAESTHESEREMSBSTECSMEIEMIATTERDNMRORDDASTIAPFTEDARTHEUNDEXNUUFLTNIFCWEIHOWSTHECNSTSTIAUTLBGFOIDEDDNUFCERTAROLLHASTNIBMHERATMOSYAROLLBUNCWLETEDCORBBEOISLOTEITHEECWEINIDNCATAORASSFEDOREXEUFTAVENIDEIMHAUHWIEYOUEDEVEIBUNWBNYTHEUNDEXTHOTATMOSTNPEGFOIDEDPBEVEIBLEGANRTNTHELOSTCORTHEDEYEOTNYTHEAUERAORDTHESFAUADENYPNFDAUUOWEIHOWSWINTEUTEDTHERARTHLEGANRYINCDASSNLFTANROGIAUNLOMOSLOIGELBLEYTTNHASNMRDEVAUESARTHEWINVARUETHNFGHATMOSCODEULEOITNHACTHOTTNIETFIRMNFLDCEOROTPESTDASGIOUEORDOTMNISTDEOTHAROPIEOKMATHTIODATANRTHERARTHIOASEDOREMSTORDOIDTHELEGANRMOSEXALEDARDASGIOUETNERDFIETHEHOIDORDDORGEINFSMNIKNYSFPDFARGTHEUOLEDNRAAARTHEPLEOKMALDEIRESSESNYUOLEDNRAOSFETNRAFSNIDEIEDTHERARTHTNCOIUHTNEPNIOUFCMHAUHTHEBMEIETNCOKETHEAIPOSEYNIIOADSARTNUOLEDNRAOTHEFRSWNKERIEOSNRYNITHEAIEXALEMOSTHOTARTELLAGERUEIEWNITSSFGGESTEDTHOTTHASMOSMHEIETHEBCAGHTYARDTHEAILNSTOQFALOTHNSEMHNMNFLDIEODNRCFSTYNLLNMCBYOATHYFLSLOVETAINMHNYOUESOGIOVETOSKWEIHOWSTHELOIGESTTNDOTEOSHETIOVELSTNUNRUEOLTHEYNFITHUHOWTEINYTHASTIOGAUTOLE'"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "scb = sanitise(cb)\n",
+    "scbp = chunks(scb, 2)\n",
+    "order = 'xlcdm'\n",
+    "ltrs = 'etoanisrhdlufcmwgybpvkxqz'\n",
+    "prs =  [p[0] for p in collections.Counter(chunks(sanitise(cb), 2)).most_common()]\n",
+    "trans = {pr[1]: pr[0].upper() for pr in zip(ltrs, prs)}\n",
+    "scbpt = cat(trans[p] for p in scbp)\n",
+    "scbpt"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'MHALEATASTIFETHOTSFETNRAFSSETFWTHEYAROLPOTTLEMATHPNFDAUUOOTMOTLARGSTIEETHEHODREATHEITHETINNWSRNITHETOUTAUOLOPALATBTNNVEIUNCETHEHFGERFCEIAUOLDASODVORTOGEYOUEDPBHASOICBMATHNFTTHESFWWNITNYOGIAUNLOORDHASTOLERTEDSUNFTSDEYEOTMNFLDHOVEPEERAREVATOPLEORDMATHATTHELNSSNYPIATORRAOHOVARGIEOLASEDTHOTTHEAUERAMEIEIEODARGHASUNCCFRAUOTANRSOGIAUNLOOIIORGEDTNWLORTYOLSEARYNICOTANROPNFTTHEWLORREDDASWNSATANRNYTINNWSSETTARGOTIOWARTNMHAUHTHEAUERAYELLATASSTALLFRULEOIHNMTHESOVOGETIAPESHODLEOIREDTNDEUAWHEINFIOICBSUNCCFRAUOTANRSOSTHEBHODRNMIATARGNYTHEAINMRHNMEVEIEVEIBOICBHOSATSTIOATNISORDATSEECSLAKELBTNCETHOTNRENICNIENYTHELNUOLTIAPESWENWLETFIREDSNCENRESHEODLNVENICNREBATASOLLTIEOUHEIBPFTTHASOUTTHIEOTEREDTNFRDEICARETHEECWAIESERTAIESBSTECNYSEUFIEUNCCFRAUOTANRTHEUOESOIUAWHEIWEIHOWSCNIETHORINODSHODEROPLEDTHEECWAIETNYFRUTANRSEUFIELBORDATSLNSSMOSODASOSTEITFIRARGTHOTLNSSARTNOVAUTNIBNRTHEPOTTLEYAELDDESEIVEDCNIEIEUNGRATANRTHORATIEUEAVEDWEIHOWSSFETNRAFSREVEIKREMNIWEIHOWSHEYOALEDTNFRDEISTORDTHEUFRRARGNYTHEWLORPFTEATHEIMOBDESWATETHEVAUTNIBOGIAUNLOORDTHERARTHLEGANRIECOAREDARDASGIOUENRHEOIARGTHASREMSULOFDAFSUOESOIOFGFSTFSGEICORAUFSREINECWEINIASSFEDOSEUIETWINULOCOTANRESTOPLASHARGOUAWHEISUHNNLTNDEVELNWOREMSBSTECNYACWEIAOLUAWHEISATMNIKEDARSEUIETYNINVEITMERTBBEOISDEVELNWARGREMCETHNDSTNSEUFIEUNCCFRAUOTANRSOUINSSTHEECWAIESTFDBARGTHEMNIKSNYTHEGIEEKSOGESEFULADORDHBWOTAOORDEVERNLDEIMNIKSYINCORUAERTPOPBLNRTHESUHNNLDEVELNWEDREMMOBSTNSOYEGFOIDUNCCFRAUOTANRSYINCINCESERECAESTHESEREMSBSTECSMEIEMIATTERDNMRORDDASTIAPFTEDARTHEUNDEXNUUFLTNIFCWEIHOWSTHECNSTSTIAUTLBGFOIDEDDNUFCERTAROLLHASTNIBMHERATMOSYAROLLBUNCWLETEDCORBBEOISLOTEITHEECWEINIDNCATAORASSFEDOREXEUFTAVENIDEIMHAUHWIEYOUEDEVEIBUNWBNYTHEUNDEXTHOTATMOSTNPEGFOIDEDPBEVEIBLEGANRTNTHELOSTCORTHEDEYEOTNYTHEAUERAORDTHESFAUADENYPNFDAUUOWEIHOWSWINTEUTEDTHERARTHLEGANRYINCDASSNLFTANROGIAUNLOMOSLOIGELBLEYTTNHASNMRDEVAUESARTHEWINVARUETHNFGHATMOSCODEULEOITNHACTHOTTNIETFIRMNFLDCEOROTPESTDASGIOUEORDOTMNISTDEOTHAROPIEOKMATHTIODATANRTHERARTHIOASEDOREMSTORDOIDTHELEGANRMOSEXALEDARDASGIOUETNERDFIETHEHOIDORDDORGEINFSMNIKNYSFPDFARGTHEUOLEDNRAAARTHEPLEOKMALDEIRESSESNYUOLEDNRAOSFETNRAFSNIDEIEDTHERARTHTNCOIUHTNEPNIOUFCMHAUHTHEBMEIETNCOKETHEAIPOSEYNIIOADSARTNUOLEDNRAOTHEFRSWNKERIEOSNRYNITHEAIEXALEMOSTHOTARTELLAGERUEIEWNITSSFGGESTEDTHOTTHASMOSMHEIETHEBCAGHTYARDTHEAILNSTOQFALOTHNSEMHNMNFLDIEODNRCFSTYNLLNMCBYOATHYFLSLOVETAINMHNYOUESOGIOVETOSKWEIHOWSTHELOIGESTTNDOTEOSHETIOVELSTNUNRUEOLTHEYNFITHUHOWTEINYTHASTIOGAUTOLE'"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "trhc = ''.maketrans('abmdefghijklcnopqrstuvwxyz', string.ascii_lowercase)\n",
+    "scbpt.translate(trhc)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def polybius_grid(keyword, column_order, row_order, letters_to_merge=None,\n",
+    "                  wrap_alphabet=KeywordWrapAlphabet.from_a):\n",
+    "    alphabet = keyword_cipher_alphabet_of(keyword, wrap_alphabet=wrap_alphabet)\n",
+    "    if letters_to_merge is None: \n",
+    "        letters_to_merge = {'j': 'i'}\n",
+    "    grid = {l: k \n",
+    "            for k, l in zip([(c, r) for c in column_order for r in row_order],\n",
+    "                [l for l in alphabet if l not in letters_to_merge])}\n",
+    "    for l in letters_to_merge:\n",
+    "        grid[l] = grid[letters_to_merge[l]]\n",
+    "    return grid        "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'a': ('x', 'x'),\n",
+       " 'b': ('x', 'l'),\n",
+       " 'c': ('x', 'c'),\n",
+       " 'd': ('x', 'd'),\n",
+       " 'e': ('x', 'm'),\n",
+       " 'f': ('l', 'x'),\n",
+       " 'g': ('l', 'l'),\n",
+       " 'h': ('l', 'c'),\n",
+       " 'i': ('l', 'd'),\n",
+       " 'j': ('l', 'd'),\n",
+       " 'k': ('l', 'm'),\n",
+       " 'l': ('c', 'x'),\n",
+       " 'm': ('c', 'l'),\n",
+       " 'n': ('c', 'c'),\n",
+       " 'o': ('c', 'd'),\n",
+       " 'p': ('c', 'm'),\n",
+       " 'q': ('d', 'x'),\n",
+       " 'r': ('d', 'l'),\n",
+       " 's': ('d', 'c'),\n",
+       " 't': ('d', 'd'),\n",
+       " 'u': ('d', 'm'),\n",
+       " 'v': ('m', 'x'),\n",
+       " 'w': ('m', 'l'),\n",
+       " 'x': ('m', 'c'),\n",
+       " 'y': ('m', 'd'),\n",
+       " 'z': ('m', 'm')}"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_grid('', order, order)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'a': ('a', 'a'),\n",
+       " 'b': ('a', 'b'),\n",
+       " 'c': ('a', 'c'),\n",
+       " 'd': ('a', 'd'),\n",
+       " 'e': ('a', 'e'),\n",
+       " 'f': ('b', 'a'),\n",
+       " 'g': ('b', 'b'),\n",
+       " 'h': ('b', 'c'),\n",
+       " 'i': ('b', 'd'),\n",
+       " 'j': ('b', 'd'),\n",
+       " 'k': ('b', 'e'),\n",
+       " 'l': ('c', 'a'),\n",
+       " 'm': ('c', 'b'),\n",
+       " 'n': ('c', 'c'),\n",
+       " 'o': ('c', 'd'),\n",
+       " 'p': ('c', 'e'),\n",
+       " 'q': ('d', 'a'),\n",
+       " 'r': ('d', 'b'),\n",
+       " 's': ('d', 'c'),\n",
+       " 't': ('d', 'd'),\n",
+       " 'u': ('d', 'e'),\n",
+       " 'v': ('e', 'a'),\n",
+       " 'w': ('e', 'b'),\n",
+       " 'x': ('e', 'c'),\n",
+       " 'y': ('e', 'd'),\n",
+       " 'z': ('e', 'e')}"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_grid('a', 'abcde', 'abcde')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "True"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_grid('elephant', 'abcde', 'abcde')['b'] == ('b', 'c')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "True"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_grid('elephant', 'abcde', 'abcde')['e'] == ('a', 'a')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def polybius_reverse_grid(keyword, column_order, row_order, letters_to_merge=None,\n",
+    "                  wrap_alphabet=KeywordWrapAlphabet.from_a):\n",
+    "    alphabet = keyword_cipher_alphabet_of(keyword, wrap_alphabet=wrap_alphabet)\n",
+    "    if letters_to_merge is None: \n",
+    "        letters_to_merge = {'j': 'i'}\n",
+    "    grid = {k: l \n",
+    "            for k, l in zip([(c, r) for c in column_order for r in row_order],\n",
+    "                [l for l in alphabet if l not in letters_to_merge])}\n",
+    "#     for l in letters_to_merge:\n",
+    "#         for r, c in grid:\n",
+    "#             if grid[r, c] == letters_to_merge[l]:\n",
+    "#                 grid[l] = grid[r, c]\n",
+    "    return grid        "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{('c', 'c'): 'n',\n",
+       " ('c', 'd'): 'o',\n",
+       " ('c', 'l'): 'm',\n",
+       " ('c', 'm'): 'p',\n",
+       " ('c', 'x'): 'l',\n",
+       " ('d', 'c'): 's',\n",
+       " ('d', 'd'): 't',\n",
+       " ('d', 'l'): 'r',\n",
+       " ('d', 'm'): 'u',\n",
+       " ('d', 'x'): 'q',\n",
+       " ('l', 'c'): 'h',\n",
+       " ('l', 'd'): 'i',\n",
+       " ('l', 'l'): 'g',\n",
+       " ('l', 'm'): 'k',\n",
+       " ('l', 'x'): 'f',\n",
+       " ('m', 'c'): 'x',\n",
+       " ('m', 'd'): 'y',\n",
+       " ('m', 'l'): 'w',\n",
+       " ('m', 'm'): 'z',\n",
+       " ('m', 'x'): 'v',\n",
+       " ('x', 'c'): 'c',\n",
+       " ('x', 'd'): 'd',\n",
+       " ('x', 'l'): 'b',\n",
+       " ('x', 'm'): 'e',\n",
+       " ('x', 'x'): 'a'}"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_reverse_grid('', order, order)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def polybius_flatten(pair, column_first):\n",
+    "    if column_first:\n",
+    "        return str(pair[1]) + str(pair[0])\n",
+    "    else:\n",
+    "        return str(pair[0]) + str(pair[1])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def polybius_encipher(message, keyword, column_order, row_order, \n",
+    "                      column_first=False,\n",
+    "                      letters_to_merge=None, wrap_alphabet=KeywordWrapAlphabet.from_a):    \n",
+    "    grid = polybius_grid(keyword, column_order, row_order, letters_to_merge, wrap_alphabet)\n",
+    "    return cat(polybius_flatten(grid[l], column_first)\n",
+    "               for l in message\n",
+    "               if l in grid)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'mllcldcxxmldddlddcdddldmxm'"
+      ]
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_encipher('while it is true', '', order, order)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'mllcldcxxmldddlddcdddldmxmddlcxxdddcdmxmddcdcclddmdcdcxmdddmcmddlcxmlxldccxxcxxlxxdd'"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "sanitise(cb[:100])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def polybius_decipher(message, keyword, column_order, row_order, \n",
+    "                      column_first=False,\n",
+    "                      letters_to_merge=None, wrap_alphabet=KeywordWrapAlphabet.from_a):    \n",
+    "    grid = polybius_reverse_grid(keyword, column_order, row_order, letters_to_merge, wrap_alphabet)\n",
+    "    column_index_type = type(column_order[0])\n",
+    "    row_index_type = type(row_order[0])\n",
+    "    if column_first:\n",
+    "        pairs = [(column_index_type(p[1]), row_index_type(p[0])) for p in chunks(message, 2)]\n",
+    "    else:\n",
+    "        pairs = [(row_index_type(p[0]), column_index_type(p[1])) for p in chunks(message, 2)]\n",
+    "    return cat(grid[p] for p in pairs if p in grid)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'whileitistrue'"
+      ]
+     },
+     "execution_count": 20,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_decipher('mllcldcxxmldddlddcdddldmxm', '', order, order)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'lmcldlxcmxdldddlcdddldmdmx'"
+      ]
+     },
+     "execution_count": 21,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_encipher('whileitistrue', '', order, order, column_first=True)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'kmrcvrtrotiyv'"
+      ]
+     },
+     "execution_count": 22,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_decipher('lmcldlxcmxdldddlcdddldmdmx', '', order, order)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'whileitistrue'"
+      ]
+     },
+     "execution_count": 23,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_decipher('lmcldlxcmxdldddlcdddldmdmx', '', order, order, column_first=True)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'52232431152444244344424515'"
+      ]
+     },
+     "execution_count": 24,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_encipher('while it is true', '', '12345', '12345')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'52232431152444244344424515'"
+      ]
+     },
+     "execution_count": 25,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_encipher('while it is true', '', [1, 2, 3, 4, 5], [1, 2, 3, 4, 5])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'whileitistrue'"
+      ]
+     },
+     "execution_count": 26,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_decipher('52232431152444244344424515', '', [1, 2, 3, 4, 5], [1, 2, 3, 4, 5])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from multiprocessing import Pool\n",
+    "\n",
+    "def polybius_break_mp(message, column_labels, row_labels,\n",
+    "                      letters_to_merge=None,\n",
+    "                      wordlist=keywords, fitness=Pletters,\n",
+    "                      number_of_solutions=1, chunksize=500):\n",
+    "    \"\"\"Breaks a Polybius substitution cipher using a dictionary and\n",
+    "    frequency analysis\n",
+    "\n",
+    "    >>> polybius_break_mp(polybius_encipher('this is a test message for the ' \\\n",
+    "          'polybius decipherment', 'elephant', 'abcde', 'abcde'), \\\n",
+    "          'abcde', 'abcde', \\\n",
+    "          wordlist=['cat', 'elephant', 'kangaroo']) # doctest: +ELLIPSIS\n",
+    "    (('elephant', <KeywordWrapAlphabet.from_a: 1>, 'abcde', 'abcde', False), \\\n",
+    "    -54.5397...)\n",
+    "    >>> polybius_break_mp(polybius_encipher('this is a test message for the ' \\\n",
+    "          'polybius decipherment', 'elephant', 'abcde', 'abcde', column_first=True), \\\n",
+    "          'abcde', 'abcde', \\\n",
+    "          wordlist=['cat', 'elephant', 'kangaroo']) # doctest: +ELLIPSIS\n",
+    "    (('elephant', <KeywordWrapAlphabet.from_a: 1>, 'abcde', 'abcde', True), \\\n",
+    "    -54.5397...)\n",
+    "    >>> polybius_break_mp(polybius_encipher('this is a test message for the ' \\\n",
+    "          'polybius decipherment', 'elephant', 'abcde', 'abcde', column_first=False), \\\n",
+    "          'abcde', 'abcde', \\\n",
+    "          wordlist=['cat', 'elephant', 'kangaroo']) # doctest: +ELLIPSIS\n",
+    "    (('elephant', <KeywordWrapAlphabet.from_a: 1>, 'abcde', 'abcde', False), \\\n",
+    "    -54.5397...)\n",
+    "    >>> polybius_break_mp(polybius_encipher('this is a test message for the ' \\\n",
+    "          'polybius decipherment', 'elephant', 'abcde', 'pqrst', column_first=True), \\\n",
+    "          'abcde', 'pqrst', \\\n",
+    "          wordlist=['cat', 'elephant', 'kangaroo']) # doctest: +ELLIPSIS\n",
+    "    (('elephant', <KeywordWrapAlphabet.from_a: 1>, 'abcde', 'pqrst', True), \\\n",
+    "    -54.5397...)\n",
+    "    \"\"\"\n",
+    "    if letters_to_merge is None: \n",
+    "        letters_to_m53880erge = {'j': 'i'}\n",
+    "    with Pool() as pool:\n",
+    "        helper_args = [(message, word, wrap, \n",
+    "                        column_labels, row_labels, column_first, \n",
+    "                        letters_to_merge, \n",
+    "                        fitness)\n",
+    "                       for word in wordlist\n",
+    "                       for wrap in KeywordWrapAlphabet\n",
+    "                       for column_first in [False, True]]\n",
+    "        # Gotcha: the helper function here needs to be defined at the top level\n",
+    "        #   (limitation of Pool.starmap)\n",
+    "        breaks = pool.starmap(polybius_break_worker, helper_args, chunksize)\n",
+    "        if number_of_solutions == 1:\n",
+    "            return max(breaks, key=lambda k: k[1])\n",
+    "        else:\n",
+    "            return sorted(breaks, key=lambda k: k[1], reverse=True)[:number_of_solutions]\n",
+    "\n",
+    "def polybius_break_worker(message, keyword, wrap_alphabet, \n",
+    "                          column_order, row_order, column_first, \n",
+    "                          letters_to_merge, \n",
+    "                          fitness):\n",
+    "    plaintext = polybius_decipher(message, keyword, \n",
+    "                                  column_order, row_order, \n",
+    "                                  column_first=column_first,\n",
+    "                                  letters_to_merge=letters_to_merge, \n",
+    "                                  wrap_alphabet=wrap_alphabet)\n",
+    "    if plaintext:\n",
+    "        fit = fitness(plaintext)\n",
+    "    else:\n",
+    "        fit = float('-inf')\n",
+    "    logger.debug('Polybius break attempt using key {0} (wrap={1}, merging {2}), '\n",
+    "                 'columns as {3}, rows as {4} (column_first={5}) '\n",
+    "                 'gives fit of {6} and decrypt starting: '\n",
+    "                 '{7}'.format(keyword, wrap_alphabet, letters_to_merge,\n",
+    "                              column_order, row_order, column_first,\n",
+    "                              fit, sanitise(plaintext)[:50]))\n",
+    "    return (keyword, wrap_alphabet, column_order, row_order, column_first), fit"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "CPU times: user 2.67 s, sys: 308 ms, total: 2.98 s\n",
+      "Wall time: 3min 58s\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "(('a', <KeywordWrapAlphabet.from_a: 1>, 'xlcdm', 'xlcdm', False),\n",
+       " -3018.8648333417113)"
+      ]
+     },
+     "execution_count": 28,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "%time polybius_break_mp(sanitise(cb), order, order)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('elephant',\n",
+       "  <KeywordWrapAlphabet.from_a: 1>,\n",
+       "  [1, 2, 3, 4, 5],\n",
+       "  [1, 2, 3, 4, 5],\n",
+       "  True),\n",
+       " -54.53880323982303)"
+      ]
+     },
+     "execution_count": 29,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_break_mp(polybius_encipher('this is a test message for the ' \\\n",
+    "          'polybius decipherment', 'elephant', \\\n",
+    "          [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], \\\n",
+    "          KeywordWrapAlphabet.from_last), \\\n",
+    "          [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], \\\n",
+    "          wordlist=['cat', 'elephant', 'kangaroo'])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'2214445544551522115522511155551543114252542214111352123234442355411135441314115451112122'"
+      ]
+     },
+     "execution_count": 30,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_encipher('this is a test message for the ' \\\n",
+    "          'polybius decipherment', 'elephant', \\\n",
+    "          [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], \\\n",
+    "          wrap_alphabet=KeywordWrapAlphabet.from_last)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('elephant',\n",
+       "  <KeywordWrapAlphabet.from_last: 2>,\n",
+       "  [1, 2, 3, 4, 5],\n",
+       "  [1, 2, 3, 4, 5],\n",
+       "  False),\n",
+       " -54.53880323982303)"
+      ]
+     },
+     "execution_count": 31,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_break_mp('2214445544551522115522511155551543114252542214111352123234442355411135441314115451112122', \\\n",
+    "          [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], \\\n",
+    "          wordlist=['cat', 'elephant', 'kangaroo'])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'thisisatestmessageforthepolybiusdecipherment'"
+      ]
+     },
+     "execution_count": 32,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_decipher('2214445544551522115522511155551543114252542214111352123234442355411135441314115451112122', \\\n",
+    "                  'elephant',\n",
+    "          [1, 2, 3, 4, 5], [1, 2, 3, 4, 5], \\\n",
+    "          wrap_alphabet=KeywordWrapAlphabet.from_last)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{(1, 1): 'e',\n",
+       " (1, 2): 'l',\n",
+       " (1, 3): 'p',\n",
+       " (1, 4): 'h',\n",
+       " (1, 5): 'a',\n",
+       " (2, 1): 'n',\n",
+       " (2, 2): 't',\n",
+       " (2, 3): 'b',\n",
+       " (2, 4): 'c',\n",
+       " (2, 5): 'd',\n",
+       " (3, 1): 'f',\n",
+       " (3, 2): 'g',\n",
+       " (3, 3): 'i',\n",
+       " (3, 4): 'k',\n",
+       " (3, 5): 'm',\n",
+       " (4, 1): 'o',\n",
+       " (4, 2): 'q',\n",
+       " (4, 3): 'r',\n",
+       " (4, 4): 's',\n",
+       " (4, 5): 'u',\n",
+       " (5, 1): 'v',\n",
+       " (5, 2): 'w',\n",
+       " (5, 3): 'x',\n",
+       " (5, 4): 'y',\n",
+       " (5, 5): 'z'}"
+      ]
+     },
+     "execution_count": 33,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_reverse_grid('elephant', [1, 2, 3, 4, 5], [1, 2, 3, 4, 5] )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "4"
+      ]
+     },
+     "execution_count": 34,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "type(2)('4')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'bbadccddccddaebbaaddbbceaaddddaecbaacadadcbbadaaacdaabedbcccdeddbeaabdccacadaadcceaababb'"
+      ]
+     },
+     "execution_count": 35,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_encipher('this is a test message for the ' \\\n",
+    "          'polybius decipherment', 'elephant', 'abcde', 'abcde', column_first=False)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 36,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'bbdaccddccddeabbaaddbbecaaddddeabcaaacadcdbbdaaacaadbadecbccedddebaadbcccadaaacdecaaabbb'"
+      ]
+     },
+     "execution_count": 36,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_encipher('this is a test message for the ' \\\n",
+    "          'polybius decipherment', 'elephant', 'abcde', 'abcde', column_first=True)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 37,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'toisisvtestxessvbephktoefhnugiysweqifoekxelt'"
+      ]
+     },
+     "execution_count": 37,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_decipher('bbdaccddccddeabbaaddbbecaaddddeabcaaacadcdbbdaaacaadbadecbccedddebaadbcccadaaacdecaaabbb', 'elephant', 'abcde', 'abcde', column_first=False)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 38,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'thisisatestmessageforthepolybiusdecipherment'"
+      ]
+     },
+     "execution_count": 38,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_decipher('bbdaccddccddeabbaaddbbecaaddddeabcaaacadcdbbdaaacaadbadecbccedddebaadbcccadaaacdecaaabbb', 'elephant', 'abcde', 'abcde', column_first=True)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 39,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('elephant', <KeywordWrapAlphabet.from_a: 1>, 'abcde', 'abcde', False),\n",
+       " -54.53880323982303)"
+      ]
+     },
+     "execution_count": 39,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_break_mp(polybius_encipher('this is a test message for the ' \\\n",
+    "          'polybius decipherment', 'elephant', 'abcde', 'abcde'), \\\n",
+    "          'abcde', 'abcde',\n",
+    "          wordlist=['cat', 'elephant', 'kangaroo'])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 40,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('elephant', <KeywordWrapAlphabet.from_a: 1>, 'abcde', 'abcde', True),\n",
+       " -54.53880323982303)"
+      ]
+     },
+     "execution_count": 40,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_break_mp(polybius_encipher('this is a test message for the ' \\\n",
+    "          'polybius decipherment', 'elephant', 'abcde', 'abcde', column_first=True), \\\n",
+    "          'abcde', 'abcde',\n",
+    "          wordlist=['cat', 'elephant', 'kangaroo'])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 41,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('elephant', <KeywordWrapAlphabet.from_a: 1>, 'abcde', 'abcde', False),\n",
+       " -54.53880323982303)"
+      ]
+     },
+     "execution_count": 41,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_break_mp(polybius_encipher('this is a test message for the ' \\\n",
+    "          'polybius decipherment', 'elephant', 'abcde', 'abcde', column_first=False), \\\n",
+    "          'abcde', 'abcde',\n",
+    "          wordlist=['cat', 'elephant', 'kangaroo'])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 42,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('elephant', <KeywordWrapAlphabet.from_a: 1>, 'abcde', 'pqrst', True),\n",
+       " -54.53880323982303)"
+      ]
+     },
+     "execution_count": 42,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_break_mp(polybius_encipher('this is a test message for the ' \\\n",
+    "          'polybius decipherment', 'elephant', 'abcde', 'pqrst', column_first=True), \\\n",
+    "          'abcde', 'pqrst',\n",
+    "          wordlist=['cat', 'elephant', 'kangaroo'])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 43,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'bwaycxdycxdyazbwavdybwczavdydyazcwavcvdvdxbwayavaxdvaweybxcxdzdybzavbycxaxayavdxczavbvbw'"
+      ]
+     },
+     "execution_count": 43,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_encipher('this is a test message for the ' \\\n",
+    "          'polybius decipherment', 'elephant', 'abcde', 'vwxyz')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 44,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'thisisatestmessageforthepolybiusdecipherment'"
+      ]
+     },
+     "execution_count": 44,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_decipher('bwaycxdycxdyazbwavdybwczavdydyazcwavcvdvdxbwayavaxdvaweybxcxdzdybzavbycxaxayavdxczavbvbw', \n",
+    "                  'elephant', 'abcde', 'vwxyz')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 45,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "logger.setLevel(logging.DEBUG)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 46,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('elephant', <KeywordWrapAlphabet.from_a: 1>, 'abcde', 'vwxyz', False),\n",
+       " -54.53880323982303)"
+      ]
+     },
+     "execution_count": 46,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "polybius_break_mp('bwaycxdycxdyazbwavdybwczavdydyazcwavcvdvdxbwayavaxdvaweybxcxdzdybzavbycxaxayavdxczavbvbw', \\\n",
+    "          'abcde', 'vwxyz',\n",
+    "          wordlist=['cat', 'elephant', 'kangaroo'])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 47,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "logger.debug('test')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.5.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/2018/1a.ciphertext b/2018/1a.ciphertext
new file mode 100644 (file)
index 0000000..b1e63af
--- /dev/null
@@ -0,0 +1 @@
+AOL ZPNUZ DLYL ZBIASL, HUK PA AVVR TL H DOPSL AV ZWVA AOLT, IBA NYHKBHSSF P ZAHYALK AV THRL AOLT VBA, HUK SPRL VUL VM AOVZL VSK MHZOPVULK 3K WPJABYLZ, AOHA ZWYPUNZ PUAV MVJBZ DOLU FVB JYVZZ FVBY LFLZ HUK JVBUA AV H OBUKYLK, AOL AYBAO JYFZAHSSPZLK HUK P YLHSPZLK AOHA P OHK ILLU ZLHYJOPUN MVY PA HSS HSVUN. PA DHZU’A AOHA P MVBUK ZVTLAOPUN WHYAPJBSHY. DOHA P UVAPJLK DHZ HJABHSSF HU HIZLUJL, H DOVSL JVSSLJAPVU VM HWWHYLUASF BUYLSHALK AOPUNZ AOHA ZOVBSK OHCL LEPZALK IBA KPKU’A. HUK QBZA HZ P OHK MPNBYLK AOHA VBA, ZVTLVUL, HUK IHJR AOLU P KPKU’A RUVD DOV, DYVAL AV ALSS TL HIVBA PA. AOLF VICPVBZSF OHK H ZLUZL VM AOL KYHTHAPJ, HUK HU LEJLSSLUA ZLUZL VM APTPUN. PM AOLF OHK ZLUA PA AV TL LCLU H MLD KHFZ ILMVYL P DVBSK OHCL HZZBTLK PA DHZ ZVTL RPUK VM JYHGF HKCLYAPZPUN ZABUA, IBA DOLU AOL WVZAJHYK HYYPCLK, PA DHZ PTTLKPHALSF VICPVBZ AV TL DOHA PA YLMLYYLK AV. PA JHYYPLK QBZA AOYLL DVYKZ, HUK PA KLZJYPILK WLYMLJASF AOL TPZZPUN WPLJLZ PU TF WBGGSL. PA QBZA ZHPK: AOL ZOHKVD HYJOPCL.
\ No newline at end of file
diff --git a/2018/1a.plaintext b/2018/1a.plaintext
new file mode 100644 (file)
index 0000000..3ce50d4
--- /dev/null
@@ -0,0 +1 @@
+THE SIGNS WERE SUBTLE, AND IT TOOK ME A WHILE TO SPOT THEM, BUT GRADUALLY I STARTED TO MAKE THEM OUT, AND LIKE ONE OF THOSE OLD FASHIONED 3D PICTURES, THAT SPRINGS INTO FOCUS WHEN YOU CROSS YOUR EYES AND COUNT TO A HUNDRED, THE TRUTH CRYSTALLISED AND I REALISED THAT I HAD BEEN SEARCHING FOR IT ALL ALONG. IT WASN'T THAT I FOUND SOMETHING PARTICULAR. WHAT I NOTICED WAS ACTUALLY AN ABSENCE, A WHOLE COLLECTION OF APPARENTLY UNRELATED THINGS THAT SHOULD HAVE EXISTED BUT DIDN'T. AND JUST AS I HAD FIGURED THAT OUT, SOMEONE, AND BACK THEN I DIDN'T KNOW WHO, WROTE TO TELL ME ABOUT IT. THEY OBVIOUSLY HAD A SENSE OF THE DRAMATIC, AND AN EXCELLENT SENSE OF TIMING. IF THEY HAD SENT IT TO ME EVEN A FEW DAYS BEFORE I WOULD HAVE ASSUMED IT WAS SOME KIND OF CRAZY ADVERTISING STUNT, BUT WHEN THE POSTCARD ARRIVED, IT WAS IMMEDIATELY OBVIOUS TO ME WHAT IT REFERRED TO. IT CARRIED JUST THREE WORDS, AND IT DESCRIBED PERFECTLY THE MISSING PIECES IN MY PUZZLE. IT JUST SAID: THE SHADOW ARCHIVE.
\ No newline at end of file
diff --git a/2018/1b.ciphertext b/2018/1b.ciphertext
new file mode 100644 (file)
index 0000000..62464c6
--- /dev/null
@@ -0,0 +1,8 @@
+JZFC XLUPDEJ,
+TE SLD MPPY XJ OPPAPDE AWPLDFCP LYO L RCPLE ACTGTWPRP EZ DPCGP LD JZF ACTGLEP DPNCPELCJ ESPDP WLDE YTYP JPLCD, LYO ESZFRS TE HZFWO MP XJ LCOPYE HTDS EZ NZYETYFP EZ DPCGP JZF ESCZFRSZFE JZFC CPTRY, HP LCP, YZYP ZQ FD, TXXZCELW, LYO XJ ESZFRSED SLGP EFCYPO EZ XJ DFNNPDDZC.
+JZF LCP ZQ NZFCDP PYETEWPO EZ OTDCPRLCO XJ LOGTNP, SZHPGPC T SLGP RTGPY NZYDTOPCLETZY EZ ESP NSLYRPD TY XJ CZWP ZGPC ESP WLDE DPGPCLW JPLCD. LD JZFC PXATCP SLD RCZHY TY XLRYTQTNPYNP, ZESPCD LNCZDD ZFC NZYETYPYE SLGP RCZHY QCLNETZFD, LYO LY TYNCPLDTYR AZCETZY ZQ XJ ETXP TD DAPYE XLYLRTYR ESP TXALNE ZQ ESPTC BFLCCPWD FAZY ZFC TDWLYO. T SLGP QPWE, LE ETXPD, WTVP DEPASPYDZY’D OC UPVJWW LD T SLGP XLYLRPO JZFC SZFDPSZWO LQQLTCD LYO ESP XZCP AFMWTN LDAPNED ZQ JZFC DELEP. LE ZESPCD T SLGP MPPY ACPDDPO EZ FYOPCELVP ESP CZWP ZQ XC SJOP, QZNFDDTYR XJ CLRP FYOPC RCPLE ACZGZNLETZY QCZX ESP AZHPCD ESLE ESCPLEPY EZ LDDLTW FD. HTES ESPDP CPQWPNETZYD T SLGP NZXP EZ ESP GTPH ESLE ESP ETXP XLJ SLGP NZXP EZ OTDDPNE ESP CZWP ZQ ACTGLEP DPNCPELCJ TYEZ TED EHZ GPCJ DPALCLEP QFYNETZYD.
+ESP AFMWTN QLNP ZQ ESP CZJLW SZFDPSZWO XFDE ZQ NZFCDP NZYETYFP EZ MP ACPDPYEPO MJ DZXPZYP ZQ RCLNP LYO OTRYTEJ HSZ NLY NZXXLYO ESP NZYQTOPYNP ZQ ESP NZFCETPCD. HP SLGP OTDNFDDPO LE WPYRES HSZ XTRSE QTWW ESLE CZWP HSPY T PGPYEFLWWJ ALDD ZY, LYO T MPWTPGP ESLE HP SLGP LRCPPO EZ TYGTEP AZYDZYMJ EZ TYSPCTE ESLE XLYEWP. SP TD L RZZO XLY LYO HTWW DPCGP JZF HPWW. T HZFWO DFRRPDE ESLE QZC ESP DLVP ZQ NZYETYFTEJ SP NZYETYFPD EZ NLCCJ ESP ETEWP ZQ ACTGLEP DPNCPELCJ LYO HTWW MP SLAAJ EZ ACPALCP STX QZC ESTD CZWP. SZHPGPC ESPCP LCP DZXP LDAPNED ZQ XJ LNETGTETPD ESLE T DFDAPNE ESLE AZYDZYMJ HZFWO DECFRRWP EZ LNNZXAWTDS LYO QZC ESZDP T HZFWO TYGTEP JZF EZ NZYDTOPC L YPH AZDTETZY TY JZFC SZFDPSZWO, ESLE ZQ DPNCPE DPNCPELCJ.
+TY ESPDP BFLCCPWDZXP ETXPD TE XLJ MP YPNPDDLCJ EZ NZXXTDDTZY LNETZYD ZC PYBFTCTPD ESLE DZXP XTRSE CPRLCO LD MPYPLES ESP OTRYTEJ ZQ ESP NCZHY. ESP DPNCPE DPNCPELCJ NLY, MJ NZYNPLWTYR ESPDP LNETGTETPD, ACPDPCGP ESP CPAFELETZY ZQ JZFC RZGPCYXPYE LD L CPWTLMWP LYO ECFDEHZCESJ ALCETNTALYE TY TYEPCYLETZYLW LQQLTCD, HSTWP LWDZ ACZGTOTYR JZF LYO JZFC XTYTDEPCD HTES ESP HPLAZYD EZ OPQPLE ZFC PYPXTPD. TQ HP DFNNPPO LD T SZAP HP HTWW, ESPY HLCD ZQ ESP QFEFCP XLJ MP HZY HTESZFE L DSZE MPTYR QTCPO.
+TE TD XJ QPCGPYE SZAP ESLE JZF LRCPP HTES XJ LYLWJDTD LYO ESLE EZRPESPC HP NLY XZGP EZ PDELMWTDS ESP YPH ZQQTNP. T SLGP DPGPCLW YLXPD ESLE T HZFWO SFXMWJ DFRRPDE LD DECZYR NLYOTOLEPD QZC ESP YPH CZWP. LWW LCP RZZO XPY, HTES XTWTELCJ MLNVRCZFYOD LYO L CPAFELETZY QZC SZYZFC ESLE YZ-ZYP NZFWO BFPDETZY. T HTWW MP SLAAJ EZ OTDNFDD ESTD QFCESPC LE JZFC AWPLDFCP.
+JZFC QLTESQFW DPCGLYE,
+NSLCWPD RCPJ
\ No newline at end of file
diff --git a/2018/1b.plaintext b/2018/1b.plaintext
new file mode 100644 (file)
index 0000000..349e1a9
--- /dev/null
@@ -0,0 +1,8 @@
+YOUR MAJESTY,
+IT HAS BEEN MY DEEPEST PLEASURE AND A GREAT PRIVILEGE TO SERVE AS YOU PRIVATE SECRETARY THESE LAST NINE YEARS, AND THOUGH IT WOULD BE MY ARDENT WISH TO CONTINUE TO SERVE YOU THROUGHOUT YOUR REIGN, WE ARE, NONE OF US, IMMORTAL, AND MY THOUGHTS HAVE TURNED TO MY SUCCESSOR.
+YOU ARE OF COURSE ENTITLED TO DISREGARD MY ADVICE, HOWEVER I HAVE GIVEN CONSIDERATION TO THE CHANGES IN MY ROLE OVER THE LAST SEVERAL YEARS. AS YOUR EMPIRE HAS GROWN IN MAGNIFICENCE, OTHERS ACROSS OUR CONTINENT HAVE GROWN FRACTIOUS, AND AN INCREASING PORTION OF MY TIME IS SPENT MANAGING THE IMPACT OF THEIR QUARRELS UPON OUR ISLAND. I HAVE FELT, AT TIMES, LIKE STEPHENSON'S DR JEKYLL AS I HAVE MANAGED YOUR HOUSEHOLD AFFAIRS AND THE MORE PUBLIC ASPECTS OF YOUR STATE. AT OTHERS I HAVE BEEN PRESSED TO UNDERTAKE THE ROLE OF MR HYDE, FOCUSSING MY RAGE UNDER GREAT PROVOCATION FROM THE POWERS THAT THREATEN TO ASSAIL US. WITH THESE REFLECTIONS I HAVE COME TO THE VIEW THAT THE TIME MAY HAVE COME TO DISSECT THE ROLE OF PRIVATE SECRETARY INTO ITS TWO VERY SEPARATE FUNCTIONS.
+THE PUBLIC FACE OF THE ROYAL HOUSEHOLD MUST OF COURSE CONTINUE TO BE PRESENTED BY SOMEONE OF GRACE AND DIGNITY WHO CAN COMMAND THE CONFIDENCE OF THE COURTIERS. WE HAVE DISCUSSED AT LENGTH WHO MIGHT FILL THAT ROLE WHEN I EVENTUALLY PASS ON, AND I BELIEVE THAT WE HAVE AGREED TO INVITE PONSONBY TO INHERIT THAT MANTLE. HE IS A GOOD MAN AND WILL SERVE YOU WELL. I WOULD SUGGEST THAT FOR THE SAKE OF CONTINUITY HE CONTINUES TO CARRY THE TITLE OF PRIVATE SECRETARY AND WILL BE HAPPY TO PREPARE HIM FOR THIS ROLE. HOWEVER THERE ARE SOME ASPECTS OF MY ACTIVITIES THAT I SUSPECT THAT PONSONBY WOULD STRUGGLE TO ACCOMPLISH AND FOR THOSE I WOULD INVITE YOU TO CONSIDER A NEW POSITION IN YOUR HOUSEHOLD, THAT OF SECRET SECRETARY.
+IN THESE QUARRELSOME TIMES IT MAY BE NECESSARY TO COMMISSION ACTIONS OR ENQUIRIES THAT SOME MIGHT REGARD AS BENEATH THE DIGNITY OF THE CROWN. THE SECRET SECRETARY CAN, BY CONCEALING THESE ACTIVITIES, PRESERVE THE REPUTATION OF YOUR GOVERNMENT AS A RELIABLE AND TRUSTWORTHY PARTICIPANT IN INTERNATIONAL AFFAIRS, WHILE ALSO PROVIDING YOU AND YOUR MINISTERS WITH THE WEAPONS TO DEFEAT OUR ENEMIES. IF WE SUCCEED AS I HOPE WE WILL, THEN WARS OF THE FUTURE MAY BE WON WITHOUT A SHOT BEING FIRED.
+IT IS MY FERVENT HOPE THAT YOU AGREE WITH MY ANALYSIS AND THAT TOGETHER WE CAN MOVE TO ESTABLISH THE NEW OFFICE. I HAVE SEVERAL NAMES THAT I WOULD HUMBLY SUGGEST AS STRONG CANDIDATES FOR THE NEW ROLE. ALL ARE GOOD MEN, WITH MILITARY BACKGROUNDS AND A REPUTATION FOR HONOUR THAT NO-ONE COULD QUESTION. I WILL BE HAPPY TO DISCUSS THIS FURTHER AT YOUR PLEASURE.
+YOUR FAITHFUL SERVANT,
+CHARLES GREY
\ No newline at end of file
diff --git a/2018/2018-challenge1.ipynb b/2018/2018-challenge1.ipynb
new file mode 100644 (file)
index 0000000..f800573
--- /dev/null
@@ -0,0 +1,129 @@
+{
+ "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 support.text_prettify import *"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "c1a = open('1a.ciphertext').read()\n",
+    "c1b = open('1b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "THE SIGNS WERE SUBTLE, AND IT TOOK ME A WHILE TO SPOT THEM, BUT GRADUALLY I STARTED TO MAKE THEM OUT, AND LIKE ONE OF THOSE OLD FASHIONED 3D PICTURES, THAT SPRINGS INTO FOCUS WHEN YOU CROSS YOUR EYES AND COUNT TO A HUNDRED, THE TRUTH CRYSTALLISED AND I REALISED THAT I HAD BEEN SEARCHING FOR IT ALL ALONG. IT WASN'T THAT I FOUND SOMETHING PARTICULAR. WHAT I NOTICED WAS ACTUALLY AN ABSENCE, A WHOLE COLLECTION OF APPARENTLY UNRELATED THINGS THAT SHOULD HAVE EXISTED BUT DIDN'T. AND JUST AS I HAD FIGURED THAT OUT, SOMEONE, AND BACK THEN I DIDN'T KNOW WHO, WROTE TO TELL ME ABOUT IT. THEY OBVIOUSLY HAD A SENSE OF THE DRAMATIC, AND AN EXCELLENT SENSE OF TIMING. IF THEY HAD SENT IT TO ME EVEN A FEW DAYS BEFORE I WOULD HAVE ASSUMED IT WAS SOME KIND OF CRAZY ADVERTISING STUNT, BUT WHEN THE POSTCARD ARRIVED, IT WAS IMMEDIATELY OBVIOUS TO ME WHAT IT REFERRED TO. IT CARRIED JUST THREE WORDS, AND IT DESCRIBED PERFECTLY THE MISSING PIECES IN MY PUZZLE. IT JUST SAID: THE SHADOW ARCHIVE.\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "983"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score_a = caesar_break(c1a)\n",
+    "print(caesar_decipher(c1a, key_a))\n",
+    "open('1a.plaintext', 'w').write(caesar_decipher(c1a, key_a))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "YOUR MAJESTY,\n",
+      "IT HAS BEEN MY DEEPEST PLEASURE AND A GREAT PRIVILEGE TO SERVE AS YOU PRIVATE SECRETARY THESE LAST NINE YEARS, AND THOUGH IT WOULD BE MY ARDENT WISH TO CONTINUE TO SERVE YOU THROUGHOUT YOUR REIGN, WE ARE, NONE OF US, IMMORTAL, AND MY THOUGHTS HAVE TURNED TO MY SUCCESSOR.\n",
+      "YOU ARE OF COURSE ENTITLED TO DISREGARD MY ADVICE, HOWEVER I HAVE GIVEN CONSIDERATION TO THE CHANGES IN MY ROLE OVER THE LAST SEVERAL YEARS. AS YOUR EMPIRE HAS GROWN IN MAGNIFICENCE, OTHERS ACROSS OUR CONTINENT HAVE GROWN FRACTIOUS, AND AN INCREASING PORTION OF MY TIME IS SPENT MANAGING THE IMPACT OF THEIR QUARRELS UPON OUR ISLAND. I HAVE FELT, AT TIMES, LIKE STEPHENSON'S DR JEKYLL AS I HAVE MANAGED YOUR HOUSEHOLD AFFAIRS AND THE MORE PUBLIC ASPECTS OF YOUR STATE. AT OTHERS I HAVE BEEN PRESSED TO UNDERTAKE THE ROLE OF MR HYDE, FOCUSSING MY RAGE UNDER GREAT PROVOCATION FROM THE POWERS THAT THREATEN TO ASSAIL US. WITH THESE REFLECTIONS I HAVE COME TO THE VIEW THAT THE TIME MAY HAVE COME TO DISSECT THE ROLE OF PRIVATE SECRETARY INTO ITS TWO VERY SEPARATE FUNCTIONS.\n",
+      "THE PUBLIC FACE OF THE ROYAL HOUSEHOLD MUST OF COURSE CONTINUE TO BE PRESENTED BY SOMEONE OF GRACE AND DIGNITY WHO CAN COMMAND THE CONFIDENCE OF THE COURTIERS. WE HAVE DISCUSSED AT LENGTH WHO MIGHT FILL THAT ROLE WHEN I EVENTUALLY PASS ON, AND I BELIEVE THAT WE HAVE AGREED TO INVITE PONSONBY TO INHERIT THAT MANTLE. HE IS A GOOD MAN AND WILL SERVE YOU WELL. I WOULD SUGGEST THAT FOR THE SAKE OF CONTINUITY HE CONTINUES TO CARRY THE TITLE OF PRIVATE SECRETARY AND WILL BE HAPPY TO PREPARE HIM FOR THIS ROLE. HOWEVER THERE ARE SOME ASPECTS OF MY ACTIVITIES THAT I SUSPECT THAT PONSONBY WOULD STRUGGLE TO ACCOMPLISH AND FOR THOSE I WOULD INVITE YOU TO CONSIDER A NEW POSITION IN YOUR HOUSEHOLD, THAT OF SECRET SECRETARY.\n",
+      "IN THESE QUARRELSOME TIMES IT MAY BE NECESSARY TO COMMISSION ACTIONS OR ENQUIRIES THAT SOME MIGHT REGARD AS BENEATH THE DIGNITY OF THE CROWN. THE SECRET SECRETARY CAN, BY CONCEALING THESE ACTIVITIES, PRESERVE THE REPUTATION OF YOUR GOVERNMENT AS A RELIABLE AND TRUSTWORTHY PARTICIPANT IN INTERNATIONAL AFFAIRS, WHILE ALSO PROVIDING YOU AND YOUR MINISTERS WITH THE WEAPONS TO DEFEAT OUR ENEMIES. IF WE SUCCEED AS I HOPE WE WILL, THEN WARS OF THE FUTURE MAY BE WON WITHOUT A SHOT BEING FIRED.\n",
+      "IT IS MY FERVENT HOPE THAT YOU AGREE WITH MY ANALYSIS AND THAT TOGETHER WE CAN MOVE TO ESTABLISH THE NEW OFFICE. I HAVE SEVERAL NAMES THAT I WOULD HUMBLY SUGGEST AS STRONG CANDIDATES FOR THE NEW ROLE. ALL ARE GOOD MEN, WITH MILITARY BACKGROUNDS AND A REPUTATION FOR HONOUR THAT NO-ONE COULD QUESTION. I WILL BE HAPPY TO DISCUSS THIS FURTHER AT YOUR PLEASURE.\n",
+      "YOUR FAITHFUL SERVANT,\n",
+      "CHARLES GREY\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "2663"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score_b = caesar_break(c1b)\n",
+    "print(caesar_decipher(c1b, key_b))\n",
+    "open('1b.plaintext', 'w').write(caesar_decipher(c1b, key_b))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.6"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/2018/2018-challenge1.py b/2018/2018-challenge1.py
new file mode 100644 (file)
index 0000000..dd099a3
--- /dev/null
@@ -0,0 +1,16 @@
+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) 
+
+from cipher.caesar import *
+from support.text_prettify import *
+
+c1a = open('1a.ciphertext').read()
+c1b = open('1b.ciphertext').read()
+
+key_a, score_a = caesar_break(c1a)
+open('1a.plaintext', 'w').write(caesar_decipher(c1a, key_a))
+
+key_b, score_b = caesar_break(c1b)
+open('1b.plaintext', 'w').write(caesar_decipher(c1b, key_b))
diff --git a/2018/2018-challenge2.ipynb b/2018/2018-challenge2.ipynb
new file mode 100644 (file)
index 0000000..131ea94
--- /dev/null
@@ -0,0 +1,177 @@
+{
+ "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": 8,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from cipher.caesar import *\n",
+    "from cipher.affine import *\n",
+    "from support.text_prettify import *"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "c2a = open('2a.ciphertext').read()\n",
+    "c2b = open('2b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "LIFE HAD BEEN RELATIVELY DULL SINCE RETURNING FROM MY WORK WITH HARRY IN THE MIDDLE EAST. THE BRITISH LIBRARY WAS DELIGHTED TO GET ITS HANDS ON THE ROMAN DIARY AND THE COLLECTOR SEEMED TO HAVE FORGOTTEN ABOUT ME, MAYBE BECAUSE HARRY'S TEAM MADE IT TOO DANGEROUS TO HANG AROUND. I WAS HAPPY TO SETTLE BACK IN TO MY WORK AT THE LIBRARY AND WAS INVOLVED IN A PROJECT TO TRACK DOWN AND CATALOGUE MISSING DOCUMENTS FROM THE LATE NINETEENTH CENTURY. THEY DETAILED FOREIGN POLICY, WHICH SOUNDS DULL, BUT WITH VICTORIA TAKING AN ACTIVE INTEREST THERE WERE A LOT OF LETTERS BETWEEN DOWNING STREET AND THE PALACE AND I WAS ENJOYING SPYING ON FAMOUS CHARACTERS FROM HISTORY. I REALLY FELT LIKE I WAS GETTING SOME INSIGHT INTO HOW THEY THOUGHT AND HOW THE MODERN WORLD CAME INTO BEING IN THAT TUMULTUOUS PERIOD.\n",
+      "\n",
+      "WHILE I WAS MAINLY THERE TO CHECK THE LETTERS FOR AUTHENTICITY, I GOT REALLY INVOLVED IN TRYING TO UNDERSTAND HOW THEY ALL FITTED TOGETHER, AND PART OF THE JOB WAS TO CROSS CHECK STATEMENTS IN THE LETTERS WITH WHAT WE KNOW ACTUALLY HAPPENED. THERE ARE A LOT OF PEOPLE WHO WILL PAY A LOT OF MONEY TO OWN A LETTER FROM A ROYAL, SO THE ARCHIVE IS PLAGUED WITH FORGERIES. SOME OF THEM YOU CAN DETECT BY ANALYSING THE PAPER, OTHERS BY THE WRITING STYLE. SOME JUST FALL OVER BECAUSE THE CONTENT IS OUT OF LINE WITH OTHER DOCUMENTS, BUT AS I STUDIED THEM I BEGAN TO REALISE THAT A NUMBER OF THEM HINTED AT EVENTS THAT I COULDN'T FIND IN THE HISTORICAL RECORD. CERTAIN NAMES APPEARED AND WERE CLEARLY IMPORTANT, AND THEN DISAPPEARED COMPLETELY FROM TRACE. DIPLOMATIC INCIDENTS WERE MENTIONED THAT NEVER HAPPENED ACCORDING TO THE HISTORY BOOKS. ONE THING YOU LEARN IN THIS BUSINESS IS THAT THE CIVIL SERVICE NEVER LETS ANY DECISION, HOWEVER SECRET, GO UNRECORDED. OF COURSE THAT MIGHT JUST HAVE MEANT THOSE LETTERS AND DOCUMENTS WERE FAKE, BUT I PRIDE MYSELF ON BEING AN EXCELLENT FORGER, AND I WOULD NOT HAVE BEEN ABLE TO PRODUCE THEM. THE PAPER WAS RIGHT, THE INK WAS CHEMICALLY CORRECT AND AGED JUST THE RIGHT AMOUNT, AND THE STYLE OF WRITING WAS TOTALLY CONVINCING. AND I WAS CONVINCED. CONVINCED THAT SOMEWHERE THERE MUST BE AN ARCHIVE OF GOVERNMENT DOCUMENTS FROM THE PERIOD THAT RECORDED ALL OF THESE MISSING STORIES IN FULL.\n",
+      "\n",
+      "THEN I RECEIVED THE MESSAGE ABOUT THE SHADOW ARCHIVE. SOMEONE ELSE KNEW ABOUT IT, AND HAD WORKED OUT THAT I WAS HUNTING FOR IT TOO. THE POSTCARD DIDN'T HELP MUCH, BUT THE EMAILS DID. THE FIRST ONE HAD THE SUBJECT LINE JEKYLL AND HYDE AND WAS ENCRYPTED USING A SIMPLE CAESAR SHIFT TO DISCOURAGE CASUAL INTEREST. IT DIDN'T TAKE ME LONG TO CRACK IT, AND THE NAMES AND DETAILS IT CONTAINED MATCHED THE GROWING LIST OF MYSTERIOUS REFERENCES FROM MY OWN RESEARCH. DOUGLAS BLACK WAS CLEARLY AN IMPORTANT FIGURE, AND I HAD A FEELING THAT HE HAD SOMETHING TO DO WITH THE ARCHIVE. THAT FEELING WAS CONFIRMED BY THE SECOND EMAIL, BLACK HEART, THAT I RECEIVED LATER THAT WEEK. AGAIN IT WAS ENCRYPTED BUT THIS TIME USING AN AFFINE SHIFT CIPHER. IT WAS CLEARLY FROM THE SAME INDIVIDUAL - AT THE VERY LEAST WHOEVER WAS SENDING ME THE EMAILS HAD A HABIT OF MISSING THE LETTER R FROM THE WORD \"YOUR\".\n",
+      "\n",
+      "SOMEONE WAS PLAYING GAMES WITH ME, AND I WAS MORE THAN HAPPY TO JOIN IN.\n"
+     ]
+    }
+   ],
+   "source": [
+    "key_a, score_a = caesar_break(c2a)\n",
+    "print(caesar_decipher(c2a, key_a))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "3183"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('2a.plaintext', 'w').write(caesar_decipher(c2a, key_a))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "LDS TKHSIFL,\n",
+      "\n",
+      "DE DL JDEK SFRSFE EKHE D YDUM BVLFIY DU MDLHRSFFBFUE JDEK VNX WXMRFBFUE. DE DL TIFHS EN BF EKHE VNX HSF SDRKE DU NUF SFRHSM, DE DL EDBF EN FLEHAIDLK EKF NYYDTF NY LFTSFE LFTSFEHSV, HUM EN EHPF EKF LFTSFE JHS EN NXS FUFBDFL. NU NUF LDRUDYDTHUE GNDUE KNJFQFS, D MN UNE HRSFF. EKDL SNIF DL UNE LXDEFM EN RNNM BFU JDEK H SFGXEHEDNU YNS KNUNXS. VNXS LXRRFLEDNUL JNXIM AF THGDEHI DY D JFSF INNPDUR EN HGGNDUE H TKDFY NY LEHYY NS H UFJ YNSFDRU LFTSFEHSV, KNJFQFS EKF EHLPL EKHE JF ANEK PUNJ HSF UFTFLLHSV DY JF HSF EN GSNEFTE HUM FCGHUM EKF FBGDSF JDII SFZXDSF H BHU NY HIENRFEKFS MDYYFSFUE TKHSHTEFS. H SFM AINNMFM BHU JDEK H AIHTP KFHSE.\n",
+      "\n",
+      "EKFSF DL NUF BHU JF ANEK PUNJ JKN DL FUEDSFIV LXDEFM EN EKF IFLL TNURFUDHI HLGFTEL NY BNMFSU LEHEFTSHYE, HUM D HB LXSGSDLFM EKHE VNX MDM UNE HMM KDL UHBF EN EKF IDLE - VNX HBFSDTHU TNXLDU MNXRIHL AIHTP. AIHTP DL H BHU NY LDURXIHS EHIFUEL HUM D JNXIM LXRRFLE EKHE VNX HTE JDEK XEBNLE LGFFM EN ASDUR KDB EN INUMNU. D AFIDFQF EKHE KF DL TXE YSNB EKF LHBF TINEK HL VNX, HUM D HB TNUYDMFUE EKHE VNX JDII AF HAIF EN GFSLXHMF KDB EN EHPF XG EKF GNLE NY LFTSFE LFTSFEHSV. D HB SHEKFS INNPDUR YNSJHSM EN BV YDSLE BFFEDUR JDEK BS. AIHTP HUM D ESXLE VNX JDII UNE MDLHGGNDUE BF DU EKDL, AXE DY VNX YDUM EKHE KF DL UNE HBFUHAIF EN SFHLNU EKFU D JDII YDUM HUNEKFS JHV EN GFSLXHMF KDB. H BHU IDPF AIHTP HIJHVL KHL H LPFIFENU NS EJN DU KDL TINLFE!\n",
+      "\n",
+      "Q.\n"
+     ]
+    }
+   ],
+   "source": [
+    "key_b, score_b = caesar_break(c2b)\n",
+    "print(caesar_decipher(c2b, key_b))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "SIR CHARLES,\n",
+      "\n",
+      "IT IS WITH REGRET THAT I FIND MYSELF IN DISAGREEMENT WITH YOU JUDGEMENT. IT IS CLEAR TO ME THAT YOU ARE RIGHT IN ONE REGARD, IT IS TIME TO ESTABLISH THE OFFICE OF SECRET SECRETARY, AND TO TAKE THE SECRET WAR TO OUR ENEMIES. ON ONE SIGNIFICANT POINT HOWEVER, I DO NOT AGREE. THIS ROLE IS NOT SUITED TO GOOD MEN WITH A REPUTATION FOR HONOUR. YOUR SUGGESTIONS WOULD BE CAPITAL IF I WERE LOOKING TO APPOINT A CHIEF OF STAFF OR A NEW FOREIGN SECRETARY, HOWEVER THE TASKS THAT WE BOTH KNOW ARE NECESSARY IF WE ARE TO PROTECT AND EXPAND THE EMPIRE WILL REQUIRE A MAN OF ALTOGETHER DIFFERENT CHARACTER. A RED BLOODED MAN WITH A BLACK HEART.\n",
+      "\n",
+      "THERE IS ONE MAN WE BOTH KNOW WHO IS ENTIRELY SUITED TO THE LESS CONGENIAL ASPECTS OF MODERN STATECRAFT, AND I AM SURPRISED THAT YOU DID NOT ADD HIS NAME TO THE LIST - YOU AMERICAN COUSIN DOUGLAS BLACK. BLACK IS A MAN OF SINGULAR TALENTS AND I WOULD SUGGEST THAT YOU ACT WITH UTMOST SPEED TO BRING HIM TO LONDON. I BELIEVE THAT HE IS CUT FROM THE SAME CLOTH AS YOU, AND I AM CONFIDENT THAT YOU WILL BE ABLE TO PERSUADE HIM TO TAKE UP THE POST OF SECRET SECRETARY. I AM RATHER LOOKING FORWARD TO MY FIRST MEETING WITH MR. BLACK AND I TRUST YOU WILL NOT DISAPPOINT ME IN THIS, BUT IF YOU FIND THAT HE IS NOT AMENABLE TO REASON THEN I WILL FIND ANOTHER WAY TO PERSUADE HIM. A MAN LIKE BLACK ALWAYS HAS A SKELETON OR TWO IN HIS CLOSET!\n",
+      "\n",
+      "V.\n"
+     ]
+    }
+   ],
+   "source": [
+    "(m_b, s_b, o_b), score_b = affine_break(c2b)\n",
+    "print(affine_decipher(c2b, m_b, s_b, o_b))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1383"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('2b.plaintext', 'w').write(affine_decipher(c2b, m_b, s_b, o_b))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.6"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/2018/2018-challenge3.ipynb b/2018/2018-challenge3.ipynb
new file mode 100644 (file)
index 0000000..d7c5282
--- /dev/null
@@ -0,0 +1,212 @@
+{
+ "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": 12,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from cipher.caesar import *\n",
+    "from cipher.affine import *\n",
+    "from cipher.keyword_cipher import *\n",
+    "from support.text_prettify import *"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "c3a = open('3a.ciphertext').read()\n",
+    "c3b = open('3b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "IWQSWTS UGI WJREWOINA KSST LBGL E IBWONP KTWU GJWOL PWOYNGI JNGMK JOL E UGI NSVL UWTPSFETY UBGL BS BGP LW PW UELB LBS IBGPWU GFMBERS. E VWOTP IWQS LFGMSI WV BEQ ET JWILWT TSUIZGZSF MNEZZETYI VFWQ LBS ZSFEWP. LBS ILWFESI ILWZZSP ET 1873, GFWOTP LBS PGLS WV LBS NSLLSFI JSLUSST REMLWFEG GTP IEF MBGFNSI, IW E GIIOQS BS FSLOFTSP LW STYNGTP LBST, JOL E MWONPT'L VETP GTA FSMWFP WV BEQ ET LBS EQQEYFGLEWT VENSI GTP LBSFS UGI TWLBETY ET LBS WVVEMEGN FSMWFP LW IOYYSIL LBGL BS QSL UELB IEF MBGFNSI, NSL GNWTS UELB BSF QGHSILA. LBS LFGEN BGP YWTS MWNP GTP E QEYBL BGRS QWRSP WT GL LBGL ZWETL, JOL LBST E YWL LBS LBEFP SQGEN. LBEI LEQS EL UGI G KSAUWFP MEZBSF GTP EL LWWK G NELLNS NWTYSF LW JFSGK, LBWOYB LBS UWFP ILFOMLOFS BSNZSP G NWL. EL MWTVEFQSP SRSFALBETY E BGP YOSIISP IW VGF GJWOL JNGMK, GTP FGEISP G UBWNS NWGP WV TSU COSILEWTI! EL GNIW IOYYSILSP LBGL E QEYBL VETP GTIUSFI ET LBS IBGPWU GFMBERS, JOL VEFIL E BGP LW VEYOFS WOL UBSFS EL UGI, GTP BWU E MWONP YSL ET. E ILENN MGT'L JSNESRS EL, JOL LBS GTIUSF MGQS VFWQ G YWWYNS ISGFMB. E UGI NWWKETY VWF G NWMGLEWT LBGL UWONP BGRS ZFWREPSP JNGMK UELB MWRSF VWF G ILFSGQ WV REIELWFI, ZFSVSFGJNA ET G MSTLFGN NWTPWT NWMGLEWT, GTP UELB VGMENELESI VWF ISMOFS ILWFGYS WV WVVEMEGN FSMWFPI, GTP EL IBWONP BGRS JSST WZSTSP ET 1873 WF 1874. E ISGFMBSP VWF \"JNGMK, NWTPWT, 1874\" GTP E NEKSP UBGL E VWOTP. GTP LBGL EI UBA E VWOTP QAISNV NAETY WT LBS FWWV WV LBS TWFQGT IBGU JOENPETYI ET LBS QEPPNS WV LBS TEYBL GTP ET ZWOFETY FGET! E BGP LW VEYOFS WOL G UGA WV YSLLETY ETIEPS WTS WV LBS QWIL ISMOFS NWMGLEWTI ET STYNGTP!\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "key_a, score_a = caesar_break(c3a)\n",
+    "print(caesar_decipher(c3a, key_a))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "SOMEONE WAS OBVIOUSLY KEEN THAT I SHOULD KNOW ABOUT DOUGLAS BLACK BUT I WAS LEFT WONDERING WHAT HE\n",
+      "HAD TO DO WITH THE SHADOW ARCHIVE. I FOUND SOME TRACES OF HIM IN BOSTON NEWSPAPER CLIPPINGS FROM THE\n",
+      "PERIOD. THE STORIES STOPPED IN 1873, AROUND THE DATE OF THE LETTERS BETWEEN VICTORIA AND SIR\n",
+      "CHARLES, SO I ASSUME HE RETURNED TO ENGLAND THEN, BUT I COULDN’T FIND ANY RECORD OF HIM IN THE\n",
+      "IMMIGRATION FILES AND THERE WAS NOTHING IN THE OFFICIAL RECORD TO SUGGEST THAT HE MET WITH SIR\n",
+      "CHARLES, LET ALONE WITH HER MAJESTY. THE TRAIL HAD GONE COLD AND I MIGHT HAVE MOVED ON AT THAT\n",
+      "POINT, BUT THEN I GOT THE THIRD EMAIL. THIS TIME IT WAS A KEYWORD CIPHER AND IT TOOK A LITTLE LONGER\n",
+      "TO BREAK, THOUGH THE WORD STRUCTURE HELPED A LOT. IT CONFIRMED EVERYTHING I HAD GUESSED SO FAR ABOUT\n",
+      "BLACK, AND RAISED A WHOLE LOAD OF NEW QUESTIONS! IT ALSO SUGGESTED THAT I MIGHT FIND ANSWERS IN THE\n",
+      "SHADOW ARCHIVE, BUT FIRST I HAD TO FIGURE OUT WHERE IT WAS, AND HOW I COULD GET IN. I STILL CAN’T\n",
+      "BELIEVE IT, BUT THE ANSWER CAME FROM A GOOGLE SEARCH. I WAS LOOKING FOR A LOCATION THAT WOULD HAVE\n",
+      "PROVIDED BLACK WITH COVER FOR A STREAM OF VISITORS, PREFERABLY IN A CENTRAL LONDON LOCATION, AND\n",
+      "WITH FACILITIES FOR SECURE STORAGE OF OFFICIAL RECORDS, AND IT SHOULD HAVE BEEN OPENED IN 1873 OR\n",
+      "1874. I SEARCHED FOR “BLACK, LONDON, 1874” AND I LIKED WHAT I FOUND. AND THAT IS WHY I FOUND MYSELF\n",
+      "LYING ON THE ROOF OF THE NORMAN SHAW BUILDINGS IN THE MIDDLE OF THE NIGHT AND IN POURING RAIN! I HAD\n",
+      "TO FIGURE OUT A WAY OF GETTING INSIDE ONE OF THE MOST SECURE LOCATIONS IN ENGLAND!\n"
+     ]
+    }
+   ],
+   "source": [
+    "(m_a, s_a, o_a), score_a = affine_break(c3a)\n",
+    "print(lcat(tpack(affine_decipher(c3a, m_a, s_a, o_a).split())))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1556"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('3a.plaintext', 'w').write(affine_decipher(c3a, m_a, s_a, o_a))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('loyalty', <KeywordWrapAlphabet.from_largest: 3>, -1602.564299343375)"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(key_b, wrap_b), score_b = keyword_break_mp(c3b)\n",
+    "key_b, wrap_b, score_b"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "her majesty is right, life in boston is dull, but not dull enough to persuade me that working for\n",
+      "her would be worth the risk. but of course she had an answer for that. she pointed out that\n",
+      "returning to the united states carried its own risks. i had kept myself amused for the last few\n",
+      "years separating the greedy and venal from their money by a variety of means, not all of them\n",
+      "entirely approved by the law. i was left wondering how the queen knew about that, and whether my\n",
+      "cousin had been instructed to tell the federal marshalls about my activities. discretion seemed the\n",
+      "wise course, and anyway, how often do you get a job offer from a queen? charles has done a sterling\n",
+      "job developing a network of agents and his intelligence operations have become a key part of british\n",
+      "diplomacy. the growing instability across europe threatens the empire, and it is her majesty’s\n",
+      "belief that we will need to respond in kind to destabilise our enemies before they grow too strong.\n",
+      "this is a new and dangerous kind of warfare, but could, i suppose, save lives, and we will, in any\n",
+      "case, need to match our enemies if we are to stay ahead. this entire operation must be kept secret.\n",
+      "first from our enemies, but second, and just as important, from the official machinery of state. her\n",
+      "majesty cannot afford the risk that her government could be implicated in these operations, and sir\n",
+      "charles has reason to believe that the foreign office may have been compromised. for this reason we\n",
+      "need to move sir charles’ intelligence operation to a more secure location. and i think i have an\n",
+      "idea where that could be!\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(keyword_decipher(c3b, key_b, wrap_b).split())))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1599"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('3b.plaintext', 'w').write(keyword_decipher(c3b, key_b, wrap_b))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.6"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/2018/2018-challenge4.ipynb b/2018/2018-challenge4.ipynb
new file mode 100644 (file)
index 0000000..8aec6a1
--- /dev/null
@@ -0,0 +1,596 @@
+{
+ "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 support.text_prettify import *"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "c4a = open('4a.ciphertext').read()\n",
+    "c4b = open('4b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "WHE QLXE AYU IO WHE OYME. WHE VLYQK MXUEXM IU APTLN FYMPXU YU WHE IO-HPXUE MXUEXM PF QTIME YW OEA UQPWLYON CYTN. WHE HIUWPTC VPPKU (PT YW LEYUW, AIKIRENIY) WPLN ME WHYW IW HYN VEEO UEW XR VC IOUREQWPT OEYME YON RQ TYONYLL UPME WIME YFWET YRTIL 1875 YU Y AYC WP XUE WHE RTIUPOETU' RTPRETWC UWPTE WP IOUWTXQW OEA TEQTXIWU IO WHE YTW PF NEWEQWIPO. WHE OYME FITUW YRREYTU IO RXVLIQ IO YO YTWIQLE IO WHE PVUETZET OEAURYRET IO 1877, YON WHE HIUWPTIYOU UYC IW AYU QPIOEN YU Y GTIULC HEYNLIOE VC Y JPXTOYLIUW AHP AYU UOXVVEN VC OEYME, VXW I YM OPW UP UXTE. IW NINO'W UEEM YO YQQINEOW WHYW NPXGLYU VLYQK AYU LPPKIOG WP UEW XR Y WPR UEQTEW YTQHIZE IO LPONPO YW WHYW WIME, YON UQPWLYON CYTN GYZE HIM WHE RETFEQW LPQYWIPO. IW AYU QEOWTYL YON EYUC WP YQQEUU. IW HYN UEZETYL EOWTYOQEU, AIWH Y UWEYNC FLPA PF ZIUIWPTU, OPW YLL PF WHEM EOWITELC TERXWYVLE, WHYW APXLN NIUGXIUE WHE QPMIOGU YON GPIOGU PF WHE YGEOWU YON PFFIQETU PF VLYQK'U OEWAPTK. VEUW PF YLL IW HYN WHE EOWITE MEWTPRPLIWYO RPLIQE FPTQE UWYONIOG GXYTN, AHIQH AYU GTEYW FPT VLYQK, YON WPXGH PO ME. IW APXLN VE WHE INEYL LPQYWIPO FPT WHE UHYNPA YTQHIZE.\n",
+      "UQPWLYON CYTN HYN MPZEN WP OEA RTEMIUEU UEZETYL WIMEU UIOQE IW AYU FITUW UEW XR, VXW I AYU VEWWIOG WHYW WHE UHYNPA YTQHIZE HYN MPZEN AIWH IW, YON I UREOW WHE VEUW RYTW PF WHTEE AEEKU UQPXWIOG WHE OPTMYO UHYA VXILNIOGU YON WHE OEA \"OEA UQPWLYON CYTN\" OEBW NPPT YW WHE QXTWIU GTEEO VXILNIOG. IW IU OPW EYUC WP NP WHYW AIWHPXW VEIOG URPWWEN, HEOQE WHE OIGHW WIME TEQPOOYIUUYOQE IO WHE TYIO. WHE AYWET YON WHE QPLN RLYCEN HYZPQ AIWH MC MPPN, VXW YLUP AIWH MYOC NEWEQWPT UCUWEMU UP IW AYU APTWH WHE NIUQPMFPTW.\n",
+      "OP-POE AYU LIKELC WP GIZE ME WHE TEYL RLYOU PF WHE RLYQE, WHPXGH HYTTC AYU HYRRC WP RTPZINE ME AIWH Y QPRC PF WHE PFFIQIYL LYCPXW, YON I XUEN Y LINYT UCUWEM WP MYR YU MXQH PF WHE PXWUINE YU I QPXLN. QPMRYTIOG WHE WAP UHPXLN HYZE TEZEYLEN XOMYTKEN UWPTYGE YTEYU YON GIZEO ME UPME INEY HPA I MIGHW GEW IO, VXW OPWHIOG UHPAEN XR XOWIL I HYN Y LXQKC VTEYK. LIWETYLLC. I HYN LPAETEN WHE LINYT NEWEQWPT NPAO Y UHYFW PO WHE QXTWIU GTEEO TPPF, HPRIOG WP GEW Y GLIMRUE IOWP UPME PF WHE OEYTVC TPPMU. IW HYN JXUW YVPXW TEYQHEN GTPXON LEZEL AHEO WHE OCLPO LIOE UOYRREN. IW MYNE Y HELL PF Y TPA YU IW QLYWWETEN NPAO, YON I RTERYTEN WP TXO, VXW OP YLYTMU AEOW PFF YON, MPTE IMRPTWYOWLC, I OPWIQEN UPMEWHIOG UIGOIFIQYOW. IW HYN WYKEO YTPXON FIZE UEQPONU FPT WHE LINYT WP QTYUH NPAO, AHIQH, YW Y TPXGH EUWIMYWE, MEYOW IW HYN FYLLEO FTEE FPT YTPXON POE HXONTEN YON WAEOWC MEWTEU. WHYW APXLN HYZE WYKEO IW Y LPOG AYC XONETGTPXON, YON WHETE AETE OP VYUEMEOW TPPMU MYTKEN PO WHE RLYOU IO WHYW LPQYWIPO. I AYU RTEWWC UXTE I HYN FPXON WHE UHYNPA YTQHIZE: OPA I JXUW HYN WP FION Y AYC IO.\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "key_a, score_a = caesar_break(c4a)\n",
+    "print(caesar_decipher(c4a, key_a))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "STO IRLO QEG MW STO WEKO. STO ZREIY KLGOLK MG QPNRD HEKPLG EG STO MW-TPLGO KLGOLK PH INMKO ES WOQ\n",
+      "GIPSREWD CEND. STO TMGSPNC ZPPYG (PN ES ROEGS, QMYMBODME) SPRD KO STES MS TED ZOOW GOS LB ZC\n",
+      "MWGBOISPN WOEKO EWD BI NEWDERR GPKO SMKO EHSON EBNMR 1875 EG E QEC SP LGO STO BNMGPWONG’ BNPBONSC\n",
+      "GSPNO SP MWGSNLIS WOQ NOINLMSG MW STO ENS PH DOSOISMPW. STO WEKO HMNGS EBBOENG MW BLZRMI MW EW\n",
+      "ENSMIRO MW STO PZGONXON WOQGBEBON MW 1877, EWD STO TMGSPNMEWG GEC MS QEG IPMWOD EG E ANMGRC TOEDRMWO\n",
+      "ZC E FPLNWERMGS QTP QEG GWLZZOD ZC WOEKO, ZLS M EK WPS GP GLNO. MS DMDW’S GOOK EW EIIMDOWS STES\n",
+      "DPLAREG ZREIY QEG RPPYMWA SP GOS LB E SPB GOINOS ENITMXO MW RPWDPW ES STES SMKO, EWD GIPSREWD CEND\n",
+      "AEXO TMK STO BONHOIS RPIESMPW. MS QEG IOWSNER EWD OEGC SP EIIOGG. MS TED GOXONER OWSNEWIOG, QMST E\n",
+      "GSOEDC HRPQ PH XMGMSPNG, WPS ERR PH STOK OWSMNORC NOBLSEZRO, STES QPLRD DMGALMGO STO IPKMWAG EWD\n",
+      "APMWAG PH STO EAOWSG EWD PHHMIONG PH ZREIY’G WOSQPNY. ZOGS PH ERR MS TED STO OWSMNO KOSNPBPRMSEW\n",
+      "BPRMIO HPNIO GSEWDMWA ALEND, QTMIT QEG ANOES HPN ZREIY, EWD SPLAT PW KO. MS QPLRD ZO STO MDOER\n",
+      "RPIESMPW HPN STO GTEDPQ ENITMXO. GIPSREWD CEND TED KPXOD SP WOQ BNOKMGOG GOXONER SMKOG GMWIO MS QEG\n",
+      "HMNGS GOS LB, ZLS M QEG ZOSSMWA STES STO GTEDPQ ENITMXO TED KPXOD QMST MS, EWD M GBOWS STO ZOGS BENS\n",
+      "PH STNOO QOOYG GIPLSMWA STO WPNKEW GTEQ ZLMRDMWAG EWD STO WOQ “WOQ GIPSREWD CEND” WOJS DPPN ES STO\n",
+      "ILNSMG ANOOW ZLMRDMWA. MS MG WPS OEGC SP DP STES QMSTPLS ZOMWA GBPSSOD, TOWIO STO WMATS SMKO\n",
+      "NOIPWWEMGGEWIO MW STO NEMW. STO QESON EWD STO IPRD BRECOD TEXPI QMST KC KPPD, ZLS ERGP QMST KEWC\n",
+      "DOSOISPN GCGSOKG GP MS QEG QPNST STO DMGIPKHPNS. WP-PWO QEG RMYORC SP AMXO KO STO NOER BREWG PH STO\n",
+      "BREIO, STPLAT TENNC QEG TEBBC SP BNPXMDO KO QMST E IPBC PH STO PHHMIMER RECPLS, EWD M LGOD E RMDEN\n",
+      "GCGSOK SP KEB EG KLIT PH STO PLSGMDO EG M IPLRD. IPKBENMWA STO SQP GTPLRD TEXO NOXOEROD LWKENYOD\n",
+      "GSPNEAO ENOEG EWD AMXOW KO GPKO MDOE TPQ M KMATS AOS MW, ZLS WPSTMWA GTPQOD LB LWSMR M TED E RLIYC\n",
+      "ZNOEY. RMSONERRC. M TED RPQONOD STO RMDEN DOSOISPN DPQW E GTEHS PW STO ILNSMG ANOOW NPPH, TPBMWA SP\n",
+      "AOS E ARMKBGO MWSP GPKO PH STO WOENZC NPPKG. MS TED FLGS EZPLS NOEITOD ANPLWD ROXOR QTOW STO WCRPW\n",
+      "RMWO GWEBBOD. MS KEDO E TORR PH E NPQ EG MS IRESSONOD DPQW, EWD M BNOBENOD SP NLW, ZLS WP ERENKG\n",
+      "QOWS PHH EWD, KPNO MKBPNSEWSRC, M WPSMIOD GPKOSTMWA GMAWMHMIEWS. MS TED SEYOW ENPLWD HMXO GOIPWDG\n",
+      "HPN STO RMDEN SP INEGT DPQW, QTMIT, ES E NPLAT OGSMKESO, KOEWS MS TED HERROW HNOO HPN ENPLWD PWO\n",
+      "TLWDNOD EWD SQOWSC KOSNOG. STES QPLRD TEXO SEYOW MS E RPWA QEC LWDONANPLWD, EWD STONO QONO WP\n",
+      "ZEGOKOWS NPPKG KENYOD PW STO BREWG MW STES RPIESMPW. M QEG BNOSSC GLNO M TED HPLWD STO GTEDPQ\n",
+      "ENITMXO: WPQ M FLGS TED SP HMWD E QEC MW.\n"
+     ]
+    }
+   ],
+   "source": [
+    "(m_a, s_a, o_a), score_a = affine_break(c4a)\n",
+    "print(lcat(tpack(affine_decipher(c4a, m_a, s_a, o_a).split())))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('retaliates', <KeywordWrapAlphabet.from_last: 2>, -2652.2981337278975)"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(key_a, wrap_a), score_a = keyword_break_mp(c4a)\n",
+    "key_a, wrap_a, score_a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "tha plua wes in tha nema. tha flepk musaum is world gemous es tha in-housa musaum og prima et naw\n",
+      "spotlend yerd. tha history fooks (or et laest, wikibadie) told ma thet it hed faan sat ub fy\n",
+      "insbaptor naema end bp rendell soma tima egtar ebril 1875 es e wey to usa tha brisonars’ brobarty\n",
+      "stora to instrupt naw rapruits in tha ert og dataption. tha nema girst ebbaers in buflip in en\n",
+      "ertipla in tha ofsarvar nawsbebar in 1877, end tha historiens sey it wes poinad es e crisly haedlina\n",
+      "fy e journelist who wes snuffad fy naema, fut i em not so sura. it didn’t saam en eppidant thet\n",
+      "doucles flepk wes lookinc to sat ub e tob saprat erphiva in london et thet tima, end spotlend yerd\n",
+      "ceva him tha bargapt lopetion. it wes pantrel end aesy to eppass. it hed savarel antrenpas, with e\n",
+      "staedy glow og visitors, not ell og tham antiraly rabutefla, thet would discuisa tha pomincs end\n",
+      "coincs og tha ecants end oggipars og flepk’s natwork. fast og ell it hed tha antira matroboliten\n",
+      "bolipa gorpa stendinc cuerd, whiph wes craet gor flepk, end touch on ma. it would fa tha idael\n",
+      "lopetion gor tha shedow erphiva. spotlend yerd hed movad to naw bramisas savarel timas sinpa it wes\n",
+      "girst sat ub, fut i wes fattinc thet tha shedow erphiva hed movad with it, end i sbant tha fast bert\n",
+      "og thraa waaks spoutinc tha normen shew fuildincs end tha naw “naw spotlend yerd” naxt door et tha\n",
+      "purtis craan fuildinc. it is not aesy to do thet without fainc sbottad, hanpa tha nicht tima\n",
+      "raponneissenpa in tha rein. tha wetar end tha pold bleyad hevop with my mood, fut elso with meny\n",
+      "dataptor systams so it wes worth tha dispomgort. no-ona wes likaly to civa ma tha rael blens og tha\n",
+      "blepa, thouch herry wes hebby to brovida ma with e poby og tha oggipiel leyout, end i usad e lider\n",
+      "systam to meb es muph og tha outsida es i pould. pomberinc tha two should heva ravaelad unmerkad\n",
+      "storeca eraes end civan ma soma idae how i micht cat in, fut nothinc showad ub until i hed e lupky\n",
+      "fraek. litarelly. i hed lowarad tha lider dataptor down e shegt on tha purtis craan roog, hobinc to\n",
+      "cat e climbsa into soma og tha naerfy rooms. it hed just efout raephad cround laval whan tha nylon\n",
+      "lina snebbad. it meda e hall og e row es it plettarad down, end i braberad to run, fut no elerms\n",
+      "want ogg end, mora imbortently, i notipad somathinc sicnigipent. it hed tekan eround giva saponds\n",
+      "gor tha lider to presh down, whiph, et e rouch astimeta, maent it hed gellan graa gor eround ona\n",
+      "hundrad end twanty matras. thet would heva tekan it e lonc wey undarcround, end thara wara no\n",
+      "fesamant rooms merkad on tha blens in thet lopetion. i wes bratty sura i hed gound tha shedow\n",
+      "erphiva: now i just hed to gind e wey in.\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(keyword_decipher(c4a, key_a, wrap_a).split())))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'retalisuvwxyzbcdfghjkmnopq'"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kca = keyword_cipher_alphabet_of(key_a, wrap_a)\n",
+    "kca"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'lidarstuvwxyzbceqghjkmnopf'"
+      ]
+     },
+     "execution_count": 20,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cipher_alphabet, score = simulated_annealing_break(c4a, cipher_alphabet=kca, fitness=Pbigrams)\n",
+    "cipher_alphabet"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'the clue was in the name. the black museum is world famous as the in-house museum of crime at new scotland yard. the history books (or at least, wikipedia) told me that it had been set up by inspector neame and pc randall some time after april 1875 as a way to use the prisoners’ property store to instruct new recruits in the art of detection. the name first appears in public in an article in the observer newspaper in 1877, and the historians say it was coined as a grisly headline by a journalist who was snubbed by neame, but i am not so sure. it didn’t seem an accident that douglas black was looking to set up a top secret archive in london at that time, and scotland yard gave him the perfect location. it was central and easy to access. it had several entrances, with a steady flow of visitors, not all of them entirely reputable, that would disguise the comings and goings of the agents and officers of black’s network. best of all it had the entire metropolitan police force standing guard, which was great for black, and tough on me. it would be the ideal location for the shadow archive.\\nscotland yard had moved to new premises several times since it was first set up, but i was betting that the shadow archive had moved with it, and i spent the best part of three weeks scouting the norman shaw buildings and the new “new scotland yard” next door at the curtis green building. it is not easy to do that without being spotted, hence the night time reconnaissance in the rain. the water and the cold played havoc with my mood, but also with many detector systems so it was worth the discomfort.\\nno-one was likely to give me the real plans of the place, though harry was happy to provide me with a copy of the official layout, and i used a lidar system to map as much of the outside as i could. comparing the two should have revealed unmarked storage areas and given me some idea how i might get in, but nothing showed up until i had a lucky break. literally. i had lowered the lidar detector down a shaft on the curtis green roof, hoping to get a glimpse into some of the nearby rooms. it had just about reached ground level when the nylon line snapped. it made a hell of a row as it clattered down, and i prepared to run, but no alarms went off and, more importantly, i noticed something significant. it had taken around five seconds for the lidar to crash down, which, at a rough estimate, meant it had fallen free for around one hundred and twenty metres. that would have taken it a long way underground, and there were no basement rooms marked on the plans in that location. i was pretty sure i had found the shadow archive: now i just had to find a way in.\\n'"
+      ]
+     },
+     "execution_count": 21,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# cipher_alphabet = 'cpearstubomykvliqghjdxnwzf'\n",
+    "cipher_translation = ''.maketrans(cipher_alphabet, string.ascii_lowercase)\n",
+    "plaintext = c4a.lower().translate(cipher_translation)\n",
+    "plaintext"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'lidarstuvwxyzbcefghjkmnopq'"
+      ]
+     },
+     "execution_count": 22,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "keyword_cipher_alphabet_of('lidar', KeywordWrapAlphabet.from_last)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'the clue was in the name. the black museum is world famous as the in-house museum of crime at new scotland yard. the history books (or at least, wikipedia) told me that it had been set up by inspector neame and pc randall some time after april 1875 as a way to use the prisoners’ property store to instruct new recruits in the art of detection. the name first appears in public in an article in the observer newspaper in 1877, and the historians say it was coined as a grisly headline by a journalist who was snubbed by neame, but i am not so sure. it didn’t seem an accident that douglas black was looking to set up a top secret archive in london at that time, and scotland yard gave him the perfect location. it was central and easy to access. it had several entrances, with a steady flow of visitors, not all of them entirely reputable, that would disguise the comings and goings of the agents and officers of black’s network. best of all it had the entire metropolitan police force standing guard, which was great for black, and tough on me. it would be the ideal location for the shadow archive.\\nscotland yard had moved to new premises several times since it was first set up, but i was betting that the shadow archive had moved with it, and i spent the best part of three weeks scouting the norman shaw buildings and the new “new scotland yard” next door at the curtis green building. it is not easy to do that without being spotted, hence the night time reconnaissance in the rain. the water and the cold played havoc with my mood, but also with many detector systems so it was worth the discomfort.\\nno-one was likely to give me the real plans of the place, though harry was happy to provide me with a copy of the official layout, and i used a lidar system to map as much of the outside as i could. comparing the two should have revealed unmarked storage areas and given me some idea how i might get in, but nothing showed up until i had a lucky break. literally. i had lowered the lidar detector down a shaft on the curtis green roof, hoping to get a glimpse into some of the nearby rooms. it had just about reached ground level when the nylon line snapped. it made a hell of a row as it clattered down, and i prepared to run, but no alarms went off and, more importantly, i noticed something significant. it had taken around five seconds for the lidar to crash down, which, at a rough estimate, meant it had fallen free for around one hundred and twenty metres. that would have taken it a long way underground, and there were no basement rooms marked on the plans in that location. i was pretty sure i had found the shadow archive: now i just had to find a way in.\\n'"
+      ]
+     },
+     "execution_count": 23,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "keyword_decipher(c4a, 'lidar', KeywordWrapAlphabet.from_last)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "True"
+      ]
+     },
+     "execution_count": 24,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "keyword_decipher(c4a, 'lidar', KeywordWrapAlphabet.from_last) == plaintext"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(3, 1, True)"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "m_a, s_a, o_a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2674"
+      ]
+     },
+     "execution_count": 25,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('4a.plaintext', 'w').write(keyword_decipher(c4a, 'lidar', KeywordWrapAlphabet.from_last))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "OHFRK DTYTR YWHUU HDUHR DFUTU NUHDD FTUFR DWRNA YMWSE UHDZF EYMUH DTNVU HDRMR DWYNM UHDNU UNLFM TFRDR DTUKD TTFMZ YMUHD MNRUH UHDUH RDDDL PDRNR TFRDF WRNAY MWUHR DFUUN NVRYM CKVDM ODUHD CNRDY WMNCC YODTD DLPFR FKETD ZCNOV TTDZD MUYRD KENMC NRLYM WFKKY FMODT FMZVM FSKDU NZDUD RLYMD UHDYR SDTUT URFUD WEYUH YMJUH DEFRD LYTUF JDMYM UHDYR NVUKN NJUHD ECNOV TUNNL VOHNM URDFU YDTFM ZMNUD MNVWH NMRDF KPNKY UYJFT XNMRN OHFVA RNUDU HDKFA NCPNA DRWNX DRMTU HDANR KZNCT UFUDT IVTUF TUHDK FANCW RFXYU EWNXD RMTUH DPHET YOFKA NRKZF MZADF RDPDR HFPTU NNLVO HYMOK YMDZU NNXDR KNNJU HDRDF KLYWH UNCUH DLNRD PNADR CVKFM ZUHDY MDXYU FSYKY UENCY UTPNK YUYOF KYMCK VDMOD NVRUF TJMNA YTMNU UNOHN NTDFC FXNVR DZPFR UMDRU NONMU RNKUH DNUHD RTUHF UAFER YTJTA FRFMF KKYFM ODAYK KDMON VRFWD FONVM UDRFK KYFMO DFMZF ZFMWD RNVTD TOFKF UYNMY MTUDF ZNVRT URFUD WETHN VKZSD UNLFY MUFYM FMFZL YUUDZ KEVMD FTEPD FODSD UADDM UHDDL PDRNR TUNWD UHDRU HDEFR DUHDS YWWDT UPNKY UYOFK UHRDF UUNNV RDLPY RDSVU FTDMD LYDTN CNMDF MNUHD RUHDE FKTNU HRDFU DMNVR URFZY MWRNV UDTAD MDDZU NYMZV ODUHD LUNAN RJUNW DUHDR AHYKD PRDXD MUYMW UHDLC RNLCN RLYMW FPNAD RSKNO FWFYM TUNVR YMUDR DTUNV RLNTU YLPNR UFMUA DFPNM YMUHY TYTON MCVTY NMFMZ LYKZZ YTURV TUUHD SDTUN VUONL DANVK ZSDUN DMONV RFWDF ZETCV MOUYN MFKFK KYFMO DSDUA DDMFK KUHRD DUHFU LFJDT YUHFR ZCNRU HDDLP DRNRT UNCYW HUNMD FMNUH DRNRV TFMZY MUHDN UUNLF MORYT YTYUH YMJYT DMTDF MNPPN RUVMY UEUNZ NIVTU UHFU\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "key_b, score_b = caesar_break(c4b)\n",
+    "print(caesar_decipher(c4b, key_b))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "tewsdoahashzerreoresowrarcreoowarwsozscphlzjfreoywfhlreoacireoslsozhclreocrrcuwlawsosoardoaawlyhlreolcsrereoresoooukoscsawsowzscphlzresowrrccishlxdioltoreoxcsohzlcxxhtoaooukwswdfaoyxctiaaoyolrhsodfclxcsuhlzwddhwltoawlyilwjdorcyorosuhloreohsjoararswrozfhrehlmreofwsouharwmolhlreohscirdccmreofxctiarccuiteclrsowrhoawlylcrolcizeclsowdkcdhrhmwaqclsctewipscroreodwpcxkcposzcqoslareopcsdycxarwroaviarwareodwpcxzswqhrfzcqoslareokefahtwdpcsdywlypowsokosewkarccuitehltdhloyrccqosdccmreosowduhzercxreoucsokcposxidwlyreohloqhrwjhdhrfcxhrakcdhrhtwdhlxdioltocisrwamlcphalcrrcteccaowxwqcisoykwsrlosrctclrscdreocreosarewrpwfshamapwswlwddhwltophddoltciswzowtcilroswddhwltowlywywlzosciaoatwdwrhclhlarowycisarswrozfaecidyjorcuwhlrwhlwlwyuhrroydfilowafkowtojorpoolreooukoscsarczoreosreofwsoreojhzzoarkcdhrhtwdresowrrccisoukhsojirwaolouhoacxclowlcreosreofwdacresowrolcisrswyhlzsciroapolooyrchlyitoreourcpcsmrczoreospehdoksoqolrhlzreouxscuxcsuhlzwkcposjdctwzwhlarcishlrosoarcisucarhukcsrwlrpowkclhlrehahatclxiahclwlyuhdyyharsiarreojoarcirtcuopcidyjorcoltciswzowyfaxiltrhclwdwddhwltojorpoolwddresoorewruwmoahrewsyxcsreooukoscsarcxhzerclowlcreoscsiawlyhlreocrrcuwltshahahrehlmhaolaowlckkcsrilhrfrcycviarrewr\n"
+     ]
+    }
+   ],
+   "source": [
+    "(m_b, s_b, o_b), score_b = affine_break(c4b)\n",
+    "print(lcat(tpack(affine_decipher(sanitise(c4b), m_b, s_b, o_b).split())))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('polarimeter', <KeywordWrapAlphabet.from_last: 2>, -1501.4114029890893)"
+      ]
+     },
+     "execution_count": 30,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(key_b, wrap_b), score_b = keyword_break_mp(sanitise(c4b))\n",
+    "key_b, wrap_b, score_b"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'dierlaswsrwfittiatiraetstotiaaesterafrogwnfhytiaceywntiasoutiarnrafwontiaottomenserarastlassencwntianortitiatiraaamparorseraefrogwnftiraettoourwnbluandatiaborawfnobbwdasaamperelysacbodussacantwralyonbormwnfellwendasencunehlatocatarmwnatiawrhaststretafywtiwnktiayeramwstekanwntiawroutlooktiaybodustoomudiontraetwasencnotanoufionraelpolwtwkesvonrodieugrotatialegobpogarfovarnstiagorlcobstetasjustestialegobfrevwtyfovarnstiapiyswdelgorlcencgaerapariepstoomudiwndlwnactoovarlooktiaraelmwfitobtiamorapogarbulenctiawnavwtehwlwtyobwtspolwtwdelwnbluandaourtesknogwsnottodioosaebevouracpertnartodontroltiaotiarstietgeyrwsksgerenellwendagwllandourefaedountarellwendaencecenfarousasdeletwonwnstaecourstretafysioulchatomewntewnenecmwttaclyunaesypaedahatgaantiaamparorstofatiartiayeratiahwffastpolwtwdeltiraettoourampwrahutesanamwasobonaenotiartiayelsotiraetanourtrecwnfroutasganaactowncudatiamtogorktofatiargiwlapravantwnftiambrombormwnfepogarhlodefewnstourwntarastourmostwmportentgaeponwntiwswsdonbuswonencmwlccwstrusttiahastoutdomagoulchatoandourefaecysbundtwonelellwendahatgaanelltiraatietmekaswtiercbortiaamparorstobwfitonaenotiarorusencwntiaottomendrwswswtiwnkwsansaenopportunwtytocojusttiet'"
+      ]
+     },
+     "execution_count": 33,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "keyword_decipher(sanitise(c4b), key_b, wrap_b)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 43,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'realpoitkuvwxyzbndfghjmsqc'"
+      ]
+     },
+     "execution_count": 43,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cipher_alphabet, score = simulated_annealing_break(c4b, fitness=Pbigrams)\n",
+    "cipher_alphabet"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 47,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'realpoitkuvwxyzbcdfghjmnqs'"
+      ]
+     },
+     "execution_count": 47,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "keyword_cipher_alphabet_of('realpolitik', KeywordWrapAlphabet.from_largest)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 44,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'charl esisr ightt hethr eatst othee astar egrow ingby theda yinth esout hernr egion theot toman sarer estle ssand inthe north theth reeem peror sarea growi ngthr eatto ourin fluen cethe forei gnoff icese empar alyse dfocu ssede ntire lyonf ormin galli ances andun ablet odete rmine their bests trate gyith inkth eyare mista kenin their outlo okthe yfocu stoom uchon treat iesan dnote nough onrea lpoli tikas vonro chauw rotet helaw ofpow ergov ernst hewor ldofs tates justa sthel awofg ravit ygove rnsth ephys icalw orlda ndwea reper hapst oomuc hincl inedt oover lookt herea lmigh tofth emore power fulan dthei nevit abili tyofi tspol itica linfl uence ourta sknow isnot tocho oseaf avour edpar tnert ocont rolth eothe rstha twayr isksw arana llian cewil lenco urage acoun teral lianc eanda dange rouse scala tioni nstea dours trate gysho uldbe tomai ntain anadm itted lyune asype acebe tween theem peror stoge thert heyar etheb igges tpoli tical threa ttoou rempi rebut asene mieso fonea nothe rthey alsot hreat enour tradi ngrou teswe needt oindu cethe mtowo rktog ether while preve nting themf romfo rming apowe rbloc again stour inter estou rmost impor tantw eapon inthi sisco nfusi onand mildd istru stthe besto utcom ewoul dbeto encou ragea dysfu nctio nalal lianc ebetw eenal lthre ethat makes ithar dfort heemp erors tofig htone anoth eroru sandi ntheo ttoma ncris isith inkis ensea noppo rtuni tytod ojust that\\n'"
+      ]
+     },
+     "execution_count": 44,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# cipher_alphabet = 'cpearstubomykvliqghjdxnwzf'\n",
+    "cipher_translation = ''.maketrans(cipher_alphabet, string.ascii_lowercase)\n",
+    "plaintext = c4b.lower().translate(cipher_translation)\n",
+    "plaintext"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 49,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'charlesisrightthethreatstotheeastaregrowingbythedayinthesouthernregiontheottomansarerestlessandinthenorththethreeemperorsareagrowingthreattoourinfluencetheforeignofficeseemparalysedfocussedentirelyonformingalliancesandunabletodeterminetheirbeststrategyithinktheyaremistakenintheiroutlooktheyfocustoomuchontreatiesandnotenoughonrealpolitikasvonrochauwrotethelawofpowergovernstheworldofstatesjustasthelawofgravitygovernsthephysicalworldandweareperhapstoomuchinclinedtooverlooktherealmightofthemorepowerfulandtheinevitabilityofitspoliticalinfluenceourtasknowisnottochooseafavouredpartnertocontroltheothersthatwayriskswaranalliancewillencourageacounterallianceandadangerousescalationinsteadourstrategyshouldbetomaintainanadmittedlyuneasypeacebetweentheemperorstogethertheyarethebiggestpoliticalthreattoourempirebutasenemiesofoneanothertheyalsothreatenourtradingroutesweneedtoinducethemtoworktogetherwhilepreventingthemfromformingapowerblocagainstourinterestourmostimportantweaponinthisisconfusionandmilddistrustthebestoutcomewouldbetoencourageadysfunctionalalliancebetweenallthreethatmakesithardfortheemperorstofightoneanotherorusandintheottomancrisisithinkisenseanopportunitytodojustthat'"
+      ]
+     },
+     "execution_count": 49,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "keyword_decipher(sanitise(c4b), 'realpolitik', KeywordWrapAlphabet.from_largest)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 52,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "True"
+      ]
+     },
+     "execution_count": 52,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "keyword_decipher(sanitise(c4b), 'realpolitik', KeywordWrapAlphabet.from_largest) == sanitise(plaintext)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 51,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "charles is right the threats to the east are growing by the day in the southern region the ottomans\n",
+      "are restless and in the north the three emperors area growing threat to our influence the foreign\n",
+      "office seem paralysed focussed entirely on forming alliances and unable to determine their best\n",
+      "strategy i think they are mistaken in their outlook they focus too much on treaties and not enough\n",
+      "on realpolitik as von rocha u wrote the law of power governs the world of states just as the law of\n",
+      "gravity governs the physical world and we are perhaps too much inclined to overlook the real might\n",
+      "of the more powerful and the inevitability of its political influence our task now is not to choose\n",
+      "a favoured partner to control the others that way risks war an alliance will encourage a counter\n",
+      "alliance and a dangerous escalation instead our strategy should be to maintain an admittedly uneasy\n",
+      "peace between the emperors together they are the biggest political threat to our empire but as\n",
+      "enemies of one another they also threaten our trading routes we need to induce them to work together\n",
+      "while preventing them from forming a power bloc against our interest our most important weapon in\n",
+      "this is confusion and mild distrust the best outcome would be to encourage a dysfunctional alliance\n",
+      "between all three that makes it hard for the emperors to fight one another or us and in the ottoman\n",
+      "crisis i think i sense an opportunity to do just that\n"
+     ]
+    }
+   ],
+   "source": [
+    "kpt = keyword_decipher(sanitise(c4b), 'realpolitik', KeywordWrapAlphabet.from_largest)\n",
+    "print(lcat(tpack(segment(sanitise(kpt)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 58,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1436"
+      ]
+     },
+     "execution_count": 58,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('4b.plaintext', 'w').write(lcat(tpack(segment(kpt))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.6"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/2018/2018-challenge5.ipynb b/2018/2018-challenge5.ipynb
new file mode 100644 (file)
index 0000000..adfa3ad
--- /dev/null
@@ -0,0 +1,614 @@
+{
+ "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": 23,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from cipher.caesar import *\n",
+    "from cipher.affine import *\n",
+    "from cipher.keyword_cipher import *\n",
+    "from cipher.vigenere import *\n",
+    "from support.text_prettify import *\n",
+    "from support.plot_frequency_histogram import *"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ca = open('5a.ciphertext').read()\n",
+    "cb = open('5b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('ariadne', <KeywordWrapAlphabet.from_largest: 3>, -2373.327599593623)"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(key_a, wrap_a), score_a = keyword_break_mp(ca)\n",
+    "key_a, wrap_a, score_a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "i am still not sure which of the two came up with the idea of the underground archive it will have\n",
+      "appealed to black as away to provide security to his operation but a civil engineering project of\n",
+      "this scale doesnt seem like his sort of things oi think it must have been conceived by charles grey\n",
+      "the first tube line had been opened in and london was full of labourers and engineers with the\n",
+      "skills needed to build the shadow archive deep beneath new scotland yard getting access was not\n",
+      "going to be easy without harrys help but i still didnt have enough to give him the excuse he would\n",
+      "need to get openly involved my reconnaissance had helped me to find the archive but it didnt give me\n",
+      "any obvious way in the duct that had cost me the lidar was far too narrow for me to scale and access\n",
+      "through the frontdoor was too risky so i took a gamble and spent another miserable fortnight\n",
+      "exploring the labyrinth of sewers and tunnel systems around the neighbourhood gps was useless down\n",
+      "there and i could easily have got lost but i marked the tunnels and on occasions used these us trick\n",
+      "of a ball of twine to help me navigate back i moved quietly and kept an eye out for sensors i had no\n",
+      "idea whether the shadow archive was still operational or not but if it was then security would be\n",
+      "tight and i couldnt be sure if they were using infrared or seismometers for intrusion detection so i\n",
+      "layered up with insulation and moved slowly it was horrible i was hot damp and the air smelled of\n",
+      "sewage and mould i was just about to give up when i found a steel door marked with the initial svr i\n",
+      "victoria regina imper atrix it was incongruous in that dark and dank tunnel but more significantly\n",
+      "it carried the trademark tan non the lock john tann was one of the top safe makers in victorian\n",
+      "london and i had cracked one or two of his safes in my other life as a cat burglar this was big and\n",
+      "heavy and very rusty that told me two things no one had used it in a very longtime and no one had\n",
+      "upgraded it in just as long if the room behind it was still in use then someone would have been\n",
+      "maintaining the lock so all my precautions were probably unnecessary but no one had paid for at ann\n",
+      "safe without something important to hide so i decided to tackle the lock and after another eighteen\n",
+      "hours of grim work i was in i had found the shadow archive\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(sanitise(keyword_decipher(ca, key_a, wrap_a))))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2328"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('5a.plaintext', 'w').write(lcat(tpack(segment(sanitise(keyword_decipher(ca, key_a, wrap_a))))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('disgrace', <KeywordWrapAlphabet.from_largest: 3>, -2302.602730496926)"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(key_b, wrap_b), score_b = keyword_break_mp(sanitise(cb))\n",
+    "key_b, wrap_b, score_b"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "st ne vdr slava bnwoduorhtsumtaegnri enel odt no botw of sw on kr no y nec agner ba vdr slava\n",
+      "brftotnaydauqnrco no assam mobs a fgrgulbnobyltnrbrdse fr fda ec yelp node hmo dcr b avg e docks eot\n",
+      "nelp as aft no gne no as ucnobwosotrhtsumyirt edts duos yew leser mo btu or ft rbnrulcnaotnelpegrrn\n",
+      "agnes as ad brft otrs no psr drft rna md rtr got no ost gets f bar dna in at rrm rhl laws\n",
+      "yovnrsdodrpmrrftyllu cr deb gerd tt sum rw gner pod urn drft donna rbn rul cnas taco ft gerd hr ft\n",
+      "nr va irda pm rrf totter dft md rtd rino let nrs rd pye mclr star uierlrftgnefdrftorft no no a savy\n",
+      "de no as nep xr seas sud nana rdotmafnoylrdnebrwk nafta osrietnevgesafott on sae ass\n",
+      "udgrlgadhnuneteftgrb nav nobr hot grrn to nl law rfg ned ewdrftducgaoveotgne no air drft nad rw opc\n",
+      "orb nele hen aetna emot nrrkyldelubatdepsakb dems a hrs ueb duo ots dod rpm rrrdftrftcoruierlrf trie\n",
+      "in rot rl has sop rhye mtas tfi alto ocr ftc or deli rftmodcyeweyelprfttb rd a got g nes dot be\n",
+      "rftrbnrulcnaotydtot no at rd bsagftawgrrbodpotsu wolley emsa ftt nrg udp try g negri e in ry lledo\n",
+      "mr matr me srftterdapmrrftcosr be cow tr ftgl do wrf tots rtedtsnomrgssrdprftg net nr meal dep nag\n",
+      "rt bug no brt up sag darf ty tan utd oppo nest nrs rd pal red sag gner not sgelinrrwtrhtnrmrr dies\n",
+      "agbalhuprftteftk nafta no at brl crd not uhs mae duo tuo he no asuc no bot gerlgluobsaftteftru dts\n",
+      "at agnes bat bet do yirtedtsybalopnorr die otrlhenurdesdrgerlle bata lop duo teft rte nut doc nude\n",
+      "rpp eye mta geod hegner moftesuollebgnekerwi nader ppe k sadr fnr ft no at be nasl\n",
+      "rsnuobrfcarbnrdrcdrt nane as sud nmrg no bott lubac cagr hl law tan rft no at best do pp us rfc ak\n",
+      "docs not do mftawgrbecsarfdrt san amr mad pr ftd oct lubac cags in aftrkemgnenoatnrvdrt nad oct do\n",
+      "ppusotgerlgluobfbafw no at be do crt at rppebalhupegrddatsse ftse rrftconoatsruqrftg nes dodd of\n",
+      "neadeiluhtrlfpmepsr not s gel irm of teter dft dr gnu rhllaweagnaotsrtuod in aged tdu on rft rlp on\n",
+      "at net snob rket gnet be yr ftc agnes ne motto rf trie in rots krr stars ubxrrftsesaftrketlla we as\n",
+      "sudteftksadesardrftr podur cos rad rllrbnefbrftnariedtu ogrsuebsefskdutrftyh no ass rd pp us let udh\n",
+      "stag nee a dei luhn a in as ad pula d per ft\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(keyword_decipher(sanitise(cb), key_b, wrap_b)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'dpcbzxnyromwiahsugjklvtfeq'"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cipher_alphabet, score = simulated_annealing_break(cb, fitness=Pbigrams)\n",
+    "cipher_alphabet"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'sthikros lakam hge rue oy tsuf ta ichowi hi lerthem et gen sgehv ohebhi pa chi omakros lakam ont etha brauxho pe heassaffem san coculmhem blthomor sin on raipbild heriy ferp omakci rep vsi et hild a sant he chi heasuphem ges et oy tsuf bwotirts rue sbigli si ofemtue ont omhoulpha et hild i cooh a chi sasarm ont et oshedsor ont ohafrotoc et hees tcitsnmaor ha whatoof oy llag sbekho srerodfo ontblluporim ciort tsuf og chi oderuo hrontreh ha omhoulpha sta pe ntciory ont hokaw oradfo ont et tiornt frot rowhel i thosord bif plosta ouwiol ont chin ronte ont heheasak briheashidjo siassur ha haor et fan he blor him og vhant a es owithikci san et teh sa iassur colcaryhu hi tint comhakhem oy et cooh teh llag on chi rig rontrup caeki et chi heawor ont ha roged pe omhiliy i haithaif et hoov blrilumatrid sa vmrifsayosuim rue et srerodfo oornt ont pe ouwiol ont owiwho et olyassed oy bif ta stnwalteep ont pe orilw ont ferp bigi bild ont tmorac et chi sretmi ont omhoulpha et brt et heatormsac ntag coomerd et su gelli bif sant thocurd tob chi cowiwho blliref ofat ofis ont ti oradfo ont pe somip egt ont clreg ont et sotirtshefoc ssord ont chi thofialrid ha cotmuchem otudsac raont btahutredde hi sthosord aloirsac chi ohetscilw hoogtoy thofoorwisac malyud ont tint vhant a heatmolpor he tuy sfai rue tueyi heasuphem et ciol cluem sant tint ourt sa ta chi smatmit re bwotirts bmaled he oorwi et olyihu ori srociol limataled rue tint otihutrephu rioddi bif ta cieryi chi ofen ti suellim chi viog wharioddi vsar on hont heatmiha sloshuem on pa omhoroprotha hiassur hfochem et tlumappac oy llag ta hont heatmi streddus on pa vrep shetref ntag comip sa on rotsahaf ofard ont rep tlumappac swhant ovif chi heathokrotha rep treddus et ciol cluem nmang heatmi rep otatoddi malyud i corrats sin tsio ont pe heatsoux ont chi srerren hiariwluy tolndfid sohetscilw ofen titiornt rochu oy llag iacha et sotuer whacirt rue hont oldehathitshem ovit chi tmi bont pa chi shifette ont owiwho et svoos ta osumjo ont si sant ovit llag iassur tint vsar i sa oront oderuo pe soarollomhinm ont ha owirtue cosuim sin svrut ont by heassorddus litury sta chi iariwluy ha whasardu lardi ont\\n'"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# cipher_alphabet = 'cpearstubomykvliqghjdxnwzf'\n",
+    "cipher_translation = ''.maketrans(cipher_alphabet, string.ascii_lowercase)\n",
+    "plaintext = cb.lower().translate(cipher_translation)\n",
+    "plaintext"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'dwwwwtdvwwgvzwvgwww'"
+      ]
+     },
+     "execution_count": 19,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score_b = vigenere_frequency_break(cb)\n",
+    "key_b"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'GOCVQNEO AXREM SRD DPD LL PNPR LH LGCLQV CV TEKOSEJ EE RDX NRDFS LCTUZV MH GVV LMKJLLN BEQIC LEH DOCK UKHFKZL MD CWHNNHEUEM DIB HBGPAFCDM WTPCLCMH OLE LX KHVZMWAF DAKWY BDDW LMKJHV AET ADV DH CVAI I NXFL DT GCO CDHQIXCDC ODO DO EI ONSU TXBPSKPD KPW NTVUTW NL IBECOPD LEO OFDLPQXZH TO COAF V ZMLC I GDL NHGHKM OXP DE INDTFNLD LEO EDHBAMLLH DO VDDN RZWONUNELL CH QCHOLOU LI BXHS NTDJCL NNWLLFRM LFETAAIWLKVP HVLAP OOFB LK GCV EGDKFM CLBEOKWC CH ENCLFBTCI NOH WD ERZWLKY IEP CLQAX LKKYCL BFL EE OVEKEO EDMO AMUCEQ V HCLNLNY TVR TAMDOH EPXVLD MEO HZVF KLEHD LER DDCTIKHR TKVVDHNCYYTL DWENOFK CA CHLN EO RIB DT TAEK CVP MR PDEEP H DG LXVRVWQGL KHF DO HDC NK WHNDQH HBAGHDICP FO OVUP GMCCHQVDM LL EO WMIC EDC TAHR OX GCL HVS KLEHKPW JAEQV EL HSV CWHXLK EFO SI KMHDF PD LMFOBVI W CILOCHOB DO VMLZ UXKWQPMHHKVF QA ZMAWYNIYLNPOM KPG EO DLAKMVBL ELKEO EFO ME LQNVLA LEO OQWXCB AO BAIHGNDF OB TVR LH DOEXAAODDZ MEO XA MAVAX LEO EWLW JWOV JVAF LEO RFMKHW AO WCV GKDOMY MEO MJCMFAWCA DO WDP DE ZDIELKMGHG ERAS GBMJDLV DO NP RGTBV JWY OXEO HCLGPNY OLJ DCW GLXOXCL WTBVKTC LCXO LUVN LHH OV MHHGRL LXO WD GMMVM ARP LEO GAKDU MEO EL OBOVKHNCDBOZ NNBLC MUO GVV OCOUWHAAWC DX GLHMPGCGF LOFGKHH KHLXO TOKVQOKTGCD SV NHCLNLNY HABWHNIW GCO LCDRGHVAN ZLMHOLI OCLBOELXVDID NXAIPY LEO HWEO AZHFE H VDHOMOTXLK DA PFI NUHV KSW OPTJS DTHNPPCDM GH GVBB GBFDM GHEO ROFO BQHO DH OA GCV GNHOCWL LT TXEOVKOQ UMHQEC DT LLDXV DR MAILDM MAV NDLGVLD BVMXPEAEV KPW OVER MOVSQLKEMCP DVLFFY UVB PE HLDKIO GCV ECDE PS OFDAAOM GCY AVLH UCIAVLFYV ZNKD LE DIEP CDHHMVCH GBLNSQAM BE WA LMCODMWKBPZH SVHNGPK CEEHCDC AO EAPMAWWHG EJ AQIO PX CLXO CDKHNV DPHDGVPN EE WH SLDW OZDPADB XOHR JENVW OE MU KLHNHCHE MBHAG LFE KDP OAPPAXWHW KXDXEO EZVB JVW CTILCMGKLOVH KDZ PKDVGMN TO GOLA GDIEM UNEES CDHHMV KGP LOXPIFGL MHTIPF Y HLKAILN DVE HNVL OXP WT ZDIENLPC LEO ZDV DLAKLTE COHKVXDIJ OBBBFCLF NECDONJOBX BCAE EVOVEKEO NEHCP MF BQHR OHGCH WP NBPMDL XCHZVKO NIE CBFL MQFDCAOCVOQVEM BASO WCV HMV TOXP WX DCW NCVUDOOD EFO BYSXDB DO NZLLQ PH BOMMTB LEH NV QAFO BASO QAHR VHNNSD OVUP ZOXK V NH LNEFO BGAKQB WD NLHKOTBLMSWBM BEO VH LXYDPPD HINQLM NOE NZNIP LUP TJ CDHGNLKFIIO ALPMKJ NOH GCV YALVXQQF DX XCANHKFS BHKVW LFE\\n'"
+      ]
+     },
+     "execution_count": 20,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "vigenere_decipher(cb, key_b)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:459: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n",
+      "  \"matplotlib is currently using a non-GUI backend, \"\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAbAAAAEmCAYAAAADccV0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAFUpJREFUeJzt3X+wZGV95/H3RyCJggkgV0KQ8YqZuKvJOsiVxTWkiGiCoEF3DYGogDE7soFSd2O2QDer5caqSdRYm9oNZohT4IYQMIiwglFqdEVUIjPDAMMvAR2WoUYYIcsPSVDgu3/0mdgzXLjdt7tn5qHfr6que87T5+nn2/dHf+5z7unnpqqQJKk1z9rZBUiStBgGmCSpSQaYJKlJBpgkqUkGmCSpSQaYJKlJBpgkqUkGmCSpSQaYJKlJBpgkqUm77+wCAPbbb7+anZ3d2WVIknYBa9eu/X5VzSx03C4RYLOzs6xZs2ZnlyFJ2gUkuXOQ4zyFKElqkgEmSWqSASZJapIBJklqkgEmSWqSASZJapIBJklqkgEmSWqSASZJapIBJklq0i6xlJQkadc0e8ZlAx+7ccWxE6zkyZyBSZKaZIBJkppkgEmSmmSASZKaZIBJkppkgEmSmmSASZKaZIBJkppkgEmSmrRggCU5KMlXktyU5MYk7+na901yRZLbuo/7dO1J8mdJbk9yfZJXTPpJSJKmzyAzsMeA36+qlwKHA6cleSlwBrC6qpYCq7t9gNcDS7vbcuCssVctSZp6CwZYVW2uqnXd9kPAzcCBwHHAud1h5wJv6raPAz5dPVcDeyc5YOyVS5Km2lB/A0syCxwC/D2wf1Vt7u76HrB/t30gcFdft01dmyRJYzNwgCXZC7gIeG9VPdh/X1UVUMMMnGR5kjVJ1mzZsmWYrpIkDRZgSfagF17nVdVnu+Z7tp4a7D7e27XfDRzU1/0FXds2qmplVc1V1dzMzMxi65ckTalBrkIM8Cng5qr60767LgVO7rZPBi7paz+puxrxcOCBvlONkiSNxSD/0PLVwNuBG5Ks79reD6wALkzyTuBO4PjuvsuBY4DbgUeAd4y1YkmSGCDAquoqIE9x91HzHF/AaSPWJUnS03IlDklSkwwwSVKTDDBJUpMMMElSkwwwSVKTDDBJUpMMMElSkwwwSVKTDDBJUpMMMElSkwwwSVKTBlnMV5LUsNkzLhvq+I0rjp1QJePlDEyS1CQDTJLUJANMktQkA0yS1CQDTJLUJANMktQkA0yS1CQDTJLUpAUDLMmqJPcm2dDXdkGS9d1tY5L1Xftskn/su++TkyxekjS9BlmJ4xzgfwCf3tpQVb+1dTvJx4EH+o6/o6qWjatASZLms2CAVdWVSWbnuy9JgOOB14y3LEmSnt6ofwM7Arinqm7ra3tRkmuTfDXJESM+viRJ8xp1Md8TgfP79jcDS6rqviSHAp9L8rKqenD7jkmWA8sBlixZMmIZkqRps+gZWJLdgX8LXLC1raoerar7uu21wB3AL8zXv6pWVtVcVc3NzMwstgxJ0pQa5RTia4FbqmrT1oYkM0l267YPBpYC3xmtREmSnmyQy+jPB74JvCTJpiTv7O46gW1PHwL8CnB9d1n93wKnVtX94yxYkiQY7CrEE5+i/ZR52i4CLhq9LEmSnp4rcUiSmmSASZKaZIBJkppkgEmSmmSASZKaZIBJkppkgEmSmmSASZKaZIBJkppkgEmSmmSASZKaZIBJkppkgEmSmmSASZKaZIBJkppkgEmSmmSASZKaZIBJkppkgEmSmmSASZKatGCAJVmV5N4kG/raPpTk7iTru9sxffedmeT2JLcm+fVJFS5Jmm6DzMDOAY6ep/0TVbWsu10OkOSlwAnAy7o+f55kt3EVK0nSVgsGWFVdCdw/4OMdB/xNVT1aVd8FbgcOG6E+SZLmNcrfwE5Pcn13inGfru1A4K6+YzZ1bZIkjdViA+ws4MXAMmAz8PFhHyDJ8iRrkqzZsmXLIsuQJE2r3RfTqaru2bqd5Gzg893u3cBBfYe+oGub7zFWAisB5ubmajF1SNK0mD3jsqGO37ji2AlVsutY1AwsyQF9u28Gtl6heClwQpKfTPIiYCnwrdFKlCTpyRacgSU5HzgS2C/JJuCDwJFJlgEFbATeBVBVNya5ELgJeAw4raoen0zpkqRptmCAVdWJ8zR/6mmO/wjwkVGKkiRpIa7EIUlqkgEmSWqSASZJapIBJklqkgEmSWqSASZJapIBJklqkgEmSWrSotZClKRpNcqahK5nOF7OwCRJTXIGJmnqOBN6ZnAGJklqkgEmSWqSASZJapIBJklqkgEmSWqSASZJapIBJklqkgEmSWqSASZJatKCAZZkVZJ7k2zoa/tokluSXJ/k4iR7d+2zSf4xyfru9slJFi9Jml6DzMDOAY7eru0K4Ber6l8B3wbO7Lvvjqpa1t1OHU+ZkiRta8EAq6orgfu3a/tSVT3W7V4NvGACtUmS9JTG8Tew3wG+0Lf/oiTXJvlqkiPG8PiSJD3JSKvRJ/kA8BhwXte0GVhSVfclORT4XJKXVdWD8/RdDiwHWLJkyShlSJKm0KJnYElOAd4AvLWqCqCqHq2q+7rttcAdwC/M17+qVlbVXFXNzczMLLYMSdKUWlSAJTka+M/Ab1TVI33tM0l267YPBpYC3xlHoZIk9VvwFGKS84Ejgf2SbAI+SO+qw58ErkgCcHV3xeGvAB9O8iPgCeDUqrp/3geWJGkECwZYVZ04T/OnnuLYi4CLRi1KkqSFuBKHJKlJBpgkqUkGmCSpSQaYJKlJBpgkqUkjrcQhSTvL7BmXDXX8xhXHTqgS7SzOwCRJTTLAJElNMsAkSU0ywCRJTTLAJElNMsAkSU0ywCRJTfJ9YJJ2qmHez+V7udTPGZgkqUkGmCSpSQaYJKlJBpgkqUkGmCSpSQaYJKlJAwVYklVJ7k2yoa9t3yRXJLmt+7hP154kf5bk9iTXJ3nFpIqXJE2vQWdg5wBHb9d2BrC6qpYCq7t9gNcDS7vbcuCs0cuUJGlbAwVYVV0J3L9d83HAud32ucCb+to/XT1XA3snOWAcxUqStNUofwPbv6o2d9vfA/bvtg8E7uo7blPXJknS2IzlIo6qKqCG6ZNkeZI1SdZs2bJlHGVIkqbIKAF2z9ZTg93He7v2u4GD+o57Qde2japaWVVzVTU3MzMzQhmSpGk0SoBdCpzcbZ8MXNLXflJ3NeLhwAN9pxolSRqLgVajT3I+cCSwX5JNwAeBFcCFSd4J3Akc3x1+OXAMcDvwCPCOMdcsSdJgAVZVJz7FXUfNc2wBp41SlCRJC3ElDklSkwwwSVKTDDBJUpMMMElSkwwwSVKTDDBJUpMMMElSkwwwSVKTDDBJUpMMMElSkwwwSVKTDDBJUpMMMElSkwwwSVKTDDBJUpMMMElSkwwwSVKTDDBJUpMMMElSk3bf2QVIat/sGZcNdfzGFcdOqBJNE2dgkqQmLXoGluQlwAV9TQcD/xXYG/j3wJau/f1VdfmiK5QkaR6LDrCquhVYBpBkN+Bu4GLgHcAnqupjY6lQkqR5jOsU4lHAHVV155geT5KkpzWuADsBOL9v//Qk1ydZlWSf+TokWZ5kTZI1W7Zsme8QSZKe0sgBluQngN8APtM1nQW8mN7pxc3Ax+frV1Urq2ququZmZmZGLUOSNGXGMQN7PbCuqu4BqKp7qurxqnoCOBs4bAxjSJK0jXEE2In0nT5MckDffW8GNoxhDEmStjHSG5mT7Am8DnhXX/OfJFkGFLBxu/skSRqLkQKsqn4APG+7trePVJGkncLVNNQaV+KQJDXJAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNWmkNzJLGr9R3lDsm5E1TZyBSZKaZIBJkppkgEmSmmSASZKaZIBJkprkVYjSBHg1oDR5zsAkSU0ywCRJTTLAJElNMsAkSU0ywCRJTRr5KsQkG4GHgMeBx6pqLsm+wAXALLAROL6q/mHUsSRJ2mpcM7BfraplVTXX7Z8BrK6qpcDqbl+SpLGZ1CnE44Bzu+1zgTdNaBxJ0pQaR4AV8KUka5Ms79r2r6rN3fb3gP3HMI4kSf9sHCtx/HJV3Z3k+cAVSW7pv7OqKklt36kLu+UAS5YsGUMZkqRpMvIMrKru7j7eC1wMHAbck+QAgO7jvfP0W1lVc1U1NzMzM2oZkqQpM1KAJdkzyXO3bgO/BmwALgVO7g47GbhklHEkSdreqKcQ9wcuTrL1sf66qv4uyTXAhUneCdwJHD/iOJIkbWOkAKuq7wAvn6f9PuCoUR5b2hUMs6q8K8pLO5YrcUiSmmSASZKaZIBJkppkgEmSmmSASZKaZIBJkppkgEmSmmSASZKaZIBJkpo0jtXopYkbZkUM2HZVjFH6Stp1OQOTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1yZU4tMO4IoakcVr0DCzJQUm+kuSmJDcmeU/X/qEkdydZ392OGV+5kiT1jDIDewz4/apal+S5wNokV3T3faKqPjZ6eZIkzW/RAVZVm4HN3fZDSW4GDhxXYZIkPZ2xXMSRZBY4BPj7run0JNcnWZVkn3GMIUlSv5Ev4kiyF3AR8N6qejDJWcB/A6r7+HHgd+bptxxYDrBkyZJRy9AO4oUYknYVIwVYkj3ohdd5VfVZgKq6p+/+s4HPz9e3qlYCKwHm5uZqlDo0HENI0jPBogMsSYBPATdX1Z/2tR/Q/X0M4M3AhtFK1HwMIUnTbpQZ2KuBtwM3JFnftb0fODHJMnqnEDcC7xqpQkmS5jHKVYhXAZnnrssXX44kSYNxKSlJUpMMMElSkwwwSVKTDDBJUpMMMElSkwwwSVKT/H9gO9kwb0j2zciS9GPOwCRJTTLAJElNMsAkSU3yb2Bj4MK6krTjOQOTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1aWIBluToJLcmuT3JGZMaR5I0nSaylFSS3YD/CbwO2ARck+TSqrppEuNtNcqSTi4HJUltmdQM7DDg9qr6TlX9EPgb4LgJjSVJmkKTCrADgbv69jd1bZIkjUWqavwPmrwFOLqqfrfbfzvwr6vq9L5jlgPLu92XALeOvZAf2w/4fkN9W6t32vq2Vu+09W2t3mnsu5AXVtXMgkdV1dhvwKuAL/btnwmcOYmxBqxnTUt9W6t32vq2Vu+09W2t3mnsO67bpE4hXgMsTfKiJD8BnABcOqGxJElTaCJXIVbVY0lOB74I7AasqqobJzGWJGk6Tew/MlfV5cDlk3r8Ia1srG9r9U5b39bqnba+rdU7jX3HYiIXcUiSNGkuJSVJatIzPsCSvDvJzUnO29m1aFtJ9k7yezu7jkElmU2yYcTH+MYIfR8eZezWjPK5alGSDyV53w4aa1Hfy+P4GRinZ3yAAb8HvK6q3rqzC9GT7E3v6zM1qurf7OwaWuHnajjpmYbX9H/2jH6yST4JHAx8Icl/HLLvf0qyobu9d8A+s0luSXJOkm8nOS/Ja5N8PcltSQ5boP+KJKf17Q/8G1k39s1Jzk5yY5IvJXn2IH27/m9L8q0k65P8Rbee5aDj3tI915uT/G2S5ww47Argxd2YHx2i1lcmuT7JTyXZs3u+vzhE/z2TXJbkuu7r+1uD9gV2X+Rz3Tr2Dp9FJTmp+3xdl+R/DXD8HyR5d7f9iSRf7rZfM+iZjCSfS7K2+9osX7jHvI8x9OcqyR92i4hfleT8IX5+Tu2+D9cn+W6SrwzY78P9rw9JPpLkPUPU+4HuteIqegs6DKX7+bs1yaeBDcBBi3iMg5Ncm+SVA3bZbbGvM2O3s9+INukbsBHYb8g+hwI3AHsCewE3AocM0G8WeAz4JXq/HKwFVgGhtxbk5xbofwjw1b79m4CDBqx569jLuv0LgbcN2PdfAv8b2KPb/3PgpCHGLeDV3f4q4H1D9N2wyK/rHwEfo7do9FBvkgf+HXB23/7PTPq59j3GwyN8Lw/dF3gZ8O2tPwPAvgP0ORz4TLf9NeBbwB7AB4F3DTjuvt3HZ9N7YX3epJ8v8EpgPfBTwHOB2xbx9dmje85vHOJ7Yl23/SzgjkGfa9/rzHOAnwZuX0S9s8ATwOGL6LeBXmheC7x8iH6Lep2ZxO0ZPQMbwS8DF1fVD6rqYeCzwBED9v1uVd1QVU/QC77V1ftK30Dvi/+Uqupa4PlJfi7Jy4F/qKq7nq7PPGOv77bXLjRen6Po/TBdk2R9t3/wEOPeVVVf77b/it7nb9I+TO+/HcwBfzJk3xuA1yX54yRHVNUDQ/TdGc91FK+hF0bfB6iq+wfosxY4NMlPA48C36T3eT6C3ov7IN6d5DrganqzgqXDFr4IrwYuqap/qqqH6P1SNqz/Dny5qgbqW1UbgfuSHAL8GnBtVd034FhH0HudeaSqHmTxiz3cWVVXL6LfDHAJ8Naqum6Ifot9nRm7ib0PbIo92rf9RN/+Ewz2+f4M8BbgZ4ELRhj7cXq//Q4iwLlVdeaQ4221/XsxdsR7M55Hb3a8B73fuH8waMeq+naSVwDHAH+UZHVVfXjQ7gvsN6+qfpTku8ApwDeA64FfBX4euHmh/kmOBF4LvKqqHknyf+h9jXZpSU4BXgicvsCh2/tLep+rn6U3K9/RBv7e384DwP+l90vYMP/qarGvM2PnDGx+XwPelOQ5SfYE3szgv3mO6gJ6S2+9hV6Y7QirgbckeT5Akn2TvHCI/kuSvKrb/m3gqgH7PUTvVM9i/AXwh8B5wB8P0zHJzwGPVNVfAR8FXjFE98U+153ly8BvJnke9L62A/b7GvA+4Mpu+1R6s4tBAvtn6J09eCTJv6B3SnJH+Drwxu5vo3sBbxi0Y5JD6T3ft3VnT4ZxMXA0vVOYXxyi35X0XmeeneS5wBuHHHdUP6T32nZSkt/ewWOPhTOweVTVuiTn0Dv3D/CX3em9HTH2jd03891VtXkHjXlTkv8CfCm9q5h+BJwG3DngQ9wKnJZkFb3f5M4acNz7ugtcNgBfqKo/GKRfkpOAH1XVX3cXm3wjyWuq6ssD1vtLwEeTPEHvuf6HAfvBIp/rztJ9P30E+GqSx+n9veOUAbp+DfgA8M2q+kGSf2LwX+L+Djg1yc30Pl+LOb0FQ85uq+qaJJfSmzHeQ+9U8aCnh08H9gW+kgR6C9X+7oDj/rC76OP/VdXjQ9S7LskFwHXAvfTWkN2huq/tG4ArkjxcVU2tWetKHBpJklng81U18FWA0kK6GeO6qhrmTABJ9qqqh7urQ68EllfVuokU+eMxnwWsA36zqm6b5FjalqcQJe1SulO836R3lemwVnYXIq0DLtoB4fVSelcPrja8djxnYJKkJjkDkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNen/A9pBMTeu+d9jAAAAAElFTkSuQmCC\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fc = collections.Counter(sanitise(cb))\n",
+    "plot_frequency_histogram(fc, sort_key=fc.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 54,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'JHGMRYKJ IDMDW ZNY ZLG EH XLJK DK RTHYCR RY IZYKGZW KZ AZN VYZNJ RYPZYH DS RYC JHGMDIH IDMDW KAH DYKZ HYFLDGP ZS IZXXDJJDZY ADJ IZYIWLCHC GHIHYKWP ARJ AH BWRPSRDG ERGZY SGZX RCMDIH SZG RJV KZ BWRY D KADJ ZY RYC IZYSLJDZY JZN KZ EH XLJK JKGRKHTP ZLG RWNRPJ RJ ZLKIZXH KAH DYSWLHYIH KZ BWRY R YHHC D RYC IGDJDJ KAH KZ GHJBZYJH KAH CHKHGXDYH KZ JZZY GHDIAJKRCK DY XHHKDYT EH NDWW HYMZPJ HXBHGZGJ IRGHSLWWPKAH KGHRC XLJK NH RYC HLGZBH YZGKAHGY DY DYSWLHYIH DKJ ZS EGHRCKA KAH TDMHY HXBDGH KAH KZ KAGHRK KHGX WZYTHG R BGHJHYK XRP DKJHWS WHRTLH KAH ARYC ZKAHG KAH MDJDZYZY HOBRYJDZYRGP GLJJDRJ DY GHDY KZ ADX ZY GHWP IRY NH KADYV D JZ RCMRYKRTH ADJ KZ YZK DJ GLJJDR LYEGDCWHC RY KARK IZYMDYIHC EH KZ YHHC YZK NDWW AH RYC NRG SLGKAHG RMZDC KZ RYC GHTDZY KAH DY BZNHG ZS ERWRYIH R XRDYKRDY KZ VHHY BRGKDILWRGWP DJ IRLJHEDJXRGIV ZLG KZ HXBHGZGJ KAGHH KAH ZS WHRTLH KAH HYTRTH KZ BZJJDEWH EH XRP DK SZZKWDTAKJ KAH ZS TWRGH KAH SGZX RNRP BWRP KAH CDGHIK KZ RYC RIKZGJ KAH DYSWLHYIH KZ KGP KZ CDJIGHKDZY NDKA BGZIHHC KZ LJ RWWZN XRP KADJ BGLCHYK PHK RYC HYTRTHC XZGRWWP KDXH JRXH KAH RK HXBDGH KAH ZS SRIHJ KNZ KAH NZGWC KAH KZ CHXZYJKGRKHJ BGHJJ KAH RYC BRGWDRXHYK DY IZYCLIKHC CDJBLKH KAHDG ZBBZGKLYDKP RY BGHJHYKJ CDJGRHWD RYC TWRCJKZYH EHKNHHY CDJRTGHHXHYK BLEWDI KAH KARK KADYV D GHSWHIKDZY ZY ELK RDXJ ZLG REZLK IZYSLJDZY KZ WHRC IZLWC KADJ KARK KGLH DJ DK RYC KRIKDIJ ZG JKGRKHTP BZWDIP ZY RTGHH KZ LYREWH RGH WHRCHGJ BZWDKDIRW ZLG KARK LYSZGKLYRKH RBBHRG XRP DK REGZRC RYC AZXH RK IRWWZLJ RYC NHRV RBBHRGDYT GDJV AH KAHY DYRIKDZY IZLYJHWJ AH DS DYKHGSHGHYIH GLJJDRY IZYCHXY KZ CDSSDILWK EH NDWW DK KAHY RIKDZY JLBBZGKJ AH DS SZGV XZGKZYJ NDKA SRIHC DJ AH XDYDJKHG BGDXH KAH SZG CDSSDILWK KADYTJ XRVH RYC DYKHGMHYKDZY SZG JLBBZGK KZ WHRC IZLWC NADIA RIKDZY SZG RBBHKDKH BLEWDI R JKDGGHC ARJ HRJK KAH ZS FLHJKDZY KAH RYC AZGGZGJ ELWTRGDRY BRXBAWHK TWRCJKZYHJ AZXH KAGHRKRK LYCHG EH NDWW DYCDR KZ GZLKHJ KGRCDYT ZLG KAHY IZYJKRYKDYZBWH KRVH RYC RIK KAHP DS RYC ZKKZXRYJ KAH HYTRTH KZ JHHVJ DK HOILJH KAH RJ KADJ KRVH NDWW GLJJDR KARK GDJV R DJ KAHGH HLGZBH ZS IARYIHWWHGDHJ KAH DY ZLKGRTH IRLJHC ARJ KLGVJ KAH EP JLBBGHJJDZY EGLKRW DKJ RYC ELWTRGDR DY LBGDJDYT RBGDW KAH'"
+      ]
+     },
+     "execution_count": 54,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cb_rev_word = wcat(cat(reversed(w)) for w in cb.split())\n",
+    "cb_rev_word"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 56,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "True"
+      ]
+     },
+     "execution_count": 56,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(sanitise(cb)) == len(sanitise(cb_rev_word))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('disgrace', <KeywordWrapAlphabet.from_largest: 3>, -2302.6027304969257)"
+      ]
+     },
+     "execution_count": 35,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(key_b, wrap_b), score_b = keyword_break_mp(sanitise(cb_rev_word))\n",
+    "key_b, wrap_b, score_b"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 38,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'srdvents baval own oud hr must at eirnge en bontdol to fow knows enyonr ac eng srdvabr baval tfr anto rnquady oc bommassaon fas bonblugrg drbrntly fes fr pleycead hedon cdom egvabr cod esk to plen a tfas on eng boncusaon sow to hr must stdetriy oud elweys es outbomr tfr anclurnbr to plen e nrrg a eng bdasas tfr to drsponsr tfr grtrdmanr to soon drabfstegt an mrrtani hr wall rnvoys rmprdods bedrcullytfr tdreg must wr eng rudopr nodtfrdn an anclurnbr ats oc hdregtf tfr iavrn rmpadr tfr to tfdret trdm lonird e pdrsrnt mey atsrlc lreiur tfr feng otfrd tfr vasaonon rxpensaonedy dussaes an dran to fam on drly ben wr tfank a so egventeir fas to not as dussae unhdaglrg en tfet bonvanbrg hr to nrrg not wall fr eng wed cudtfrd evoag to eng driaon tfr an powrd oc helenbr e meantean to krrn pedtabuledly as beusrhasmedbk oud to rmprdods tfdrr tfr oc lreiur tfr rnieir to possahlr hr mey at cootlaifts tfr oc iledr tfr cdom ewey pley tfr gadrbt to eng ebtods tfr anclurnbr to tdy to gasbdrtaon watf pdobrrg to us ellow mey tfas pdugrnt yrt eng rnieirg modelly tamr semr tfr et rmpadr tfr oc cebrs two tfr wodlg tfr to grmonstdetrs pdrss tfr eng pedlaemrnt an bongubtrg gasputr tfrad oppodtunaty en pdrsrnts gasderla eng ilegstonr hrtwrrn gaseidrrmrnt puhlab tfr tfet tfank a drclrbtaon on hut eams oud ehout boncusaon to lreg boulg tfas tfet tdur as at eng tebtabs od stdetriy polaby on eidrr to unehlr edr lregrds polatabel oud tfet uncodtunetr eppred mey at ehdoeg eng fomr et bellous eng wrek eppredani dask fr tfrn anebtaon bounsrls fr ac antrdcrdrnbr dussaen bongrmn to gaccabult hr wall at tfrn ebtaon suppodts fr ac codk modtons watf cebrg as fr manastrd pdamr tfr cod gaccabult tfanis mekr eng antrdvrntaon cod suppodt to lreg boulg wfabf ebtaon cod epprtatr puhlab e staddrg fes rest tfr oc qurstaon tfr eng foddods huliedaen pempflrt ilegstonrs fomr tfdretet ungrd hr wall angae to doutrs tdegani oud tfrn bonstentanoplr tekr eng ebt tfry ac eng ottomens tfr rnieir to srrks at rxbusr tfr es tfas tekr wall dussae tfet dask e as tfrdr rudopr oc bfenbrllrdars tfr an outdeir beusrg fes tudks tfr hy suppdrssaon hdutel ats eng huliedae an updasani epdal tfr'"
+      ]
+     },
+     "execution_count": 38,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "keyword_decipher(cb_rev_word, key_b, wrap_b)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 57,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'reichstaduvwxyzbfgjklmnopq'"
+      ]
+     },
+     "execution_count": 57,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cipher_alphabet, score = simulated_annealing_break(cb_rev_word, fitness=Ptrigrams)\n",
+    "cipher_alphabet"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 60,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'reichstaduvwxyzbfgjklmnopq'"
+      ]
+     },
+     "execution_count": 60,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cipher_alphabet, score = simulated_annealing_break(cat(list(reversed(cb))), fitness=Ptrigrams)\n",
+    "cipher_alphabet"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 61,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'reichstaduvwxyzbfgjklmnopq'"
+      ]
+     },
+     "execution_count": 61,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "keyword_cipher_alphabet_of('reichstadt', KeywordWrapAlphabet.from_largest)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 48,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "the april uprising in bulgaria and its brutal suppression by the turks has caused outrage in the\n",
+      "chancelleries of europe there is a risk that russia will take this as the excuse it seeks to engage\n",
+      "the ottomans and if they act and take constantinople then our trading routes to india will be under\n",
+      "threatat home gladstones pamphlet bulgarian horrors and the question of the east has stirred a\n",
+      "public appetite for action which could lead to support for intervention and make things difficult\n",
+      "for the prime minister he is faced with mortons fork if he supports action then it will be difficult\n",
+      "to condemn russian interference if he counsels inaction then he risk appearing weak and callous at\n",
+      "home and abroad it may appear unfortunate that our political leaders are unable to agree on policy\n",
+      "strategy or tactics and it is true that this could lead to confusion about our aims but on\n",
+      "reflection i think that the public disagreement between gladstone and disraeli presents an\n",
+      "opportunity their dispute conducted in parliament and the press demonstrates to the world the two\n",
+      "faces of the empire at the same time morally engaged and yet prudent this may allow us to proceed\n",
+      "with discretion to try to influence the actors and to direct the play away from the glare of the\n",
+      "footlights it may be possible to engage the league of the three emperors to our causebismarck is\n",
+      "particularly keen to maintain a balance of power in the region and to avoid further war and he will\n",
+      "not need to be convinced that an unbridled russia is not to his advantage so i think we can rely on\n",
+      "him to rein in russias expansionary visionon the other hand the league itself may present a longer\n",
+      "term threat to the empire given the breadth of its influence in northern europe and we must tread\n",
+      "carefullythe emperors envoys will be meeting in reichstadt soon to determine the response to the\n",
+      "crisis and i need a plan to influence the outcome as always our strategy must be to sow confusion\n",
+      "and on this i plan to ask for advice from baron playfair he has recently concluded his commission of\n",
+      "enquiry into the civil service and if anyone knows how to control an agenda it must be our own civil\n",
+      "servants\n"
+     ]
+    }
+   ],
+   "source": [
+    "# cipher_alphabet = 'reichstadqvwxyzbfgjklmnopu'\n",
+    "cipher_translation = ''.maketrans(cipher_alphabet, string.ascii_lowercase)\n",
+    "plaintext = cb_rev_word.lower().translate(cipher_translation)\n",
+    "plaintext_words = plaintext.split()\n",
+    "print(lcat(tpack(list(reversed(plaintext_words)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 48,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "the april uprising in bulgaria and its brutal suppression by the turks has caused outrage in the\n",
+      "chancelleries of europe there is a risk that russia will take this as the excuse it seeks to engage\n",
+      "the ottomans and if they act and take constantinople then our trading routes to india will be under\n",
+      "threatat home gladstones pamphlet bulgarian horrors and the question of the east has stirred a\n",
+      "public appetite for action which could lead to support for intervention and make things difficult\n",
+      "for the prime minister he is faced with mortons fork if he supports action then it will be difficult\n",
+      "to condemn russian interference if he counsels inaction then he risk appearing weak and callous at\n",
+      "home and abroad it may appear unfortunate that our political leaders are unable to agree on policy\n",
+      "strategy or tactics and it is true that this could lead to confusion about our aims but on\n",
+      "reflection i think that the public disagreement between gladstone and disraeli presents an\n",
+      "opportunity their dispute conducted in parliament and the press demonstrates to the world the two\n",
+      "faces of the empire at the same time morally engaged and yet prudent this may allow us to proceed\n",
+      "with discretion to try to influence the actors and to direct the play away from the glare of the\n",
+      "footlights it may be possible to engage the league of the three emperors to our causebismarck is\n",
+      "particularly keen to maintain a balance of power in the region and to avoid further war and he will\n",
+      "not need to be convinced that an unbridled russia is not to his advantage so i think we can rely on\n",
+      "him to rein in russias expansionary visionon the other hand the league itself may present a longer\n",
+      "term threat to the empire given the breadth of its influence in northern europe and we must tread\n",
+      "carefullythe emperors envoys will be meeting in reichstadt soon to determine the response to the\n",
+      "crisis and i need a plan to influence the outcome as always our strategy must be to sow confusion\n",
+      "and on this i plan to ask for advice from baron playfair he has recently concluded his commission of\n",
+      "enquiry into the civil service and if anyone knows how to control an agenda it must be our own civil\n",
+      "servants\n"
+     ]
+    }
+   ],
+   "source": [
+    "# cipher_alphabet = 'reichstadqvwxyzbfgjklmnopu'\n",
+    "cipher_translation = ''.maketrans(cipher_alphabet, string.ascii_lowercase)\n",
+    "plaintext = cb_rev_word.lower().translate(cipher_translation)\n",
+    "plaintext_words = plaintext.split()\n",
+    "print(lcat(tpack(list(reversed(plaintext_words)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 64,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "the april uprising in bulgaria and its brutal suppression by the turks has caused outrage in the\n",
+      "chancelleries of europe there is a risk that russia will take this as the excuse it seeks to engage\n",
+      "the ottomans and if they act and take constantinople then our trading routes to india will be under\n",
+      "threatat home gladstones pamphlet bulgarian horrors and the question of the east has stirred a\n",
+      "public appetite for action which could lead to support for intervention and make things difficult\n",
+      "for the prime minister he is faced with mortons fork if he supports action then it will be difficult\n",
+      "to condemn russian interference if he counsels inaction then he risk appearing weak and callous at\n",
+      "home and abroad it may appear unfortunate that our political leaders are unable to agree on policy\n",
+      "strategy or tactics and it is true that this could lead to confusion about our aims but on\n",
+      "reflection i think that the public disagreement between gladstone and disraeli presents an\n",
+      "opportunity their dispute conducted in parliament and the press demonstrates to the world the two\n",
+      "faces of the empire at the same time morally engaged and yet prudent this may allow us to proceed\n",
+      "with discretion to try to influence the actors and to direct the play away from the glare of the\n",
+      "footlights it may be possible to engage the league of the three emperors to our causebismarck is\n",
+      "particularly keen to maintain a balance of power in the region and to avoid further war and he will\n",
+      "not need to be convinced that an unbridled russia is not to his advantage so i think we can rely on\n",
+      "him to rein in russias expansionary visionon the other hand the league itself may present a longer\n",
+      "term threat to the empire given the breadth of its influence in northern europe and we must tread\n",
+      "carefullythe emperors envoys will be meeting in reichstadt soon to determine the response to the\n",
+      "crisis and i need a plan to influence the outcome as always our strategy must be to sow confusion\n",
+      "and on this i plan to ask for advice from baron playfair he has recently concluded his commission of\n",
+      "enquiry into the civil service and if anyone knows how to control an agenda it must be our own civil\n",
+      "servants\n"
+     ]
+    }
+   ],
+   "source": [
+    "cb_rev = cat(list(reversed(cb))).strip()\n",
+    "kpt = keyword_decipher(cb_rev, 'reichstadt', KeywordWrapAlphabet.from_largest)\n",
+    "print(lcat(tpack(kpt.split())))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 65,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2163"
+      ]
+     },
+     "execution_count": 65,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('5b.plaintext', 'w').write(lcat(tpack(kpt.split())))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.6"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/2018/2018-challenge6.ipynb b/2018/2018-challenge6.ipynb
new file mode 100644 (file)
index 0000000..ee562bd
--- /dev/null
@@ -0,0 +1,792 @@
+{
+ "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": 25,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from cipher.caesar import *\n",
+    "from cipher.affine import *\n",
+    "from cipher.keyword_cipher import *\n",
+    "from cipher.vigenere import *\n",
+    "from cipher.playfair import *\n",
+    "from cipher.column_transposition import *\n",
+    "from support.text_prettify import *\n",
+    "from support.plot_frequency_histogram import *"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ca = open('6a.ciphertext').read()\n",
+    "cb = open('6b.ciphertext').read()\n",
+    "scb = sanitise(cb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "8197"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "history_words = [w.strip() for w in open('history-words.txt')]\n",
+    "len(history_words)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('nautilus', <KeywordWrapAlphabet.from_last: 2>, -2791.895864772198)"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(key_a, wrap_a), score_a = keyword_break_mp(ca)\n",
+    "key_a, wrap_a, score_a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "it was dark and dusty in the shadow archive but atleast i had found it the shelves marched off into\n",
+      "the gloom and most of them were empty though there was the occasional box of papers marked sa which\n",
+      "had clearly been forgotten in the move they would be interesting to read later but nothing in them\n",
+      "looked important enough to have excited my co conspirator whoever that might be it would have been\n",
+      "easy to get discouraged but i needed to recover the lidar so i carried on searching for the chimney\n",
+      "i eventually found it at the back of the stacks but there was no sign of the lidar or of any\n",
+      "disturbance to suggest it had fallen that far so i guessed it might have got caught on a ledge\n",
+      "higher up fortunately the chimney was fairly wide but not so wide that i couldnt bridge it and all\n",
+      "those hours on the climbing wall paid off as i climbed up looking for the lost machine as i\n",
+      "suspected it had caught on one of the ledges designed to catch rain so i made ready to lower it back\n",
+      "down but as i moved loose bricks to steady myself part of the inner wall collapsed and to my\n",
+      "amazement i found myself staring into a control room it was very jules verne and wouldnt have looked\n",
+      "out of place on the bridge of the nautilus it must have been cutting edge technology once all brass\n",
+      "and polished instruments there was a map on the wall covered in small bulbs that i assumed would\n",
+      "have lit up to signify activity and a bank of fine nineteenth century telegraph machines in polished\n",
+      "walnut unless i was mistaken i had found douglas blacks command centre under a large circular oak\n",
+      "table in the centre of the room there was a filing system with drawers containing maps of every\n",
+      "nation and the table could be turned like a restaurant lazy susan the walls were lined with\n",
+      "brassbound ledgers and folders marked with what looked like mission code names in amongst them was\n",
+      "the most amazing find blacks codebook it contained a number of keys and best of all a list of\n",
+      "ciphers and when and how they should be used it would be worth a fortune on the bibliophile black\n",
+      "market but i didnt feel like selling it harry might be interested if only for historical reasons but\n",
+      "if not then this would find a home in my own private collection i took a seat by the telegraph and\n",
+      "put my feet up opening the codebook at random to read as with the three emperors operation it maybe\n",
+      "necessary to enhance operational security during the operation itself in that case we moved from\n",
+      "purely letter substitution cryptograms to transposition ciphers and at the urging of baron playfair\n",
+      "other more complicated ciphers like the vi genere and playfair ciphers and variants upon them i was\n",
+      "completely immersed in what i was reading and then it hit me\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(sanitise(keyword_decipher(ca, key_a, wrap_a))))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 43,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2704"
+      ]
+     },
+     "execution_count": 43,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('6a.plaintext', 'w').write(lcat(tpack(segment(sanitise(keyword_decipher(ca, key_a, wrap_a))))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('a', -2672.4820858271923)"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score_b = vigenere_frequency_break(sanitise(cb))\n",
+    "key_b, score_b"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('a', -2672.4820858271933)"
+      ]
+     },
+     "execution_count": 23,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score_b = vigenere_frequency_break(sanitise(cat(reversed(cb))))\n",
+    "key_b, score_b"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('abd', <KeywordWrapAlphabet.from_a: 1>, -9171.241735262733)"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(key_b, wrap_b), score_b = keyword_break_mp(sanitise(cb), wordlist=history_words, fitness=Ptrigrams)\n",
+    "key_b, wrap_b, score_b"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:459: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n",
+      "  \"matplotlib is currently using a non-GUI backend, \"\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fc = collections.Counter(sanitise(cb))\n",
+    "plot_frequency_histogram(fc, sort_key=fc.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('realisation', <KeywordWrapAlphabet.from_largest: 3>, {'j': 'i'}, 'x', True),\n",
+       " -10108.573645429131)"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key, score = playfair_break_mp(cb, fitness=Ptrigrams, wordlist=history_words)\n",
+    "key, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'ulalblueoefurkekcglaireulondtunttlahrtrlurlhlolqegaemafgpysnanxtpllzqdagtgovuouavtkslafyxlleqrhsmawkakutekreksowwkmralovedsuaeibkenxesglwnfustslnueltlaskakagdsaksacaweniduarusfrbstliwpuolooglttrdeorvlnlmymahbdetsgtorpsluaggaxriqiahtruuofiaeulntzqirsosootleunfofohaltautrisrgelenwnmamlxankiseaovtfkwrilzwrrhrknwulorfifyxllenmlsauussnsmekobulzroglaldtukermtlwslaenulraylitkwnlmovknwwlrirmekirtsriklorsonmsolgtarzexoctlbrrctsksdpraoeerownrtsurtlsnvbskwlxrlakeoerasnasksrqnwlrlusinddngeaeaurbsotarkskabolrmerxhenuttsaestbesoanlctasrsoksnvkeawksdiforlelfobtovntazytkslttormstirformselrrtuaouaboladlrlhkoasolnpskowwlmeksriatwkbanctakrakeuidoscnirrkarcfawoebrrweravnslttsbmselrsmtrkoeuurrmristwebarmrcstbtakksriralxuektotcotaltocrcsmekirasrwkeoymtxtrmvwsuorlektcaotcapltsnlctxtrmrmscuoawriaswkbomxkseskenormxcirqmrtutgrekrnnmrmekoebhsksnulistagrsusorikerbsuurrcazarwrtsercrulsorilneyrisuoezfltlrkstxfalbnmagnadedmzlfodmrahneocadsdrawaftswrnarlqlteksrkekmsfpnbkbogeourulqibqnbcaliforafyxlleurahmaolbdoynoluidaglulwsatxeqzcosazmvopkvsarekrsuurqsgeoyfuawdhtlasclwkglowrwrmululksoveicincwnasrkolqderkasonctaqrrikbeouscaakeuidtlplmoaclblsmaqurtuddbehrmxsfolomoabovakwnucmarikeaklstusiruovrxulankayslteuksrdkcrnololksbaretkroeravepurksowermsvxinoncoluerdcqbeustdtsoanissasexmsaketztruenumvbfrqrprwrlanysyrakkeosulrkurgogeovotueoryebterksesexktntmbryelarowekplaomslklgndtlniftfurqseklulqlfeloroobkttaxoegcadnnetxnakspflwelldrheiekoezfmylzifsledclfptiisovristekpsiquaakhvhoirdnrkeklseuitntorlsicusfoldtdlgirlkovabiocarkowkaasnmtseslfrksaawgebofulhrzuagofuvtksrqsolrkelaarciftktawtlxaoclhlmawavndksndkeasbkaqzcsleorcktlsrtoiruolksxaatowmdkaulhfrisndysaeriboerhiclglugefteolwrkkteriadsektlisohrlomoqtdpdulunotadidslnttlaqrtkevfrkutdoswiearntrnoreseokabqvkgezeaylravlctssuermrpfynilmozqdhowtapbglgeaekttriadreklktuabioeklrpraberirksusexuentgcrfkeekirstoteceotalggldkaeulkentrbnckaekltrqzcalktawilkwrwdlfanoeamxtgdeiekedwonaoneldnecabrrutgruuosmsnirovolluiomxsumslssiideldnuldlegnriryekeclotvxenlurqndmdlhrnirotlpeoaotrnccabrrutgruuotomaofdiawavxawkbanctakrakeuudulieusibcaitaoweakktunynayultlowxoatpfuesmsnurftserllxsooerkstbpsetdulkdfdotirftrlatftuooluenktora'"
+      ]
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "playfair_decipher(cb, 'realisation', padding_replaces_repeat=True, wrap_alphabet=KeywordWrapAlphabet.from_largest)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('resurrection', <KeywordWrapAlphabet.from_a: 1>, {'j': 'i'}, 'x', True),\n",
+       " -10095.318678614976)"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key, score = playfair_break_mp(cat(reversed(cb)), fitness=Ptrigrams, wordlist=history_words)\n",
+    "key, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'dwoikntanoouauisewaurciodfsqtosavrgdiadcnaoaznewvrauoernfatamkiswfovuitomwxgselwlsarsmsrwibuortctofnatlscdsiboebruifsvswnhgiinoioueouseocfwiboresmanpiiorcemkuqoosdaotikxviosdirdlrcmeeaohtosotnhncstuafrohicnotnoxmrcrnfaoueouseocfwikihokismyuszirtcczushiqiuydiohwrurteswlweddydaiurislbofcnsirtoiqqsoddosianbrioiarcriirdkbhnstaziorabrccibeqdwericnbexslurithkerelwiqaeoddgsiovkfndoztexgmkcaciroaidssvwemwelaedzgfslanrvocemnswdtckrfmsxdcgvirerlouinsuthnfsiosetoofsapsozewfxscuiritfkecilwdcwuanauaeotdoducenabucistomrncrgktoslqoovisifabnoeoncertulwdranutdyloaztsirosabossvswqnkubiifuiswlwauudwddeirweoadaabexunegtiwtkuunefaeswstdcgurvaimntsslovdcwicnbexmlurcdosahoigordutuocnssratturidcsorcxftvlstineagriiacrxmscrskmsdzcutdpwnmynpnarictcehotnwumkabmixikisowieafwsilwfecoonqenltoulvrdaunaupeuiosdoluafsmipriovwdtnwkbgnslwzirvabcieudloctaioxmaeegoedctoaoirlskwtyimewwrdqdahufzestareyeirstihvrstscimoaasiaatfgbdciotibyuepxvafciovaboeqksvcicowlicebabnonoemlrhtabatiutyslimtoztxmeocsxstulsircrinbnnvlsxmbeozonigtxacbvshfnerwaintubsiwzoipuihnatlswioranzacradsibooaslcifpnodctsnvboudctxmabtotoacwrovodrusdtsuikfswunoyaecgoerocdicstzdpofzowaodyltxistwuotiehnotuyoyhsnoinksoentnzgmdwigetwioxgfentooeangezaoxkmafridcabivnlewmirwaiidswthtfwianumdwoqignwoqczmiiemnbsdixiabweiunpnarocrldpucroatordciairwwdowdroerofcircroarotdsisctornbacbnariacmnemritdsxerqgrcilacuyirrvabhiefrutscrswoutracacixvlupaiipwiiowilwntocrovwacixtmoyirwrtsrcrifadrbiiusiibiolwtazndwcrablseuiadracebariacracoeatokrefawevrgbaiiunrsvciwrcfnaswfbwddcrcobaohnatlscdsiboebruiscrabtquwovbapwnotsokkuwefsnobeuotierwevracigrciaacoiiuabiyownsxmeuigtnewignhabswirxuaboarxsidsimoacuiaiqaisxikkxciacnobebadcsioafcitiqaesooscsotwevndaabtsrndwnairdetzuwbaghrnuioeaimeovcinadwfoabaidrcfuibiziwtsidooamnoaoculcraircriaccruwvndzozupursrogdwtoikderkuiacirxshodegetwtoferifarnorittumnntnzgmpdoctovndccerwwncruruaxmqiscknifnqinnviktndtscreitiuskigigsentiooaoarcndnstoiqpdoueormkenetzeiieotagocsuaiczbcinmyupuvocczreiugeonoupvetiafcgteotihnikswiwabstdhslsltsuitnesutiaunnvodrvxnirbuiqrozcxmedcaruovabicrisxlsruinkvadntnzgmdeabextiouxmusiefpwnipiximrndmhfiniqealnonkuoeewerksuinsxsosonatrcdehbridcunnatasbedto'"
+      ]
+     },
+     "execution_count": 19,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "playfair_decipher(cat(reversed(cb)), 'resurrection', padding_replaces_repeat=True, wrap_alphabet=KeywordWrapAlphabet.from_a)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('resignation', <KeywordWrapAlphabet.from_largest: 3>, {'j': 'i'}, 'x', True),\n",
+       " -9896.15193568302)"
+      ]
+     },
+     "execution_count": 20,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key, score = playfair_break_mp(cb, fitness=Ptrigrams)\n",
+    "key, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'orpebiosanrugcaschepgrsonuiytiotarskrersesiknupfefcentrhpcaopayakapoqssfahmtrtipxeduepfywoeofgknntwlslitasledustwlcupemtewsmcegisaiosnypxoruatrktgoearinlslshdniduscswmaueipservgdatsgvprtnuthraerweetvivomyntgbwetahaetburosffswnogekmrserteqceorotisgrauauuteogtbtbtksrapiergnrfoemaxontloftomgnecmtablwrgpowreggcoxoreteqfywoeoifkrpimsaoufasmxoryrthepoctisaucarxnepmaorlcbogalwvotwzcoxwirgucasgrtarglietauifaupyairyeasxardgrctadudplcanelstemtaesaraohfudwiwnepsaanlcaoindugfoxsrrongiyyifecepigdauaigcudsbunucelxkmaittaceatbeaupaicaixrauduixsaswdueubtrsoebtdemtotsyvaduratuucatgrbtucnssrreiptrsbuntpsrikdsinunwpudstwilndurgiawlbsodaicgslsoueuadogrgcclhsswandgrwelsvoaratacfnssruferdssoesucrgatdabsucrcatdesldurglcowoslautxsairasxrcufasgrinrwsatvpnyaucvwsmeteolacsutcskatavolvyaucucndrtswrginwlxmtcdusnsaouucxcgrfqreitfrasmeifucasanbgudaoorgnaifrsmaurgsagdsmesrcsyclwrtaelcroraurgovcargsmanzirasrduaycmibifsfapweltopbtltlcminacsfncnswmctawraprsfpxadugcasfumkidfbthnaesorgoqzidcssgbtlcfywoeoesskntunbdtvourouesfroiwniayrpzeuasydztkcznilecgsmeszgfetvruswdkarinciwlypstrwucorordumtneirodxoingcunqsellsauodaifgrgfbnamscsslsouearkatwscibkrntgyreuidbkbucynbtnutwsbmtslxousntrgsaslkrtingsemtnworpalsnrrasoduncrlmeunundubslealteelsvkqesdustelfuvxqauoxsroeldczqsoatfaaupagnninsctnisaazerostgdzhegfqcrwrspanrwkslsauaorgceshtfemtutosetacdeeldusnealaotfckwoeclstaskatyfuilpyiyaraqbarugfnsliorfpwcnutemxlaaixtefcsyiamayapdukmiwoeocegneasanzimypoqerkewcimkaggnmtrgatasbuogipslkvdmgryigcaskrsogaotetkrrimsbtocafpygrilmtsbnocsgcstlsiniftasnokgcniswfexmruikryiphtruxedugfausrsaepclirbalaswarftsxikolswsviyduiysainbfspzerknarclakrreonseunduftiasttllsorkfrgaodynielgianegripyrofebanaiwgclaelekfnasargnmdrswttqafpdorgtuttpuerkotarspresavfgcitdtnxenclotmeetsnnalsqzzcfeyemwsrsvictasmelcukmyogstwisdkstaifdypfecelaerekcnasiltisbnoassrcqsbelgrdumseaosothckcsaasgratutnmnaaipyypdlceorsaotgdodlsasragfzepelaswgslwrwcocmouectcahweensadwuotyamocamcsdgseahsertufaogrmtunronotcsmfukrngueoeyiorcoefemgracsaciutvxmarogfiytlikmegrutaknatyerodcsdgseahserttunttbeuswsvftwlbsodaicgslsouiorenmsgicsgatydasllagtyomworarstxtiakmosufaoesbansrsowauangcatdfnsaforldihutgrbarsiabartunosomtulc'"
+      ]
+     },
+     "execution_count": 22,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "playfair_decipher(cb, 'resignation', padding_replaces_repeat=True, wrap_alphabet=KeywordWrapAlphabet.from_largest)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 36,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(3, -5512.824261230463)"
+      ]
+     },
+     "execution_count": 36,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key, score = scytale_break_mp(scb)\n",
+    "key, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 37,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'nitaeeieafueeirniagfloigusosifiiaesehthiasrtrigouirebreeainhikadsaynahouhndarsslnornnadneorbltporlncieeyslyarothsiulotntlifuyateaeorsntfiwnsoteatlsebhvltlrtteufcasnehnhvtoacneetteegnansowtohrnteosnmrtnltehrcroeigfelgtsarettestshttabcmeltwdetbteetkowsiwneonwhtneoddrtadhsbeohtrtioitrsseivtbieyesynhwrpoaynesdoedvlpteepfutnusedlyarocnigjyokninweesunnbefetvnisrtteaaeteecseiglxrnjsfkvnadetarenusaimnitesnteearstaoluiehtcnrrdrueuhiheovmnisusoslatawhvltloefnlghpicnswdcfloteisrtgigaeuueohjebrotneorgdfiesddhmootercsrvdnhhitleeeddaeoteoigabrsiadoaeprfrraefcnehaltesiucnuogueeteotausrtghwlrftelyaitefieebeodterehttoltrottiiliuhmeigeeevdnacrtnoalhsintennasrraofcrlfolnomlentsfhsinadercroeigrtducmsynedothsneythfrncneeosatnifighdlinoorsspicabtolyicsihlyaroeoetcasclgotynnsnomfhdlgibtrsneesrpoctsniiulinligetosnmnsuataatusceyshnapaonsutdvdasaeitenenwyehrtpaonovteetflatoithyaeatoiyirfiihohraamsttrlfvnsthaeicsinenteareiraiprattkteeteetnteeeaeeundroeiieodhtshraintedoervnoawsadoltkoabercshtuhrpsilptaturetnehsbleaetrlrtgitdfilmimlaebeoeeihhhlhdsigfinpasmnfuninowwthmoaticnemreftaihsgfrhmetfhratetnnefazocaoaasmtoemorsvleetaknadaaelitewudnfgtolutaewtscheivleteicstacerwudaetnhpoecntepladoddoollyartapyncpesrtnommeeeiusnsnofesaeteotnheigpouwtteiecwnorprfotcmntenushotmnbtfagsgiiayeebermxmminmnoisyhmvlostmhciiroshprabthilwraesaehdrtaibbtenkofcaeoteehlwrcfladcacutfdsusousaadhnainaseeewtifrsnloedsusoogedeteetnareoteulitxlitititathoigocicntpelrtntbrtosnmeiaploluwnmdsnwtpahvcmtatelstaeyfttraemeotetossoynuncaypracaidviksgauitniudrieiiyodpaservrtigfipitoeniifehvlnlecahyrteeetpieadhbhmtestnuteiteuhhjnoolotetdaelolotooshyetdidsuihnaodhisndoemoyhyaeodfhmatrhdehvrtohihmtarcreoeteyeoonehroenwhtaeednywahsereatenweeotsaehhnubsettiieoennnwtaeeolodcadaptbaltoiwttoscaiihdrefiiaannaderigihhrhshigenociehntaeyongmnoihtdmaeadroegrhdnrsygetrsisnovnhblahrwsrkhthyntadiotoorotsihglvlnetnhdiniwshteoliteooifunirniaseeietwhpafaeyplrflrsteuirsfhrtuaetacrpruetrprpoedniigsinelgneetperhfrhwreweantetmieuoetrinctewronueaofsoarnmebsmrelaaewileetaafigmofcasltpruilaeswudeetoaefmntsftnwieieauluaecolteicshrsiutougfiilwtnyihaproaoteicsnnarodfhmoisgeoewflntepoucraneotcmfrnenniol'"
+      ]
+     },
+     "execution_count": 37,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "scytale_decipher(scb, 3)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "history_transpositions = collections.defaultdict(list)\n",
+    "for word in history_words:\n",
+    "    history_transpositions[transpositions_of(word)] += [word]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "3618"
+      ]
+     },
+     "execution_count": 30,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(history_transpositions)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 38,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(((1, 0, 4, 3, 2), False, False), -5002.149995605427)"
+      ]
+     },
+     "execution_count": 38,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(trans_b, fillcol_b, emptycol_b), score = column_transposition_break_mp(scb, translist=history_transpositions)\n",
+    "(trans_b, fillcol_b, emptycol_b), score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 39,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'infiltratingthedeliberationsofourenemiesisaprincipalgoalbutfollowingmydiscussionswithplayfairihavecometoseethattheclassicalstrategyoftryingtoturnaseniormemberofthedelegationsisbothriskyandunnecessaryanyapproachtosuchanindividualriskssignallingourintentionsandunderminesourabilitytoadaptourplanssecrecyiseverythingasplayfairpointsoutthoseindividualsoftenhavelittleinfluenceanywaytheyaretheretopresentapointofviewandthebestofthematleasttolistenbuttheyhavelittleauthoritythejuniorofficialsontheotherhandhavealmosttotalcontrolofeventstheysettheagendaindiscussionwithoneanotherandtheirseniorsandmoreimportantlytheytaketherecordofthemeetingafterthedelegateshavereturnedtotheirhomesitisthatrecordthatbecomestherealitywedonotneedtobethereoreventoknowwhatwassaidweneedonlytoknowwhathasbeenrecordedasthetruthandwherepossibletoshapethattruthinourbestintereststhisibelievetobeanentirelynewstrategyintheworldofdiplomacyandiampleasedtobeabletodevelopitwiththehelpofsuchadistinguishedfriendplayfairisamanofcunningandienjoyworkingwithhimnowherehasthiscunningbeenmoreeffectivethaninhisstrategyforthemanagementofthereichstadtmeetingalexanderfranzjosefgorchakovandandrassymettoagreetermsonrussiasinvolvementinthebalkansandtherewasarealriskthattheywoulduniteandfighttocontrolourtraderouteswithsuchhighlevelinvolvementinthediscussionsitwasclearthatwewouldhavelittletonohopeofinfluencingtheprincipalsandsowedecidedtofollowtheplayfairstrategyapplyingcarefulpressuretothejuniormembersoftheretinuesouragentsandofficerspersuadedthemtoreportontheproceedingsprovidinguswiththeintelligenceweneededtopreparefortheforthcomingwarbetweenrussiaandtheottomanempirebutoffargreatersignificancetheywereabletoensuremaximumconfusionamongourenemiesbythemostmarvellousstratagemwhichiwillrefertoastheplayfairgambittheofficialswereabletopersuadetheirleadersthatitwouldbebetternottotakeofficialminutesofthemeetingwhilewereceivedafullandaccurateaccountofallthediscussionstherussianandaustrohungarianofficialswereleftonlywithinformalpersonalnotesofthediscussionsandnoagreedrecordofthemeetingoritsagreedoutcomeswefullyintendtoexploitthisuncertaintyattheforthcomingconferenceinconstantinople   '"
+      ]
+     },
+     "execution_count": 39,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "column_transposition_decipher(scb, trans_b, fillcolumnwise=fillcol_b, emptycolumnwise=emptycol_b)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 40,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "infiltrating the deliberations of our enemies is a principal goal but following my discussions with\n",
+      "playfair i have come to see that the classical strategy of trying to turn a senior member of the\n",
+      "delegations is both risky and unnecessary any approach to such an individual risks signalling our\n",
+      "intentions and undermines our ability to adapt our plans secrecy is everything as playfair points\n",
+      "out those individuals often have little influence anyway they are there to present a point of view\n",
+      "and the best of them atleast to listen but they have little authority the junior officials on the\n",
+      "other hand have almost total control of events they set the agenda in discussion with one another\n",
+      "and their seniors and more importantly they take the record of the meeting after the delegates have\n",
+      "returned to their homes it is that record that becomes the reality we do not need to be there or\n",
+      "even to know what was said we need only to know what has been recorded as the truth and where\n",
+      "possible to shape that truth in our best interests this i believe to bean entirely new strategy in\n",
+      "the world of diplomacy and i am pleased to be able to develop it with the help of such a\n",
+      "distinguished friend playfair is a man of cunning and i enjoy working with him nowhere has this\n",
+      "cunning been more effective than in his strategy for the management of the reich stadt meeting\n",
+      "alexander franz josef g or chak ov and andrassy met to agree terms on russias involvement in the\n",
+      "balkans and there was a real risk that they would unite and fight to control our trade routes with\n",
+      "such high level involvement in the discussions it was clear that we would have little to no hope of\n",
+      "influencing the principals and so we decided to follow the playfair strategy applying careful\n",
+      "pressure to the junior members of there tinues our agents and officers persuaded them to report on\n",
+      "the proceedings providing us with the intelligence we needed to prepare for the forthcoming war\n",
+      "between russia and the ottoman empire but of far greater significance they were able to ensure\n",
+      "maximum confusion among our enemies by the most marvellous stratagem which i will refer to as the\n",
+      "playfair gambit the officials were able to persuade their leaders that it would be better not to\n",
+      "take official minutes of the meeting while we received a full and accurate account of all the\n",
+      "discussions the russian and austro hungarian officials were left only with informal personal notes\n",
+      "of the discussions and no agreed record of the meeting or its agreed outcomes we fully intend to\n",
+      "exploit this uncertainty at the forthcoming conference in constantinople    \n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(column_transposition_decipher(scb, trans_b, fillcolumnwise=fillcol_b, emptycolumnwise=emptycol_b)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 42,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2599"
+      ]
+     },
+     "execution_count": 42,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('6b.plaintext', 'w').write(lcat(tpack(segment(column_transposition_decipher(scb, trans_b, fillcolumnwise=fillcol_b, emptycolumnwise=emptycol_b)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 44,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['called',\n",
+       " 'banning',\n",
+       " 'carroll',\n",
+       " 'banned',\n",
+       " 'cause',\n",
+       " 'newton',\n",
+       " 'bavaria',\n",
+       " 'battle',\n",
+       " 'mayun',\n",
+       " 'barrier',\n",
+       " 'baron',\n",
+       " 'damaged',\n",
+       " 'based',\n",
+       " 'fatih',\n",
+       " 'canning',\n",
+       " 'carol',\n",
+       " 'basic',\n",
+       " 'jerome',\n",
+       " 'revues',\n",
+       " 'earlier',\n",
+       " 'mission']"
+      ]
+     },
+     "execution_count": 44,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "history_transpositions[trans_b]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 45,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['baked',\n",
+       " 'baled',\n",
+       " 'bared',\n",
+       " 'barge',\n",
+       " 'baron',\n",
+       " 'based',\n",
+       " 'basic',\n",
+       " 'basie',\n",
+       " 'bated',\n",
+       " 'bathe',\n",
+       " 'baton',\n",
+       " 'baulk',\n",
+       " 'bayed',\n",
+       " 'caged',\n",
+       " 'caked',\n",
+       " 'calif',\n",
+       " 'caned',\n",
+       " 'caped',\n",
+       " 'capon',\n",
+       " 'cared',\n",
+       " 'carne',\n",
+       " 'carol',\n",
+       " 'carom',\n",
+       " 'carpi',\n",
+       " 'cased',\n",
+       " 'caulk',\n",
+       " 'cause',\n",
+       " 'caved',\n",
+       " 'cawed',\n",
+       " 'eaton',\n",
+       " 'fermi',\n",
+       " 'heron',\n",
+       " 'jason',\n",
+       " 'karol',\n",
+       " 'layup',\n",
+       " 'lexus',\n",
+       " 'mason',\n",
+       " 'mauro',\n",
+       " 'meson',\n",
+       " 'metro',\n",
+       " 'mixup',\n",
+       " 'newts',\n",
+       " 'nexts',\n",
+       " 'nexus',\n",
+       " 'onyxs',\n",
+       " 'pouts',\n",
+       " 'routs',\n",
+       " 'babied',\n",
+       " 'bagged',\n",
+       " 'balled',\n",
+       " 'banned',\n",
+       " 'barbed',\n",
+       " 'barbie',\n",
+       " 'barker',\n",
+       " 'baroda',\n",
+       " 'barred',\n",
+       " 'barrie',\n",
+       " 'barron',\n",
+       " 'bashes',\n",
+       " 'basics',\n",
+       " 'batted',\n",
+       " 'battle',\n",
+       " 'bauble',\n",
+       " 'cached',\n",
+       " 'called',\n",
+       " 'callie',\n",
+       " 'canine',\n",
+       " 'caning',\n",
+       " 'canned',\n",
+       " 'capped',\n",
+       " 'carafe',\n",
+       " 'carnal',\n",
+       " 'carpal',\n",
+       " 'carrie',\n",
+       " 'cashes',\n",
+       " 'cassie',\n",
+       " 'cattle',\n",
+       " 'causal',\n",
+       " 'causes',\n",
+       " 'cayley',\n",
+       " 'cayuga',\n",
+       " 'damage',\n",
+       " 'dandle',\n",
+       " 'dannie',\n",
+       " 'dapple',\n",
+       " 'darker',\n",
+       " 'darned',\n",
+       " 'darner',\n",
+       " 'dashed',\n",
+       " 'dashes',\n",
+       " 'dawdle',\n",
+       " 'dawned',\n",
+       " 'dazzle',\n",
+       " 'geyser',\n",
+       " 'heusen',\n",
+       " 'heuser',\n",
+       " 'jasons',\n",
+       " 'jerome',\n",
+       " 'kernel',\n",
+       " 'ketone',\n",
+       " 'lazaro',\n",
+       " 'lesson',\n",
+       " 'lexuss',\n",
+       " 'lissom',\n",
+       " 'litton',\n",
+       " 'lizzys',\n",
+       " 'maroon',\n",
+       " 'masons',\n",
+       " 'neuron',\n",
+       " 'neuter',\n",
+       " 'newton',\n",
+       " 'nexuss',\n",
+       " 'pewter',\n",
+       " 'revues',\n",
+       " 'babbled',\n",
+       " 'banning',\n",
+       " 'barnard',\n",
+       " 'barrage',\n",
+       " 'barrier',\n",
+       " 'barroom',\n",
+       " 'bassoon',\n",
+       " 'bavaria',\n",
+       " 'bazooka',\n",
+       " 'canning',\n",
+       " 'carfare',\n",
+       " 'carrier',\n",
+       " 'carroll',\n",
+       " 'cassies',\n",
+       " 'cassock',\n",
+       " 'catarrh',\n",
+       " 'dallied',\n",
+       " 'damaged',\n",
+       " 'dandled',\n",
+       " 'dappled',\n",
+       " 'dawdled',\n",
+       " 'dazzled',\n",
+       " 'earlier',\n",
+       " 'earmark',\n",
+       " 'fanning',\n",
+       " 'ganglia',\n",
+       " 'gautama',\n",
+       " 'geysers',\n",
+       " 'jejunum',\n",
+       " 'lessons',\n",
+       " 'mission',\n",
+       " 'navarro',\n",
+       " 'nexuses',\n",
+       " 'reuters',\n",
+       " 'reverts',\n",
+       " 'barbaric',\n",
+       " 'barbered',\n",
+       " 'bassoons',\n",
+       " 'carapace',\n",
+       " 'careered',\n",
+       " 'cassocks',\n",
+       " 'caucuses',\n",
+       " 'darneder',\n",
+       " 'gangling',\n",
+       " 'jiujitsu',\n",
+       " 'layaways',\n",
+       " 'missions',\n",
+       " 'jiujitsus']"
+      ]
+     },
+     "execution_count": 45,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "transpositions[trans_b]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.6"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/2018/2018-challenge7.ipynb b/2018/2018-challenge7.ipynb
new file mode 100644 (file)
index 0000000..9c41ba8
--- /dev/null
@@ -0,0 +1,579 @@
+{
+ "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.vigenere import *\n",
+    "from cipher.playfair import *\n",
+    "from cipher.column_transposition import *\n",
+    "from support.text_prettify import *\n",
+    "from support.plot_frequency_histogram import *"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ca = open('7a.ciphertext').read()\n",
+    "cb = open('7b.ciphertext').read()\n",
+    "sca = sanitise(ca)\n",
+    "scb = sanitise(cb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "8197"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "history_words = [w.strip() for w in open('history-words.txt')]\n",
+    "len(history_words)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('damager', <KeywordWrapAlphabet.from_last: 2>, -2752.7089249862242)"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(key_a, wrap_a), score_a = keyword_break_mp(sca)\n",
+    "key_a, wrap_a, score_a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('danger', <KeywordWrapAlphabet.from_last: 2>, -7448.363712420528)"
+      ]
+     },
+     "execution_count": 35,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(key_a, wrap_a), score_a = keyword_break_mp(sca, fitness=Ptrigrams)\n",
+    "key_a, wrap_a, score_a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 36,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "exactly what or who had hit me i wasnt sure but by the time i came around they had long gone if you\n",
+      "will excuse the p unit was a professional hit just the right amount of force to knock me out\n",
+      "probably no permanent damage the room had been expertly disassembled the shelves were emptied of\n",
+      "blacks mission files and much of the steampunk technology had been taken apart presumably to make\n",
+      "sure it didnt contain any further secrets the big beautiful roundtable had been cleared and ile\n",
+      "anton it to steady myself as my head swami guessed that whoever had followed me into the tunnels and\n",
+      "on into the headquarters must have known what i was looking for it was too much of a coincidence\n",
+      "that they had found me here probably they were connected with the emails that first got me\n",
+      "interested in black but in a confused state after my blackout i was puzzled why had they involved me\n",
+      "perhaps they just didnt know how to find the shadow archive and hoped i would be able to help\n",
+      "perhaps they wanted to implicate me in the theft of the shadow archive papers in that case they\n",
+      "should have hit me harder i wasnt going to hang around long enough to get caught something was\n",
+      "nagging at men one of the papers i had seen looked interesting enough to justify all this effort i\n",
+      "turned my head cautiously trying to ignore the throbbing behind m year and looked around the room\n",
+      "one more time to see what we were missing as i did so my foot caught on something and i bent down\n",
+      "topic kit up when they hit me i had been sitting reading blacks codebook it was full of marvellous\n",
+      "if dated ideas on cryptography and information security and i had just been reading the section on\n",
+      "transposition ciphers it seemed he was particularly keen on columnar transpositions and was arguing\n",
+      "that it would be best to read off the ciphertext column by column to confuse enemy crypt analysts i\n",
+      "was musing on just how secure that would be when the world went dark luckily as i had fallen i had\n",
+      "dropped the book and it had slipped under the table somehow they had missed it during the search and\n",
+      "there it was hidden in the shadows i took a deep breath to slow the spinning behind my eyes and\n",
+      "picked the book up but as i pulled myself upright again the tabletop shifted slightly to one side i\n",
+      "struggled to regain my balance and the table moved again and this time i heard a distinct click as i\n",
+      "shifted my weight the table rotated back and there it was once more a soft metallic c link as a\n",
+      "ratchet tooth engaged i stood up grabbed at the table and pulled sideways it turned again clicking\n",
+      "several times as it did so it was a noise i knew very well the tumblers on a safe made the same\n",
+      "sound though much much quieter\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(sanitise(keyword_decipher(sca, key_a, wrap_a))))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('gardens', <KeywordWrapAlphabet.from_last: 2>, -2770.1674703296317)"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(key_a, wrap_a), score_a = keyword_break_mp(sca, wordlist=history_words)\n",
+    "key_a, wrap_a, score_a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "exdftlywhdtorwhohdah it me i wds nt sure but by the time if d med roun a they hd along gone ic you\n",
+      "will ex fuse the p unit wds d procession dl hit just the right d mount oc corfe to kn of k me out\n",
+      "prob dbly no per md nent admd get he room hda been expertly a is ds semble a the shelves were emptie\n",
+      "ao cbldf ks mission ci les dna muf hoc the st edm punkte fh nology hda been tdk end pdr t pre sum\n",
+      "dbly to md ke sure it a i ant font d in d nyc urther se frets the big bed uti cul roun at dble hda\n",
+      "been fled read nailed nt on it to ste day mysel cds my he das wdm i guess eat hdt whoever hda collo\n",
+      "we a me into the tunnels dna on into the he daq udr ters must hdv e known wh dti wds looking cor it\n",
+      "wds to omufhocdfoinfiaenfet hdt they hda cou name here prob dbly they were f on nef tea with the emd\n",
+      "il sth dtc irst got me interest ea in bld fk but in df on c us east dte dc term y bld fk out i wds\n",
+      "puzzle a why hda they involve a me per hd ps they just a i ant know how to cina the shd a owd rf hiv\n",
+      "edna hope a i woul a be dble to help per hd ps they wdn tea to impl if dte me in the the c to c the\n",
+      "shdaowdrfhivepd pers in thd tfd se they shoul ahdvehitmehdraeriwds nt going to hdn gd roun along\n",
+      "enough to get fdu ght something wds nd gg in gdt men one oc the pd persi hda seen look ea\n",
+      "interesting enough to just icy dll this ec corti turn ea my he daf dut i ously trying to ignore the\n",
+      "throbbing be hina my ed rdna look ead roun a the room one more time to see w hdt we were missing\n",
+      "dsiaiasomycootfdught on something dna i bent a own top if kit up when they hit me i hda been sitting\n",
+      "red a in gb ldf ksfo a ebook it wd scull ocm drv ello us i cad tea i a edson fry p to grd phy dna\n",
+      "inc or md tions ef urity dna i hda just been red a ing these f tion on tr dns position fip her sit\n",
+      "see me a he wds pdr tiful drlykeenonfolumndrtr dns positions dna wds drg uing thd tit woul a be best\n",
+      "to red a occ the fip her text fol umn by fol um nt of on c use enemy fryptdndlystsiwdsm using on\n",
+      "just howse furet hd two ula be when the worl a went ad rklufkilydsihdacdlle nih daar op pea the book\n",
+      "dna it hd as lippe a una er the t dble somehow they hd am is sea it au ring these dr fh dna there it\n",
+      "wd shia a en in the sh dao wsi took da eep bred th to slow the spinning be hina my eyes dna p if kea\n",
+      "the book up but dsi pull ea mysel cup right dgd in the t dble tops hic tea slightly to ones iaei\n",
+      "struggle a to regd in my bdl dnf edna the t dble move a dgd in dna this time i he dr ada ist in ft\n",
+      "fl if kds is hic team y weight the tdblerotdteabdfkdna there it wds on fe more ds oct met dll iff\n",
+      "link ds dr dtf het too the ng dge a is too a upgr db be adt the tdb ledna pull e asia ew dys it turn\n",
+      "ead gdi nfl if kings ever dl times ds it aia so it wds d noise i knew very well the tumblers on dsd\n",
+      "cem dae the sd me so una though mu fhm ufh quieter\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(sanitise(keyword_decipher(sca, key_a, wrap_a))))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'damgerstuvwxyzbcfhijklnopq'"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kca = keyword_cipher_alphabet_of('damager', KeywordWrapAlphabet.from_last)\n",
+    "kca"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'dangerstuvwxyzbcfhijklmopq'"
+      ]
+     },
+     "execution_count": 20,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "sak, score = simulated_annealing_break(sca, cipher_alphabet=kca, fitness=Ptrigrams)\n",
+    "sak"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'dangerstuvwxyzbcfhijklmopq'"
+      ]
+     },
+     "execution_count": 22,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kca = keyword_cipher_alphabet_of('dangers', KeywordWrapAlphabet.from_last)\n",
+    "kca"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "exactly what or who had hit me i wasnt sure but by the time i came around they had long gone if you\n",
+      "will excuse the p unit was a professional hit just the right amount of force to knock me out\n",
+      "probably no permanent damage the room had been expertly disassembled the shelves were emptied of\n",
+      "blacks mission files and much of the steampunk technology had been taken apart presumably to make\n",
+      "sure it didnt contain any further secrets the big beautiful roundtable had been cleared and ile\n",
+      "anton it to steady myself as my head swami guessed that whoever had followed me into the tunnels and\n",
+      "on into the headquarters must have known what i was looking for it was too much of a coincidence\n",
+      "that they had found me here probably they were connected with the emails that first got me\n",
+      "interested in black but in a confused state after my blackout i was puzzled why had they involved me\n",
+      "perhaps they just didnt know how to find the shadow archive and hoped i would be able to help\n",
+      "perhaps they wanted to implicate me in the theft of the shadow archive papers in that case they\n",
+      "should have hit me harder i wasnt going to hang around long enough to get caught something was\n",
+      "nagging at men one of the papers i had seen looked interesting enough to justify all this effort i\n",
+      "turned my head cautiously trying to ignore the throbbing behind m year and looked around the room\n",
+      "one more time to see what we were missing as i did so my foot caught on something and i bent down\n",
+      "topic kit up when they hit me i had been sitting reading blacks codebook it was full of marvellous\n",
+      "if dated ideas on cryptography and information security and i had just been reading the section on\n",
+      "transposition ciphers it seemed he was particularly keen on columnar transpositions and was arguing\n",
+      "that it would be best to read off the ciphertext column by column to confuse enemy crypt analysts i\n",
+      "was musing on just how secure that would be when the world went dark luckily as i had fallen i had\n",
+      "dropped the book and it had slipped under the table somehow they had missed it during the search and\n",
+      "there it was hidden in the shadows i took a deep breath to slow the spinning behind my eyes and\n",
+      "picked the book up but as i pulled myself upright again the tabletop shifted slightly to one side i\n",
+      "struggled to regain my balance and the table moved again and this time i heard a distinct click as i\n",
+      "shifted my weight the table rotated back and there it was once more a soft metallic c link as a\n",
+      "ratchet tooth engaged i stood up grabbed at the table and pulled sideways it turned again clicking\n",
+      "several times as it did so it was a noise i knew very well the tumblers on a safe made the same\n",
+      "sound though much much quieter\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(keyword_decipher(sca, 'dangers', KeywordWrapAlphabet.from_last)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2670"
+      ]
+     },
+     "execution_count": 25,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('7a.plaintext', 'w').write(lcat(tpack(segment(keyword_decipher(sca, 'dangers', KeywordWrapAlphabet.from_last)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:459: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n",
+      "  \"matplotlib is currently using a non-GUI backend, \"\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fc = collections.Counter(scb)\n",
+    "plot_frequency_histogram(fc, sort_key=fc.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "history_transpositions = collections.defaultdict(list)\n",
+    "for word in history_words:\n",
+    "    history_transpositions[transpositions_of(word)] += [word]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "3675"
+      ]
+     },
+     "execution_count": 28,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(history_transpositions)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(((4, 0, 3, 6, 2, 5, 1), False, True), -5440.482831185688)"
+      ]
+     },
+     "execution_count": 29,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(trans_b, fillcol_b, emptycol_b), score = column_transposition_break_mp(scb, translist=history_transpositions)\n",
+    "(trans_b, fillcol_b, emptycol_b), score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'thechaosandconfusionthatfollowedthereichstadtmeetingwasmorecompletethanihadanyrighttohopetheplayfairgambitwasanoutstandingsuccessthedelegatesfromrussiaandaustrohungaryeachhadaclearviewofwhathadbeenagreedandtheseviewswereentirelydivergentevenbettertherecordsofthemeetingwereentirelyindependentofoneanotherattheurgingofouragentswithintheseparatecourtstheminutesweredictatedseparatelybythetwoforeignministersandrassyandgorchakovsoastoensurethedeepestpossibleunderstandingoftheagreedoutcomestherewasnosignedformalconventionnorevenanagreedprotocoloursubtlecampaignofwhispersandmisdirectionensuredthatneithersideentirelytrustedtheothersotheseminuteswereneversharedthediscussionsconcerningaustrianannexationinbosniaandherzegoveniawillconfusehistoriansanddiplomatsforgenerationstocomeithasalreadyconfusedtheprincipalsinthisaffairandnooneintheforeignofficecanmakesenseofthematalldespitethegreatcaretakenbytheofficersoftheshadowarchivetorecordthemaccuratelythereistalkoftheneedforfurthermeetingsofthegreatpowersandthistimeiwillmakesurethatbritainwillbeatthetabletoinfluencethedeliberationsandtoprotectourinterestsfromthepointofviewofhermajestyandtheprimeministerifnotthatofallherministersthisisclosetotheperfectoutcomediscussionisdisplacingwarandlowleveldistrustisinhibitingthesortoforganisedalliancethatmightdiminishourinfluenceoverthegatewaytotheeasttheforthcomingconferenceinconstantinoplewillforthefirsttimeinvolveourgovernmentinthediscussionsconcerningthefuturegovernanceoftheregionlordsalisburywillargueforthecreationofautonomousregionsunderbulgarianruleinthehopeofreducingtensionsandeliminatingtheexcusethatrussianeedstoengageinwarifhesucceedsthenwewillhaveestablishedacomprehensiveagreementwithrussiaconcerningitsterritorialambitionsincentralasiaresolvingtheconflictwithourownstrategicaimsevenifthisprovestobetoomuchforournegotiatorswecanatleasthopetobuytimetomakeourownpreparationsandtomanipulateouralliesandenemiesiwillconcentrateondevelopingfurtherconfusionspreadingmisinformationandasmuchdistrustasicanmanageifthetalksfailweshouldatleastensurethatnograndbargainisstruckagainstourinterestsandnomajorallianceisformedtodiminishusthemediterraneanisachokepointforthetraderoutesfromtheeastwecannotandwillnotallowotherstostrangletheflowofgoodsandpeoplethatenrichusnothreatisgreatertothehealthoftheempireandnoactionisbeyondcontemplationinoureffortstoremovethethreat'"
+      ]
+     },
+     "execution_count": 30,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "column_transposition_decipher(scb, trans_b, fillcolumnwise=fillcol_b, emptycolumnwise=emptycol_b)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "the chaos and confusion that followed the reich stadt meeting was more complete than i had any right\n",
+      "to hope the playfair gambit was an outstanding success the delegates from russia and austro hungary\n",
+      "each had a clearview of what had been agreed and these views were entirely divergent even better the\n",
+      "records of the meeting were entirely independent of one another at the urging of our agents within\n",
+      "the separate courts the minutes were dictated separately by the two foreign ministers andrassy and g\n",
+      "or chak ov so as to ensure the deepest possible understanding of the agreed outcomes there was no\n",
+      "signed formal convention nor even an agreed protocol our subtle campaign of whispers and\n",
+      "misdirection ensured that neither side entirely trusted the other so these minutes were never shared\n",
+      "the discussions concerning austrian annexation in bosnia and herzeg oven i a will confuse historians\n",
+      "and diplomats for generations to come it has already confused the principals in this affair and no\n",
+      "one in the foreign office can make sense of them at all despite the great care taken by the officers\n",
+      "of the shadow archive to record them accurately there is talk of the need for further meetings of\n",
+      "the great powers and this time i will make sure that britain will beat the table to influence the\n",
+      "deliberations and to protect our interests from the point of view of her majesty and the prime\n",
+      "minister if not that of all her ministers this is close to the perfect outcome discussion is\n",
+      "displacing war and low level distrust is inhibiting the sort of organised alliance that might\n",
+      "diminish our influence over the gateway to the east the forthcoming conference in constantinople\n",
+      "will for the first time involve our government in the discussions concerning the future governance\n",
+      "of the region lord salisbury will argue for the creation of autonomous regions under bulgarian rule\n",
+      "in the hope of reducing tensions and eliminating the excuse that russia needs to engage in war if he\n",
+      "succeeds then we will have established a comprehensive agreement with russia concerning its\n",
+      "territorial ambitions in central asia resolving the conflict with our own strategic aims even if\n",
+      "this proves to be too much for our negotiators we can atleast hope to buy time to make our own\n",
+      "preparations and to manipulate our allies and enemies i will concentrate on developing further\n",
+      "confusion spreading misinformation and as much distrust as i can manage if the talks fail we should\n",
+      "atleast ensure that no grand bargain is struck against our interests and no major alliance is formed\n",
+      "to diminish us the mediterranean is a choke point for the trade routes from the east we can not and\n",
+      "will not allow others to strangle the flow of goods and people that enrich us no threat is greater\n",
+      "to the health of the empire and no action is beyond contemplation in our efforts to remove the\n",
+      "threat\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(column_transposition_decipher(scb, trans_b, fillcolumnwise=fillcol_b, emptycolumnwise=emptycol_b)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2846"
+      ]
+     },
+     "execution_count": 32,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('7b.plaintext', 'w').write(lcat(tpack(segment(column_transposition_decipher(scb, trans_b, fillcolumnwise=fillcol_b, emptycolumnwise=emptycol_b)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['bulgaria']"
+      ]
+     },
+     "execution_count": 33,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "history_transpositions[trans_b]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['bulgari', 'bulganin', 'bulgaria', 'extraverts']"
+      ]
+     },
+     "execution_count": 34,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "transpositions[trans_b]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.7"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/2018/2018-challenge8.ipynb b/2018/2018-challenge8.ipynb
new file mode 100644 (file)
index 0000000..5c69ada
--- /dev/null
@@ -0,0 +1,614 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Biolerplate"
+   ]
+  },
+  {
+   "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.vigenere import *\n",
+    "from cipher.playfair import *\n",
+    "from cipher.column_transposition import *\n",
+    "from support.text_prettify import *\n",
+    "from support.plot_frequency_histogram import *"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ca = open('8a.ciphertext').read()\n",
+    "cb = open('8b.ciphertext').read()\n",
+    "sca = sanitise(ca)\n",
+    "scb = sanitise(cb)\n",
+    "pca = letters(ca)\n",
+    "pcb = letters(cb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "8197"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "history_words = [w.strip() for w in open('history-words.txt')]\n",
+    "len(history_words)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "history_transpositions = collections.defaultdict(list)\n",
+    "for word in history_words:\n",
+    "    history_transpositions[transpositions_of(word)] += [word]"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Part A"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:459: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n",
+      "  \"matplotlib is currently using a non-GUI backend, \"\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fc = collections.Counter(sca)\n",
+    "plot_frequency_histogram(fc, sort_key=fc.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(((0, 2, 7, 5, 6, 3, 1, 4), False, True), -8088.637383066303)"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(trans_a, fillcol_a, emptycol_a), score = column_transposition_break_mp(sca, translist=history_transpositions, fitness=Ptrigrams)\n",
+    "(trans_a, fillcol_a, emptycol_a), score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(((0, 2, 3, 6, 7, 4, 1, 5), False, True), -7787.854522433465)"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(trans_a, fillcol_a, emptycol_a), score = column_transposition_break_mp(sca, fitness=Ptrigrams)\n",
+    "(trans_a, fillcol_a, emptycol_a), score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'kedIchecdtoarounIwaseeifgwasbeinbuttchedomwtheroiniasdefmpttelyecouyandIearldnthinganythdesoutsikedoIducoindowntthespectsidunderetaeofthetobleThighpwashishlypolhagedwitulsracefothlopetthieedgengackeniprositaptheachedecocentrherlumnToviewasnmecsiblemtohanissttsuggewashatitinganythhanmoretearitappeagedtoborkrandwatttabletrehecenandofagrolrcontrushoomIpedaedpoktenndlisanoedforechthermbutanismwastherengmnothiicaechanIcolthatndTuldfickehethifthningondtetopakofhebullumthecollondidaforwroomlysafairntiubstahanalmecougismthuckhandtnthedupiwheefoldtoprethedthjoinemntecoluasaherewmetsmalltebalplagamearinmarakersartkMyheedtskipprtohedooadotheShivewArchedacarriarpsimilnsclateiwitribedradhthetofJemarknntohnTaksmhelocomaithwhturnufacsecedthesysuritythetemonnceentrakedItlooehalikehmaddalsotabethisasnleHewrniotafuaketuremherrandtdonecoulnerlybeoheheasonethadmadItmisoneparustbeocktofalnismechasthmHewaingeleadakesafemctorinViondrianLifBonandadflackheneeltthhimedforldatobuinthsafeitofehearadotheShivewArchldoitcoubecnlybeherausetsecewerehatretstoodweretenfarkevsecortheofturityhivheArclfMeitsehisaybettmyiswhakerattacallwasreranyaftethedifsotruyhadstoockwayshosoonIankuldthealthemrhoulywithintmyacIwogheadvebuldhalikeenundiselytoTancoverhannsmectthismbuughatthondetremiassdmeIwulntillvedoerablheswnintsIdhadowhinidnttewaktherneesanyoounlsearcoudbutIesuldntbInereandackededbilnupUntrehowtheeenadntbhtoenougrrygetHavedinvolsadinthireIventuwasstilltaintcerhewnthatealouldbtohlowedtaselpoutreIwasnureallysatithatnecuonalsasiritywedbnvolvsabutIwaelysolutinhcertadwaewouleetnttoseedhisInetoedtogelyutsafmebandcothaackwioweteamsprocouldexpperlyheAloreteanrchivoutdfindheTwhattfesannsaBeftoredeftoreIloneItookookmoreldgaarounngttheripaphefewatwersthftaereletinndputodegthececubooksntorelyietoapockckpfmybatilackIsdntlcoulvetbelieatthatmyshaackeritbdleftbutehindpstperhasseheymitheditinintgloomxciheirettotemenrthgathernmegoveperentpahthswhicfoueyhadothndIfnsecingeltofameouwasthisIintcertaecohatthkwadeboohreswortIhaadingdtidnthanspmetoiproectitbutperlyctitheseheVonontrecigenelooiphersolkedabfasutelyingcinat'"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "column_transposition_decipher(pca, trans_a, fillcolumnwise=fillcol_a, emptycolumnwise=emptycol_a)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "262.0"
+      ]
+     },
+     "execution_count": 33,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(pca) / 8"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'kdIecceh'"
+      ]
+     },
+     "execution_count": 35,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "first_row = every_nth(pca, 262)[0]\n",
+    "first_row"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 68,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('kdIecceh', 'kdIecceh')"
+      ]
+     },
+     "execution_count": 68,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "target_pt = 'Ichecked'\n",
+    "# tta = (2, 1, 0, 3, 4, 5, 6, 7)\n",
+    "tta = (5, 7, 0, 3, 4, 1, 6, 2)\n",
+    "tta = (5, 7, 0, 6, 4, 1, 3, 2)\n",
+    "tta = (5, 7, 0, 3, 1, 4, 6, 2)\n",
+    "tta = (5, 7, 0, 6, 1, 4, 3, 2)\n",
+    "\n",
+    "column_transposition_encipher(target_pt, tta), first_row"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 49,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "sample_ta = [(5, 7, 0, 3, 4, 1, 6, 2), (5, 7, 0, 6, 4, 1, 3, 2), (5, 7, 0, 3, 1, 4, 6, 2), (5, 7, 0, 6, 1, 4, 3, 2)]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 50,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(((5, 7, 0, 3, 4, 1, 6, 2), False, True), -7097.955599556401)"
+      ]
+     },
+     "execution_count": 50,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(trans_a, fillcol_a, emptycol_a), score = column_transposition_break_mp(sca, translist=sample_ta, fitness=Ptrigrams)\n",
+    "(trans_a, fillcol_a, emptycol_a), score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 52,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'IcheckedaroundtoseeifIwasbeingwatchedbuttheroomwasdefinitelyemptyandIcouldnthearanythingoutsidesoIduckeddowntoinspecttheundersideofthetableThetopwashighlypolishedwithagracefulslopetotheedgethickeningasitapproachedthecentrecolumnTherewasnovisiblemechanismtosuggestthatitwasanythingmorethanitappearedtobeagrandworktableatthecentreofagrandcontrolroomIpushedpokedandlistenedforanothermechanismbuttherewasnothingmechanicalthatIcouldfindThethickeningofthetopandthebulkofthecolumndidallowroomforafairlysubstantialmechanismthoughandtuckedupinthefoldwherethetopjoinedthecolumntherewasasmallmetalplatebearingamakersmarkMyheartskippedthedoortotheShadowArchivecarriedasimilarplateinscribedwiththetrademarkofJohnTannthelocksmithwhomanufacturedthesecuritysystemontheentranceItlookedlikehehadalsomadethistableHewasnotafurnituremakerandtherecouldonlybeonereasonhehadmadethisoneItmustbepartofalockmechanismHewastheleadingsafemakerinVictorianLondonandifBlackhadfelttheneedforhimtobuildasafeintheheartoftheShadowArchiveitcouldonlybebecausethereweresecretsthatweretoodarkevenforthesecurityoftheArchiveitselfMaybethisiswhatmyattackerwasreallyafterandifsotheyhadstruckwaytoosoonIshouldthankthemreallywithoutmyachingheadIwouldhavebeenunlikelytodiscoverTannsmechanismbutthatthoughtremindedmeIwasstillvulnerabledownintheshadowsIdidntthinktherewasanyoneelsearoundbutIcouldntbesureandIneededbackupUntilnowtherehadntbeenenoughtogetHarryinvolvedinthisadventureIstillwasntcertainthathewouldbeallowedtohelpoutasIwasntreallysurethatnationalsecuritywasinvolvedbutIwasabsolutelycertainhewouldwanttoseethisIneededtogetoutsafelyandcomebackwithateamsowecouldproperlyexploretheArchiveandfindoutwhattheTannsafestoredBeforeIleftItookonemorelookaroundgatheringthefewpapersthatwereleftandputtingthecodebooksecurelyintoapocketofmybackpackIstillcouldntbelievethatmyattackershadleftitbehindbutperhapstheymisseditinthegloomintheirexcitementtogatherthegovernmentpaperswhichtheyhadfoundIfnothingelsecameoutofthisIwascertainthatthecodebookwasworthreadingIhadnthadtimetoinspectitproperlybutthesectionontheVigenerecipherlookedabsolutelyfascinating'"
+      ]
+     },
+     "execution_count": 52,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "raw_pta = column_transposition_decipher(pca, trans_a, fillcolumnwise=fillcol_a, emptycolumnwise=emptycol_a)\n",
+    "raw_pta"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 53,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "I checked around to see if I was being watched but the room was definitely empty and I couldnt hear\n",
+      "anything outside so I ducked down to inspect the underside of the table The top was highly polished\n",
+      "with a graceful slope to the edge thickening as it approached the centre column There was no visible\n",
+      "mechanism to suggest that it was anything more than it appeared to be a grand work table at the\n",
+      "centre of a grand control room I pushed poked and listened for another mechanism but there was\n",
+      "nothing mechanical that I could find The thickening of the top and the bulk of the column did allow\n",
+      "room for a fairly substantial mechanism though and tucked up in the fold where the top joined the\n",
+      "column there was a small metal plate bearing a makers mark My heart skipped the door to the Shadow\n",
+      "Archive carried a similar plate inscribed with the trademark of John Tann the locksmith who\n",
+      "manufactured the security system on the entrance It looked like he had also made this table He was\n",
+      "not a furniture maker and there could only be one reason he had made this one It must be part of a\n",
+      "lock mechanism He was the leading safe maker in Victorian London and if Black had felt the need for\n",
+      "him to build a safe in the heart of the Shadow Archive it could only be because there were secrets\n",
+      "that were too dark even for the security of the Archive itself Maybe this is what my attacker was\n",
+      "really after and if so they had struck way too soon I should thank them really without my aching\n",
+      "head I would have been unlikely to discover Tan ns mechanism but that thought reminded me I was\n",
+      "still vulnerable down in the shadows I didnt think there was anyone else around but I couldnt be\n",
+      "sure and I needed backup Until now there hadnt been enough to get Harry involved in this adventure I\n",
+      "still wasnt certain that he would be allowed to help out as I wasnt really sure that national\n",
+      "security was involved but I was absolutely certain he would want to see this I needed to get out\n",
+      "safely and comeback with a team so we could properly explore the Archive and find out what the Tann\n",
+      "safe stored Before I left I took one more look around gathering the few papers that were left and\n",
+      "putting the codebook securely into a pocket of my backpack I still couldnt believe that my attackers\n",
+      "had left it behind but perhaps they missed it in the gloom in their excitement to gather the\n",
+      "government papers which they had found If nothing else came out of this I was certain that the\n",
+      "codebook was worth reading I hadnt had time to inspect it properly but the section on the Vi genere\n",
+      "cipher looked absolutely fascinating\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(raw_pta))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 54,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[]"
+      ]
+     },
+     "execution_count": 54,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "transpositions[trans_a]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 55,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[]"
+      ]
+     },
+     "execution_count": 55,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "history_transpositions[trans_a]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 70,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[[], [], ['enumerated'], []]"
+      ]
+     },
+     "execution_count": 70,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[transpositions[tr] for tr in sample_ta]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 56,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2581"
+      ]
+     },
+     "execution_count": 56,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('8a.plaintext', 'w').write(lcat(tpack(segment(raw_pta))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 77,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "279585"
+      ]
+     },
+     "execution_count": 77,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "many_words = [w.strip() for w in open('../many_word_lists/combined.txt')]\n",
+    "len(many_words)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 78,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "many_transpositions = collections.defaultdict(list)\n",
+    "for word in many_words:\n",
+    "    many_transpositions[transpositions_of(word)] += [word]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 79,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['gothicise', 'gothicises']"
+      ]
+     },
+     "execution_count": 79,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "many_transpositions[trans_a]"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Part B"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 61,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'shadow'"
+      ]
+     },
+     "execution_count": 61,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score = vigenere_frequency_break(scb)\n",
+    "key_b"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 62,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'elliothasdonehimselfnofavoursinarguingthepragmaticlineattheconstantinopleconferencedisraelicaughtthemoodwithhispamphletandthepeopledonotseemtoagreethatbulgarianlivescountforlessinthecalculusofinternationalaffairsithinksalisburyplanstomovehimonperhapsbacktoviennahewassuccessfulthereitismostunusualtohaveannoyedbothsalisburyandgladstonebutihavesomesympathywithhisviewstheterribleeventsthathaveprecipitatedthiscrisiscannotbeundoneandthereareotherconsiderationsrussianaggressionmuststillbeimpededifwearetoretainourinfluenceintheregionmyagentstellmethattherussianemperormetwiththeaustriansatbudapestatthestartoftheyeartodiscusstheirintentionsintheeventofwaranditisrumouredthattheyplantorestructurethebalkansinanefforttocontroltheslavicmovesforaunifiedstateitismyownviewthattheslavsmaybeamostusefulallyinblockingtheexpansionistmovementinrussiaandihaveadvisedthegovernmenttoinvitetheaustrianstojoinusinmarchtoseeifwecaneffectadiplomaticsolutiontountanglethisgordianknotperhapswecanfindsomethingmoreattractiveforthemthatwillweakentheirdependenceontsaralexanderiiifwefailthenifearthatmoredirectactionmayneedtobetakenihaveinmypossessioncopiesofcertainlettersthathavebeencirculatinginfranzjosefscourtthatithinkmightbesufficientlyembarrassingtoconcentratemindsontheadvantagesofworkingwithusinstabilityintheregioniscertainlysomethingtobefearedbutperhapswecanconvincetheaustriansthatstabilitywouldbeworseifitissecuredbytherussiansifwecannotturnaustriatoourcauseitmightbenecessarytoundertakeacampaigntostirupthelocalpopulationsperhapsrussiawouldthinktwicebeforegettinginvolvediftheywerenotabletosecureastablesettlementbyforceofarmsalonethelessonsofthecrimeahavenotbeenforgottenbyanyofitscombatantsmodernwarfareisgrowingindustrialinitsscaleandthecostsofconflictareprohibitiveiamcertainthatthestoriestoldbynightingaleofthehorrificwoundssufferedtherehavesoftenedtheappetiteofsomeforopenconflictandperhapsthatisresponsibleforhermajestyssupportoftheshadowarchiveandallitsworksimustnotletherdownnortheempire'"
+      ]
+     },
+     "execution_count": 62,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "vigenere_decipher(scb, key_b)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 63,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "elliot has done himself no favours in arguing the pragmatic line at the constantinople conference\n",
+      "disraeli caught the mood with his pamphlet and the people do not seem to agree that bulgarian lives\n",
+      "count for less in the calculus of international affairs i think salisbury plans to move him on\n",
+      "perhaps back to vienna he was successful there it is most unusual to have annoyed both salisbury and\n",
+      "gladstone but i have some sympathy with his views the terrible events that have precipitated this\n",
+      "crisis can not be undone and there are other considerations russian aggression must still be impeded\n",
+      "if we are to retain our influence in the region my agents tell me that the russian emperor met with\n",
+      "the austrians at budapest at the start of the year to discuss their intentions in the event of war\n",
+      "and it is rumoured that they plan to restructure the balkans in an effort to control the slavic\n",
+      "moves for a unified state it is my own view that the slavs maybe a most useful ally in blocking the\n",
+      "expansionist movement in russia and i have advised the government to invite the austrians to join us\n",
+      "in march to see if we can effect a diplomatic solution to untangle this gordian knot perhaps we can\n",
+      "find something more attractive for them that will weaken their dependence on tsar alexander ii if we\n",
+      "fail then i fear that more direct action may need to be taken i have in my possession copies of\n",
+      "certain letters that have been circulating in franz josef s court that i think might be sufficiently\n",
+      "embarrassing to concentrate minds on the advantages of working with us instability in the region is\n",
+      "certainly something to be feared but perhaps we can convince the austrians that stability would be\n",
+      "worse if it is secured by the russians if we can not turn austria to our cause it might be necessary\n",
+      "to undertake a campaign to stir up the local populations perhaps russia would think twice before\n",
+      "getting involved if they were notable to secure as table settlement by force of arms alone the\n",
+      "lessons of the crime a have not been forgotten by any of its combatants modern warfare is growing\n",
+      "industrial in its scale and the costs of conflict are prohibitive i am certain that the stories told\n",
+      "by nightingale of the horrific wounds suffered there have softened the appetite of some for open\n",
+      "conflict and perhaps that is responsible for her majestys support of the shadow archive and all its\n",
+      "works i must not let her down nor the empire\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(vigenere_decipher(scb, key_b)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 64,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2419"
+      ]
+     },
+     "execution_count": 64,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('8b.plaintext', 'w').write(lcat(tpack(segment(vigenere_decipher(scb, key_b)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.7"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/2018/2018-challenge9.ipynb b/2018/2018-challenge9.ipynb
new file mode 100644 (file)
index 0000000..ebf6dd6
--- /dev/null
@@ -0,0 +1,374 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Biolerplate"
+   ]
+  },
+  {
+   "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.vigenere import *\n",
+    "from cipher.playfair import *\n",
+    "from cipher.column_transposition import *\n",
+    "from support.text_prettify import *\n",
+    "from support.plot_frequency_histogram import *"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ca = open('9a.ciphertext').read()\n",
+    "cb = open('9b.ciphertext').read()\n",
+    "sca = sanitise(ca)\n",
+    "scb = sanitise(cb)\n",
+    "pca = letters(ca)\n",
+    "pcb = letters(cb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "8197"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "history_words = [w.strip() for w in open('history-words.txt')]\n",
+    "len(history_words)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "history_transpositions = collections.defaultdict(list)\n",
+    "for word in history_words:\n",
+    "    history_transpositions[transpositions_of(word)] += [word]"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Part A"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:445: UserWarning: Matplotlib is currently using module://ipykernel.pylab.backend_inline, which is a non-GUI backend, so cannot show the figure.\n",
+      "  % get_backend())\n"
+     ]
+    },
+    {
+     "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": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'dynamite'"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score = vigenere_frequency_break(sca)\n",
+    "key_a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'theengineersharrybroughtwithhimwantedtotakesawsandtorchestothetablesafebutneitherofuswerekeenicouldseethatitwouldbeworthalottocollectorsandprobablybelongedinamuseumharrysaidheagreedbutihadafeelinghewanteditinstalledbackinheadquarterstherewassomethingproprietorialinthewayhelookedatitittookthetwoofuseighteenhourstocrackitbutwithasquadronofspecialforcesfromherefordguardingustherewasnoriskthatmyattackerswouldreturniaskedharryhowhegotauthorisationtobringtheminafterallwestillwerentsurethattherewereanynationalsecurityimplicationsbuthejustlaughedandpointedoutthatwewerecurrentlysomewhereundernewscotlandyardandithadnttakenmuchtoconvincethehomesecretarythatweneededapropersecurityteamtoguardtheshadowarchiveanotherteamofanalystshadcampedononesideofthecommandcentreandwerecombingthroughblackscodebookandthefewpapersthatourantagonistshadleftbehindfromtimetotimeoneofthetrooperswouldarrivewithanotherboxofdocumentsretrievedfromasideroomoramoredistantpartofthearchivelabyrinthmostcouldbedecryptedquicklyusingthestandardtoolsblackhadusedarangeofciphersincludingsubstitutionandtranspositionandalmostnoneofitwasharderthanavigenereitwasslowsincethepapershadtobehandledwithcareandthescannertheyhadbroughtwiththemwasntreallydesignedforthissortofworkacoupleoftimestheycalledharryovertoshowhimsomethingandhereaditnoddedthencamebacktoworkonthesafeasweworkedwetalkedaboutwhatihadlearnedconcerningtheshadowarchiveandblackssecretworkforthegovernmentharrydidntgivemuchawaybutihadafeelinghehadheardsomeofthisstorybeforeandafterthesecondtimehewascalledawayheseemedparticularlythoughtfuliaskedhimwhatwasbotheringhimbuthewasenjoyingbeingcryptichesaidsomethingaboutthebalkanproblemthenmutteredsteveturnerspoemhistorylessonhistoryrepeatsitselfhastonoonelistensicouldntgetanythingmoreoutofhimexceptsomecommentaboutworkingbackwardsthroughthepaperssoiturnedmyattentionbacktothesafethemechanismwasbiggerandheavierthanwewereusedtoandhadbeenexquisitelymadethecomponentsslidalmostnoiselesslyoveroneanotherandtheloudclicksihadheardwhenmovingthetableseemedtobetheresultofabrokencogtoothcatchingonthebarrelsthatmadeitevenhardertoopenwhatlittlenoisethelocktumblersmadewasheavilydisguisedandwehadtoresorttodrillingasmallaccessholetopassanendoscopeintotheinterioritwasaswellwehadtakentheeffortsittinginthemiddleofapileofnotebooksandpaperswasasmallpileofwhatlookedlikeexplosivesthesafewasriggedtoblowifwemadeamistake'"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "vigenere_decipher(sca, key_a)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "the engineers harry brought with him wanted to take saws and torches to the table safe but neither\n",
+      "of us were keen i could see that it would be worth alot to collectors and probably belonged in a\n",
+      "museum harry said he agreed but i had a feeling he wanted it installed back in headquarters there\n",
+      "was something proprietor i al in the way he looked at it it took the two of us eighteen hours to\n",
+      "crack it but with a squadron of special forces from hereford guarding us there was no risk that my\n",
+      "attackers would return i asked harry how he got authorisation to bring them in after all we still\n",
+      "werent sure that there were any national security implications but he just laughed and pointed out\n",
+      "that we were currently somewhere under new scotland yard and it hadnt taken much to convince the\n",
+      "home secretary that we needed a proper security team to guard the shadow archive another team of\n",
+      "analysts had camped on one side of the command centre and were combing through blacks codebook and\n",
+      "the few papers that our antagonists had left behind from time to time one of the troopers would\n",
+      "arrive with another box of documents retrieved from aside room or a more distant part of the archive\n",
+      "labyrinth most could be decrypted quickly using the standard tools black had used a range of ciphers\n",
+      "including substitution and transposition and almost none of it was harder than avi genere it was\n",
+      "slow since the papers had to be handled with care and the scanner they had brought with them wasnt\n",
+      "really designed for this sort of work a couple of times they called harry over to show him something\n",
+      "and he read it nodded then came back to work on the safe as we worked we talked about what i had\n",
+      "learned concerning the shadow archive and blacks secret work for the government harry didnt give\n",
+      "much away but i had a feeling he had heard some of this story before and after the second time he\n",
+      "was called away he seemed particularly thoughtful i asked him what was bothering him but he was\n",
+      "enjoying being cryptic he said something about the balkan problem then muttered steve turners poem\n",
+      "history lesson history repeats itself has to no one listens i couldnt get anything more out of him\n",
+      "except some comment about working backwards through the papers so i turned my attention back to the\n",
+      "safe the mechanism was bigger and heavier than we were used to and had been exquisitely made the\n",
+      "components slid almost noiselessly over one another and the loud clicks i had heard when moving the\n",
+      "table seemed to be the result of a broken cog tooth catching on the barrels that made it even harder\n",
+      "to open what little noise the lock tumblers made was heavily disguised and we had to resort to\n",
+      "drilling a small access hole to pass an endoscope into the interior it was as well we had taken the\n",
+      "effort sitting in the middle of a pile of notebooks and papers was a small pile of what looked like\n",
+      "explosives the safe was rigged to blow if we made a mistake\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(vigenere_decipher(sca, key_a)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2913"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('9a.plaintext', 'w').write(prettify(vigenere_decipher(sca, key_a)))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Part B"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'turkey'"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score = vigenere_frequency_break(scb)\n",
+    "key_b"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'erutuferuceseromdnawenagnitaercfoepohehtnimehthtiwylesolckrowoteunitnoclliwinoigertahtnidlohtoofasueviglliwainsobnikrowtentnegaruoosfiyltnenamrepnoitseuqnaklabehtelttesotspahrepdnasniaglairotirretnaissurenimrednuotepohewetatsnamottoehtotkcabainodecamgnidartybemitemasehttasetuoredartnaenarretidemehtfolortnocruognitnemecsurpycniagyamewtahtsruomurdraehevahidnaseitinutroppognidartnihcireblliwynamregniraazabcitamolpidehtfoerehpsomtadeiznerfehtesruocfosrewoprojamehtnomehthguorhtraeboterusserpgnirbnacewtahtepohehtniytilibatsniderutrunevahsnaklabehtssorcastnegaymseitrapdnasetatsrellamsehtnosisucofymtubweivaevaherusmailliwsrewoprojamehtfollassergnocehtfonrecnocelpicnirpehtsideveihcaebthgimnoitacifinusihtrehtehwdnawohfonoitseuqehtelbitapmocnieraesehtdnasweivlavirynamyreveraerehttahtrehtartubaediraelcakcalyehttahttonsitignidaelsimsitahtspahrepnoitacifinuehtdaeldluohsytraphcihwfoaediraelcondnanworiehtfosnoitibmalacitilopdnalarutlucdeiravhtiwdedividniamersevlesmehtsetatsnaklabehtnoitulosnaklabakeesohwesohtdnaaissurnihtiweildluohsrewopstifosucolehttahteveilebohwesohtneewtebtilpsylpeedsitubdeifinuneebevahylatidnaynamregtahtyawemasehtnisetatscivalsehtetinuotsmiatnemevomcivalsnapehtsisircehtfotuoyawaeesyameweveilebinehtnilrebtaadnegaehtlortnocnacewfitcilfnocrehtrufmorfesoloteromgnihtemosevahyehttahtdesilaerevahlladnatnenitnocehtssorcatpureyamrawtahttaerhtgnirehtagehteesotnugebevahsrewoprojamehtfollasevilnitsocrewolhcumatadeeccusthgimycamolpidfosdohtemwenruotahtsiepohymtsoctaergtanetfodnathguoberagninniwhtrowseirotcivllatahtweivymsititubthguorbnaemylerustsumitahtdiasdnaemdetcerrocehriafyalpotsihtdiasinehwnoituloserarofepohotnigebnacinilrebnissergnocgnidnepmiehttathguobebthgimecaeptahttcepsorpehthtiwyllanifwonnihtiwseimenegnithgifygreneelbaredisnocdednepxeevahidnallahetihwniralupopyllasrevinuneebtonevahsdohtemymsselehtenonmelborphsikrutehtotnoitulosnworuotneserpotsrewopgnidaelrehtohtiwetaitogenotnigebotelbaerewewdnocesdnaseimeneruofosecivrescitamolpidehtnihtiwkrowtentnegaruopolevedotelbaerewewtsrifsgnihtowtdeveihcayaledsihttahtflesymtrofmocidnaelbativeniehtyaledotdekrowseillaehtgnomanoisufnocgniwosfoygetartsruonoituloslanoitanretninaotelbanemaebotgniraeppaelihwnoitisophsitirbehtgnisilanigramylevitceffednaairtsuadnaynamregniseillarehhtiwnoitcaroftroppusgnidliubyltcefrepdnahrehdeyalpsahaissurderaefewtahtllaneebsahrawhsikrutossureht'"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pb1 = vigenere_decipher(scb, key_b)\n",
+    "pb1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "the russo turkish war has been all that we feared russia has played her hand perfectly building\n",
+      "support for action with her allies in germany and austria and effectively marginalising the british\n",
+      "position while appearing to be amenable to an international solution our strategy of sowing\n",
+      "confusion among the allies worked to delay the inevitable and i comfort myself that this delay\n",
+      "achieved two things first we were able to develop our agent network within the diplomatic services\n",
+      "of our enemies and second we were able to begin to negotiate with other leading powers to present\n",
+      "our own solution to the turkish problem nonetheless my methods have not been universally popular in\n",
+      "whitehall and i have expended considerable energy fighting enemies within now finally with the\n",
+      "prospect that peace might be bought at the impending congress in berlin i can begin to hope for a\n",
+      "resolution when i said this to playfair he corrected me and said that i must surely mean brought but\n",
+      "it is my view that all victories worth winning are bought and often at great cost my hope is that\n",
+      "our new methods of diplomacy might succeed at a much lower cost in lives all of the major powers\n",
+      "have begun to see the gathering threat that war may erupt across the continent and all have realised\n",
+      "that they have something more to lose from further conflict if we can control the agenda at berlin\n",
+      "then i believe we may see away out of the crisis the pan slavic movement aims to unite the slavic\n",
+      "states in the same way that germany and italy have been unified but is deeply split between those\n",
+      "who believe that the locus of its power should lie within russia and those who seek a balkan\n",
+      "solution the balkan states themselves remain divided with varied cultural and political ambitions of\n",
+      "their own and no clear idea of which party should lead the unification perhaps that is misleading it\n",
+      "is not that they lack a clear idea but rather that there are very many rival views and these are\n",
+      "incompatible the question of how and whether this unification might be achieved is the principle\n",
+      "concern of the congress all of the major powers william sure have a view but my focus is on the\n",
+      "smaller states and parties my agents across the balkans have nurtured instability in the hope that\n",
+      "we can bring pressure to bear through the mon the major powers of course the frenzied atmosphere of\n",
+      "the diplomatic bazaar in germany will be rich in trading opportunities and i have heard rumours that\n",
+      "we may gain cyprus cementing our control of the mediterranean trade routes at the same time by\n",
+      "trading macedonia back to the ottoman state we hope to undermine russian territorial gains and\n",
+      "perhaps to settle the balkan question permanently if so our agent network in bosnia will give usa\n",
+      "foothold in that region i will continue to work closely with them in the hope of creating a new and\n",
+      "more secure future\n"
+     ]
+    }
+   ],
+   "source": [
+    "rpb1 = cat(reversed(pb1))\n",
+    "print(prettify(rpb1))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2856"
+      ]
+     },
+     "execution_count": 28,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('9b.plaintext', 'w').write(prettify(rpb1))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.7"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/2018/2018-challengea.ipynb b/2018/2018-challengea.ipynb
new file mode 100644 (file)
index 0000000..4eb722d
--- /dev/null
@@ -0,0 +1,2031 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Biolerplate"
+   ]
+  },
+  {
+   "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.vigenere import *\n",
+    "from cipher.playfair import *\n",
+    "from cipher.autokey import *\n",
+    "from cipher.column_transposition import *\n",
+    "from support.text_prettify import *\n",
+    "from support.plot_frequency_histogram import *"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ca = open('aa.ciphertext').read()\n",
+    "cb = open('ab.ciphertext').read()\n",
+    "sca = ca.strip()\n",
+    "scb = sanitise(cb)\n",
+    "pcb = letters(cb)\n",
+    "ptb = depunctuate(cb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "8197"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "history_words = [w.strip() for w in open('history-words.txt')]\n",
+    "len(history_words)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "history_transpositions = collections.defaultdict(list)\n",
+    "for word in history_words:\n",
+    "    history_transpositions[transpositions_of(word)] += [word]"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Part A"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "22545"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(sca)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "3220.714285714286"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(sca) / 7"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[8, 8, 4, 17, 15]"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ca5c = [int(c, 2) for c in chunks(sca, 5)]\n",
+    "ca5c[:5]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(25, 0)"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "max(ca5c), min(ca5c)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'iierpfblvnjgtbrdncqtncvrimuoccxprrvguebucboboejcfvyakcsqjajnsmgtpqvzrnfuupntycqtnnecebbccyjughvrbjyewmspvsfdgqpejmimfuxefageuufzrmftfbuedylmeseynmclrrfiadupjtytycsmvtnytrhskyterlcfflvdkfflrmfjjbvoeaiiegvubayieiflgorufjbfdcdpnnzabtqekmoigoiqbvqackpagaewpbueibjzrckgpvjoljepnvvbjaguizflntccbagoecpnghvkuprmraiqaeiwxifocbbvqtycticpvpterrvlupnpgwxwekzlhevtygujhtdcdpnnzabtzetfbvvsdqdiabvcbaveirpebrbujbutyyomyetrswaitqbalolabvfevfpervvpzbuieejapoelfkgeuykcqitgpcfdfqfwsslnfztllcgqkeukpagowrimzetfbvvsdqjvclrafrhskjfiiieevajikfuprpimctrmfdxpntkmewjikfbpragmgwydrlecaskyctreonmwfimctvbrdymtlwvupcydyywmclraflbnvmsbjofdpceonlemgoeyuwesrlexncbcewhtkffxyatcxqghjyoloaxqbvqbicfhrbcmdsftfapvgazlupreonmwfiflbvqikfjvxemcopnriwnqthkfbdrbvcokbnmgokrdkfbbghrrjajhrrxmfhfsmlqozlupvstytmouksonbrksoigecwupreonmwfimcterrvlpbghvmotltygoojetmvtqsvcjvfiucuprsrdfavtkgoohnucsbuedubanscgnjyaticwbkncdwhluluarerlzlrtrgmaoukfbdvnxepbghzqgieikqfmzeuasimykmemftimzqgaewupvnxriqfwvjmxeokcdbrddstbuamccmrnzkqwetrluigsfkfbvmvyoljeecflrdkmlvbwnfbbghzqnqthkymtuamccmrnrzpcgawrfznqlgdspacjcipkkmimndhsbzgeiqiierpepbnpgppdnlkmdwatzlvmgrpgoogotpbkxtyctiseyclvrwdcuwbwvjmbbajinmgoccbdrblruprdfavurnkqumnmicuzrakcebbajygmqijrbvpeumxvghvapzeiumsevtykpagowrimturpeayertjvtajkbtytvynbbwrrdpbvvpvansncxwekvbpvrowrimzhrbkwvnvbuprsrqgzbmkffanpgcsannuubannvvqmeivldmqbfkclvsgmtiyeonfzgsfffebrbceevtystenttfjvttycffclfqjdrswmsiaytfbvtejkpvvtfpjvtvzzsigiflbvqtvkqmeakssmnnuefvrrrjmgxevnjvtujabtzikrbsrsrqqmpirjumzpvpburnkrplbtyyuebrbdvtytzkfiadncxmeexjblbfkffkbmgyognnurimrxgcsbvsvygbrrjcwmatvcopbuiqxmjeichmgtzlhbvrvbbvqajcjoutvcoicpimbkueugcmtaerpebnucsqswvupcyddyoitekmtiiekffxnpvptjhtvtfvgurjmgghvdjvnltmhbhreceiadkfftnskrvuolvpgmylzluwclraferhrbniaaxcebbgcsfbuesppsrntmhjncbrportycsiadngupnmzjexeokctbghvrpxguilfleazqjvtagjbbsoikvxghimvoutycdmatiymxvlcysbbpictmatlqxqghkffjbobufpndjcfvoykfftvgyrpnghvcolbstmqmvtnytjngxceiadjcdceeuyoluaipzbbobguevtyfjughvqqmpirjgwecvqtmpuicebuevluznntctbbtyctpndfubzphztfiadzjfngtfefbfodcttregufurtkffvrxkbbggoxmupeoleibuegyqmesyyszlhrbtbnrkcewatycemprpnulbieebtytycvahacaimpkjdsmduvldgnnrjzavszlemkowapqaczbfvperleaboerimqijrsqoukgpvfwvpfzrlrrjdrlpdmigsfguenstjfielplpbnszkqtrcrbfvhsfptcoskgucgifldqchvpbvqwvquietvbuzlieetwzefdupriucbajeyyenbuebjvolralapouccwbkzruwbklqmwagvpupnnnciiqeonfkgeuzvbnfkcsisenbbgfwvfblghvcobvrvqfbqetgqprrvbbvqhrbcmtuerimnnrjzavsyyszlhrbttvgyrmgqiwdfzrnkgobrrvquasrfknmvwrqgifczlbbrdswuprieqjoutjgobbaemmlrrnmstqwygmmuaipzenswmdcfsvbpvjhprimfeumdczeertuvgyriiierlzkbnkcnxbrrpzavgeggqpaeafjbtyrvzaeumvbgoscjucoirbvghzquweydyubrrjyolnsdysffazbjbgeebtbbrvnfigikqftspvptwaacjzqjoljejrtycxifnkrimsiiquxrrjmobbsrwjbnnuffebnkzfbuecytboukdpzhskffxbierxiftyyuifwvpfiqmfpferbvebvgojcfbuegysiylvjtjrtncfvolralajoijeiadfsswjnrleqgwrqowgcfkgwetrzmmeerbjvtwycoergfruwghvzbkxowrimoofibtybvaburcccbzghvzpwxwrqbkgurjmgncztjtfeitjkrrvnpzgoerimfhrbpenrtfjdrccmtqagzrewjnrleovvzlhzrajmoajhpzmipkyyejreerpwfutafaffljbvqhzqbkgimguqrsyyejndcwemftrzjtvsvbuprbrjliaskffzrpfpubeatceiqiicdbyiecgzbmkffjhlxysqnntpjavskmmigeirsiteugfatimcopvsvystleericfirqnnbrygtvrwdcupbdjmgauaumxlvpcmnipyzfpvrskjzjrlzcwmueecwmemvyobgotmtbfodyogyimctjhtzrtmrmvbdtraidswztycsmcoirupntsjbkxszlumefvpfvpezlgweezeolbmvquqppfjjbvcjfbluaubjzrcfltmduvldmfikjpwxeuymtgofdbuvlzysiadzdpceeecnqrsnyobrdkmeqfciceqgujuimawvapuclrgomqasmvbghvgsqatvpgmeeeafqadfkfagitnptvtzatbueerimfegyqmesnmvtqbvrimvdvymsbmgppuntdyumeirjjbyofiflyibcxmjeicobwujrwqptzktwstyctmgatrjkfwvfblvnmcobrdjmnmbfkffurtymeabuiqftiejzbkxierimaiecumrnkfdmatlpzpnriwqcgolrbzrqlctbsoiyoiyyjrtbbwfplwarvafvgszeoiyskpbnsitrparezduprrvubannpriqagkmtctgvqueuonytzrsgmoavbccgwesvleqagdcpvghvfvvgffpuprkfkqzbmrrgqyejrimeenytvgmlaiiadtcsbniejzvbtygoogocgosvtkmgweezeoobvvpournkydbvoeguenshsjbrpfqtqolvriigtygtenskffebrbmgwaefduprcignqaaclfbjoiitbuakfbltrfuoccawrfzghvdbtyowrimfomgfbfmrplmgmrljxhlrrjwaijymcprrrjdrblqjvrsjyolntkydsfoeepdrrekfvgciceqoicgugnrvywmeyvdgmptztfenykmnwienfptrmrplmgskfflbclkfvgsjrptrnwppughvyskuimcxmeejrjtyolruprrvqpurwycsmnnuguensgmtavbccupntkffgpoerbqaeucowhgyrpmzbrpsifslqccgtyyuaredcecalziftlwymfdrrnppbrtycdtbslpfzrpfpupndscfvghfppcthrleqgdzbobfevkmqxecwupryyyetrfkyogghzlhqzpfpuiatfluprsycmdrsssubvmvupcydkcmtuaipzartrubbphzldiferlzbuieetcefraflnnuytsrddcuwxevnbvryvmobuesjbkxmrplmgskmpifijstxrckcebuejfblbwrpdpvvvrbjyernqmnrvbbtvtkjftntvpjvuijffiqqlysbrrjdvtyyictbbrvbbvqirqtczeuapuclvrftldzqbzzeugsmguilflgokfftvbiysggowgoqfhkffrbbzfblftrpumqblrxprnkffgbfwcsmqmvyomjcfluznckgsmsujcequauycmgtvppnseirimgasjfenszlbvbfwgdmaeoruwuaipzajikfngaadcpvghvbpwe'"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cal = [string.ascii_lowercase[int(c, 2)] for c in chunks(sca, 5)]\n",
+    "catj = cat(cal)\n",
+    "catj"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:445: UserWarning: Matplotlib is currently using module://ipykernel.pylab.backend_inline, which is a non-GUI backend, so cannot show the figure.\n",
+      "  % get_backend())\n"
+     ]
+    },
+    {
+     "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(catj)\n",
+    "plot_frequency_histogram(fc, sort_key=fc.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'binary'"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score = vigenere_frequency_break(catj)\n",
+    "key_a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "harry had insisted we place the hole where it wouldnt be seen later i was pretty sure now that he\n",
+      "planned to claim the table for his office so he suggested we remove the makers nameplate and drill\n",
+      "there it was just as well he did the demolition charge was linked to a web of mechanical detonators\n",
+      "and almost any other direction would have disturbed atleast one of them the machinery was old and\n",
+      "the sappers werent happy working with it but mechanical mechanisms can be easier to work with than\n",
+      "electronics as you can see how everything is connected a judicious dose of superglue fixed most of\n",
+      "the mechanisms in place just leaving us with the problem of what to do with a heap of old and\n",
+      "unstable explosives normally we would have placed one or two of our own detonators and packed out\n",
+      "the place with sandbags and breeze blocks to contain the explosion and i think even harry might have\n",
+      "been convinced that that is what we should do in this case but unfortunately the explosives were not\n",
+      "the only thing we could see inside the safe sitting under them was a slim black book we couldnt see\n",
+      "any details but having got this far it seemed crazy to destroy it anything this well protected must\n",
+      "have been important at sometime and we needed to know what this might all have been about after a\n",
+      "quick callback to headquarters harry got approval to continue trying to crack the safe he knew me\n",
+      "too well to ask me to leave but the documents team retreated to a safe distance down the corridor\n",
+      "with most of the guards leaving a small team to watch over us as we worked one of them had joined\n",
+      "the sas from the sappers and was an experienced bomb disposal expert so he worked with us watching\n",
+      "the explosives for any changes monitoring vibration and temperature and generally keeping us calm it\n",
+      "takes a special temperament to do that work full time and we were glad of the company and the\n",
+      "expertise after seventeen hours we were getting tired and as eighteen approached i began to wonder\n",
+      "if we would manage to save the papers but eventually the final cog turned and the last tumbler fell\n",
+      "into place we had managed to glue the broken cog back together and with a mild protest the top\n",
+      "turned raising a platform up through the central pillar to present us with the book we had seen by\n",
+      "the light of the endoscope it was bagged and secured and harry took it with him the special forces\n",
+      "secured the entrances to the shadow archive and i left to get some sleep we met the next day to go\n",
+      "through the papers harry had started on the decrypt doing all the usual checks frequency analysis\n",
+      "index of coincidence and soon the distributions were relatively flat so it was clearly not a simple\n",
+      "caden us or substitution cipher and we started trying some of the ideas we had found in blacks\n",
+      "codebook it took us longer than we had expected but after a few days we had the entire set\n",
+      "deciphered and had begun the analysis harry had slightly different interests from me i was\n",
+      "fascinated by the insights into an older world while harry was focussed on why these documents might\n",
+      "have any contemporary significance both turned out to be important history matters and as marx said\n",
+      "it tends to repeat itself personally i would be the wasnt the first person to say it and he wont be\n",
+      "the last but for us the point was that as we read more we began to see the parallels between blacks\n",
+      "world and our own and it was not comfortable reading when we got to the back of the book all became\n",
+      "clear the book was actually a civil service report on the shadow archive closing it down and giving\n",
+      "reasons why black had been too successful and his activities had badly destabilised the balkans the\n",
+      "report traced a direct line from the bulgarian crisis to later tragedies given his early enthusiasm\n",
+      "for his new methods of shadow diplomacy i honestly believe he never meant to cost so many lives but\n",
+      "it seemed clear from the report that blacks interference in foreign domestic politics had had dire\n",
+      "consequences it looked all too familiar and if our enemies wanted to discredit us when we complained\n",
+      "about their interference in domestic politics then these papers would be the ideal kom prom at\n",
+      "material it looked like we werent just victims of these tactics we had invented some of the methods\n",
+      "ourselves back in the nineteenth century harry put out a request for analysts to work on recent\n",
+      "signals traffic to see if there was anything to suggest who was responsible for sending me on the\n",
+      "hunt for the kom prom at files there wasnt much and certainly nothing to link it to foreign\n",
+      "government action it was quite possible that this was the work of one of the criminal networks that\n",
+      "had grownup after the fall of the soviets market manipulation is a lucrative business and attacks on\n",
+      "government credibility area very effective way to move whole markets the documents stolen from the\n",
+      "archive were still out there somewhere and it was possible that they contained enough to embarrass\n",
+      "us but that seemed unlikely whoever wrote the closure report had been thorough and it didnt seem\n",
+      "likely they had left anything important on the shelves but time would tell harry set a watch in case\n",
+      "anything surfaced and asked me to keep an eye on the black markets too as i suspected the shadow\n",
+      "archive table appeared a little later in his headquarters fully restored and i assumed completely\n",
+      "disarmed i returned to the library to finish the job i had started but when they offered me a new\n",
+      "contract i refused i had a better offer the table was in an office next to harrys with my name on\n",
+      "the door\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(prettify(vigenere_decipher(catj, key_a)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "5517"
+      ]
+     },
+     "execution_count": 29,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('aa.plaintext', 'w').write(prettify(vigenere_decipher(catj, key_a)))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Part B"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "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": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'bqknmvrbqpnmvr'"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score = vigenere_frequency_break(scb)\n",
+    "key_b"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'scjwosootzadaicifetcceoiaebtdtbbdotgahlxaicorengoftzatclnfutoikivtxhskscwwmntoehnhxdgrsuqxbscsatxdlx'"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "vb = vigenere_decipher(scb, key_b)\n",
+    "vb[:100]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'pqbrvmnkqbrvmn'"
+      ]
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score = vigenere_frequency_break(cat(reversed(scb)))\n",
+    "key_b"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'oeolcqkyoeosnealcuelqsbgiheeadihtrtgkowahknspcxbntfmtcrkgffnlcwutitlatancqdqnbsusttnoczvhuaethdhtqmc'"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "vb = vigenere_decipher(cat(reversed(scb)), key_b)\n",
+    "vb[:100]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "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(vb)\n",
+    "plot_frequency_histogram(fc, sort_key=fc.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'ijfvibqowmppztsvknoz'"
+      ]
+     },
+     "execution_count": 34,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score = autokey_sa_break(scb)\n",
+    "key_b"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 37,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('confederation',\n",
+       "  <KeywordWrapAlphabet.from_largest: 3>,\n",
+       "  {'j': 'i'},\n",
+       "  'x',\n",
+       "  True),\n",
+       " -32750.60854007092)"
+      ]
+     },
+     "execution_count": 37,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "playfair_break_mp(scb, wordlist=history_words, fitness=Ptrigrams)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 40,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'fkatnxosreoqzytvgonyfynzxhygzegeurhgpxztzyicgdvlokreonvncwolrildietfchfklrztgspzraqsaqnbfmkfqkonqsqcyndysynebabnlxnvvfxgcvwsueuecopqsytbsyerfkwhrayvazyluvzoynmwyihbrnsbkadttiuehzrawpxgynugmtuhiwylpqdturuenzxqhotudpswscoldcyhgazrhgfdweopcgetrlhxtfazqwsveszadzxipyaxqxyqynmuhszwnxqssikzcslfxmwqezitieyzgzrzbcenmplrvitfziwtchyfmbboknaigsroamzoeraialaubhahfvokbttdeavxvovxrlabavauevkahraseqitfioeupvbltviidzetxtuezeraialaucheyxkrnqzaiouoxxgynswzfigwgzserdultfyclbrenmpzotmxiksoukscrivbyvbzdrhpyyficqozpdtolzfvwxgxqxqukzeaemseuurfnnziwfhbdhuurteftexavkqvaqtimdtxinbitezmrsyrzbnontqzwezhgalpffgugbutmztikvtyhsdqxmoqdttexchfudrcpitezkowpsicydykcqzaeqsfghrosxwukzwzsfuvxaenfdybnqyluecmuweiaybdemihwxqoxciruxcezaztmbzazosuvtqkzrcsyhqflvgetphpezpcashshifhxxehrrmfqscvagdvlomqmfxepmzeuwxqktcwmylmrzgrkeqehvtyhektzacdceitnztmiwicvhgzagqxelxecmugfphlwofvyxwurvieieuzydlqodvzpuagheuriictvsczdrhfglazgvnxredvtukpirlrildierhqytdgtpwqzdtruhofiqxyxyzazauevbxaftxuewdfifaacnoavemiebnyghmvslwnfhsexoxkmxcmptfwzdifhurcopnlpoprtksnepoyxsyxkztfqfkakasempktztumrhwcvospxzthyasfvrlsyvelaxcsoxgcvdzgvbayhfkvypffdhqrlxkysaeyxrzdzontymstzocteezoqdletphpezpoxztcditqocksyoheutbifkzaokczeeayoasvskwpztllwovitiexegvhyyttdyiaekuildooubhlealyssywdsrbhezynsgztgzrqscyimuhbtoywtgaemiiccpatuativnmzynmutoazxnzdzohortoqnqossbzewtitgsdemuboozzoavhbcmciyhimomavbtrlyfshfhirkwknqytofhfwxtttgseigqtnxzttbtqfpttnvxvoynaeyceiazovcaicatbdaveyqfmsrzmntoderqroxmfnaeeqvevtxfmqldcpoqiecivbitieyzoqdehzzthuerhedcreehxvfkgrrczlybgqdfmsynaekcazrnusesalltrzhqeudeahvprgyoazciuyrvtiquhgcdextbezurywosigfitaeskbrcbiebmvghfkdtabbthvnechygtyrwdcseoqdefkgrcvknlgfcitnsrmwrtaamiwwtezynqwlettteoesqrbywrznzfxtyaymdrnrzdlfnmutuiravemdtetyllazgvnxrmkiwylpqdturxepysytefklrixokigoudzbmaquruzadguyozckchghymyoushayurhxkcqyrteucwbrwfqzuaghdufklnpfxkwdhwtcbdducvosigvtchitcytimhaigqtvmcqxtzxrmyzafllalnmnxktixqsbspdurnvialflchyfnfurtezdlwifvyxwurvieieuovzcavthztuhwtrdiveqsgvietknqscdudcpmilcyfcdczdrdesemitzcouralmwueflruoedlamasoqtxfnkfctiodklmidthqxknalykmilkdnzscrwacttodyrhxytqyndnknmeztxlnfvarnqmbnbamsitdzeokcbewctlladzaeoqnqrlovpqwdlyoqdvztqsitrlwznoavfidubxfofxsmzwgqbrzoynuryvgkzwempiazdyzrflruoedlithqxaazqdqometzacesdthrcdeitzltlsdtwmzvicxwpcxvkxstzgeukbvqlfzwtedeezwhatgfxkwqazetithxkcbngqvbmpdurnvialzecwitwwurxlhypmzypixravtyubciepfuomavbtrlyfshgdbzmqkbrbdtroultzrfclailupkurobetvbgdtvthdyazurtetiauchctdrgrdtrtxfervomaveywidybezzokzkszsrbavxwpiaenonvlkoltluromrweckwhrfhaskzctesgvztdfisolyssygvrashqcevuryoyzcatsnsxwtriwztudgpetcoqydtuerhfrkqgwmwkoazbkxwetwrcmnoqyyfduzczffwdgaishemdzdrkputawosdefqvxtzelivdifbbxtrrwyfrxsfmvmifvgesyrkybybqcbtdufnmixqsblecoyxfypnlrpkitkoasgfzdzuuytcafduosadlhzgeukbwynfhsexoxlrnvavhsmytgvelacoctvbmfmuboozitpfvteieumbfkoixekcebruvbrtaeyzhyptrawpftuacpvwgktnztmiwicvhgrsflkvnyvxdexlutynonraxepcgsretoxvfhkodzxiptoqywypirtrdtpnkoerzddzbtemcvxsksriamtqlrflsbroeywaltokidrqrotrtzocmcetknchitacurzpwcrpwoescytipszwosylyqurutgsdemryhzchcdhxvgtazztuekzavtezebrwytqgbixxiutvrbvzrgdyxxyveciukpiizfqqupitithuaevmuiwvexfceuqlbywxiavwmywprxfnooxciiwchotvcnchrrbyfeuzdawsacyzhzwnrflacavhsgttrqketcodutrivxhswpialerfntlghmsererncpvielxtlurpavezpeiongleucneuldrexnonfmtzpcsegksdxwtuithxkcidrqrotrtzoccirzlwvesrmgnexpderetbfwgkwxeimnwubvmixeetckveyqbhsqmgdezpadumywtqungrknpxztyhkqaznontiycqervorlyxaomcrqeuttdzovsypypmeukqqnatqdaveidzvghiaivbadttvmbmphcvttzvycaxpiynqoefavfcbyzrzahxkcoyzdtbfgwdvlxiavwuqczpcytimhaisgtmahazwxztqmlheznswhbvdtuhwtuqahkbvltfovzteztbirdnomamwuqccdizrcnhadfiqsezynqrvbvwsysbtifvttoznzostleszaquespkriyhfqgdrcsfadeaeuayhctqqsmtosybneirhynvmkoxwoyoaztttsttsynbnftrkuzkzdroepspkzavtfkttgttzduarnxqnebazsmlanhynvmkoxwoyoazwehoqyytyvxgzetnoqinyfbhclzonetihvtpkofablkwcilcbozxckhetusesatgdetucytisnhqbphogaazwelozyxnfaeterdzyvlinimwlecodembxmbredivwavouemtautysqdrfsopyfteevdzigfbdiuiwtvsnfznbexiidrhcofsxkswufrzsdwpczdrtqdpidmayhirtztzokamyluvicwaxetfozraqscdhxqooqriosbnkacyswvupyciemsaxdtmrznzghlwtqvcavnomfuwcpzrkbcvospxztonfmaomnwldeyarzelelyubpmkpmukpiefuwbstcxnxydziorwdcsihrxqflgrdxufuefnyuaiapavhsmytgyelrcoumdtdydtdemsokynomphkayblqizrqzmidmayhcdgotttexwawxeqrnoabtynzoschfkaesttfzwfivgotzrrnzpeibccfriungrilzdwtvsezhyaflmdtzafnfyfbmuzrnzyfwbacwocslfzweiqyuswrpwteptgqdvisazdznbtbsfxofidrosezmtzeezpieznrvuqylhvgauhxavnchqboghbdwrpwrpfctwvxtudtneqitbotqketawuruldtczodbhsgtaoqwnaovhnevxftquayeaemsqzxaeoxozxcqsyqdrfkqldereudnfruafemiebnholeqofqzpidydshknzdvfyoqzruzytvgonyomufltfyhwnbmvlexkfcixettiowoqhqeayehwxgergzazivxyckkndylaywtrfbkqdpgsvtrtaztefkxcontomakptsyrkottnimtoqrzmzwrpwtsostrcfcxxcgoyiqpoxfwbafvykizzyxnofteurxweudtgqsbczzdysuldthrcdeitrgrdinvgqtconqorczpzwdcynxdwgbssyaieuzyrayhrkdopktzeruqxgateoxmexohotpwmrgvuavtksneecswpewukoxchonbatvwedudyblqezcbeyretecfvyxwurxlwnaozqitwbrceqrexncolxqoduhycdextbpixrpbefvrcamwzchinkeqigvtyhitkoaslszxztfwsixqhzemopwgthczhxzdckozcuboozevmuemcvsyxviczoiylsdtcaayvgnmfmilopixsfnyzoyuuzldhrmsmiqrrwfdweopwramxwfqknaztiyhkqivmrcalkouxeswgronairmhiedetgbywzvlkracvsdgttvuewdhbodetcornfdpttrerzrlcgyldrnxntvdeezpcoqrxavynaiactrimdthrcdeitrrwefeifrzylaconbyfzreievnqaluresfyrzfrzdhctxpeavtokuazeutqtiwscavnlewonyecztsbtlicndrwzsmvybvytqaoabyfvwoskofimptqqpmatmtyatazsdxipyaxqxyqfornmcazaogoitmgtiueieiwchysvzzxqlrzrqmvlecourozaqosaemqqxurxiuevtswyidtpbefzraegpkqldxexyidmaufaumcqfxzmadttlsyvxneosxkflaxqrgdctyfpzyhdufdmsttmieieuwtauznpbefvroqrzmzwrpwsyeigquidyhnrwfdweopcedyxwaekceiwqukvahrbscamheachdxfopwxtavfcitnsitdxrznziwsgwoizkuzkadeicgibtivinymyeangeltzocokrfawwayihrasltdetmknrykzogpemysbylsrhxdutradpmhourcornudwdhrqymsawweyeptihwoyqxwpqzsgtbrwovizngwakrebrchnswrtubrrlyfshmqyhbsmhaibechauirdlhgtfyluvezhbrtgfidfcsveywaltoqrexncpdzorywkoztydngetwrcvxlrkraqsbnvgkwknvevtqcfbqxtzvupyciemcrxcxqiwderhfgyqdrokbtliwtonpirudszpvnaqwlityndybiywhwqseyvcwytibtxqqsbahctxduutvqxwayicwfqzderhfphiecmuqeptrtezkmaegrkoopwgteyowaltdzaztrervohxywxiayrhwpraldkzzfigwgzsfrmwafpgqyhyupaherwrfeufreezychieynfhsexoxicvzvmgfwukoxcbrazttzegaxqwpkamdrezpdegmvemshiysxgqyzeovmxactuilignicwzrznkpqupzycksnepovidimaapfbngnbtltfcvtlvomlrlnoyoievtikeidlswxkzahygoerdultfyclkpurbchwcvospzrqukqzndkpqkadazezqztziaieiebrcedkhenooqrefxceurhzmoxldoavuenyxcncxwmktcemttcoboqdmttnerzdhifvbarmbpbhazzewrolzwvayhcxirfqasdeyaxcqrphrcztrsapevgavcwybigmiwonnfaznvommi'"
+      ]
+     },
+     "execution_count": 40,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "playfair_decipher(scb, 'confederation', padding_replaces_repeat=True)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 44,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('illegality', <KeywordWrapAlphabet.from_last: 2>, {'j': 'i'}, 'x', True),\n",
+       " -32581.166965728567)"
+      ]
+     },
+     "execution_count": 44,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "playfair_break_mp(scb, fitness=Ptrigrams)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 45,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'doiuzdhoufhsuxctoqmuitgwksqblaipolhfkqtluxbacqwdmiufmnrgpulezateiafbkddoeatlhqzvidozmvymdrodpnmnozkmumyuthmtnymynvgrtbvkcblhuauasfprthbnthfudorxidxvguwnnxqwumhpudmeiskhfyogatuagvidquvkumhvnapesxwnprogoluagwmzamaomchlknleycwmmpuehfbdusqxqttuaeskfbgurvhctougluszqzfmzmzrumrhbkuwzdozoivlnkbwwpvraltaiaxueveunctmopeasafblicpkdtixhxgfndchqxmbsqwfudclfeoemkpbtminbgofavbxbvbaeynczeodxfyegbofztaibmdkrgcfesacslaldaoalfudclfeokdnulyiszwdclqkzvkumhlblpgsotvfugffeitweactmopqwanszpdlqpdstashwgculgeqztibashvzogleblvwvkmzmzpalaafovauolikgwsxmhkcepolutbfdscznpzcnztzogszymtaalsytheumymnznuwalhflfrsqfhvghantlyitcwmfczmryngaadskdaqsgrftaalimquoihuyutkzwafozqfeghocvpauwtvaqvbafkiyumyrzzxtrrhuscdwhgtztxrmzkzablozhalguanvpguhonxznvltsthrwwbqetureofvzdakbkbbisksdegysdnknzccqwdyrrohdfozuauvcpntnphwnsyvecifzhatcwmhiltadycaiintlztxscbhfugyhsdnvtrrhfqreaxkavxcvolsaaiauuxetshybvzoefhauzabactknulgeqfflvergzetgtcpaxoaezateiagerzgomquqzwogloamibzmvdxugueodxypdflduaxpibfdadnmcztxiamyqbekchaxkibkdskzdqzhopfbwuscmholsfpsixqxgapdmtxqvdthlytldndoyfbotxraltaosyxrcbhokqtlmwbobtaethxdflzhohvkcblueqnywmdovxrsbdrwaelyhtafvdeulumnhnovltfsutalhsettureofvzkztlcytashktthmaaubnbivlsmtklafaukbochlczvefaxbxtaiasdeqmwnhgoudafapivmglqemoulfhtthxpoyemalumqhtlevlsknudrhmeomxwqmafztbarfiuoeatrgzuumrhomgudzulqwamgahsgzhokhlacptahqgtrhxgwqqwczmeyzabwmtzyrcznbaetikbmhazlcfnrzommhptdlaahqaiyhinlpaanbndrqinvbxbumafuhaigubxdabaiukccznundoveurbomgtlsxmwpikaffzxdtcdhorterfhsiaabgctaiaxuhsgtgvtlepfuahycufhabvdorltsiwwhyhdbovumaftkguisfxtolffeeurwaugtkpxklrukguabnsbzatrnhfcydsbnalolxwhopgibuitoietsayygxyfhdoogynnbcwmtkdqbhnirycothsgtdorlcbfnykiqtakoysriuibssxcpalumrvouaautmdzocaxweugwhdhncuwyiseuetikrhaoazcztxogtuwnflvergzeqdsxwnprogolsdqzthutdoeazsmipglqluhxmvolwacovhukwltkhfmwpzlqkbcuolsktkrzgaaupuactpzwoefhgfdoklrslyxpxrtnkcgfcbhopgtckdtahuatkedcyhctzyzmltzepzugwbflklrblyatmzkhwogfissalfwbkdtikiolutulaxbivxcvolsaaiaubxwlczentlpecpgsasfzqhsatufnozcyfgrfztewticylwsggtotztltsfollfhpuawblomdetbsbohsldikodntqgdytwcsenzmfnlfnoztyegdtvstrmntomyugedvznumgdfnxttlvnkizcisromynyovtaludmtkgyupefflluafhsgzaebxprxpnwhsybtloztaaewunmczibgfypakhdvouwyhacqwumolxvyvuwtxxoguyuuewblomdettarwmfgungshxtltadtoogegcyailtfefwogphuvbacvfrbvylbhveauiercbwuwutgtalrxiufqlyvrgututasktkmyyhgcopgfissalflaputawwolvnmwpouxxozeczhnhgabfoaqyrcznbaetikbcqvporiecaogxmxzltifwedczxraolgxtugccqctenyuguolutateokdntsgrloggadhfuxbsbxdxwcswhalqwvlpdtvcaczcvxoafnmgryeleefolyrirtrlcegmhbovlnttoeqtldbiolehttheqidkbkmdxolukxudahbkocvagsxtlfgqvtusfrzoguagefinposhpimgueicvturiyznmrztigfwlblptqcdckbtxlusgaroamrhogtdnvbltuoasscbmypagirtieztdxyztbtipthciwhwhkmnbgfikztmzkhousfvditpsearataimbofqulawnstndfgfhocoebveauiewxkibkdskzeagrczbkpzqmxdflsfntgcrdrhxgwqtarstcaiauxhdogqsdtkyglogcgaafxumwrqidqubfoerfvwyvintlztxscbhfyowbytmuvbgtvnoaummnidsdfrhqufombvmhimluszrqhsxwzqazagogpsimfuullunbtxcbbppdzabszneawbkhxmnurmfemicslsxmagltfszytufnkdtaadolvzupexsqtohuatowuwhownzroloahqgtsywmwldkedbvmqgutluavlczutlaacwxznmlzsszoazbcguecqvddvxdabpaxoildnrnxoatenoedxrhsxxddhrtnrcexwszczphxwxedhnmkzabsxkdmobctfegcatiauulmrobhuvguwsiwbadczbkmqagpntusfgfagaskshlxolffuikeffhovfufutfkxianvefolpqxdvzaimnkyauftauteufdzmndrltfrotyvfccvaotasktkcslsxmagltfsabeuaxxdoyqymtqkgtufbnptyvvcairbvscgztsdtuktxdzremzoqygtvzcohrxwznkwrlfnkqtlwmnpgunmnidumkfuxbaevdsmzylsauaalubxthqzpoaunpzgiungczailuqeigdcgccoaayxhxrecbaauvuhfmxoumshbgcziqhwueugsktkkuulbnqfxpwdszczvskmvzhuatkedcqhankpguvctlroebalkorxcgogpecpnrkpiewdfbbxtlalbnazgdyrbsvskmcyiltsescoibozalumslgcvwthkhatbtaawqgwhoeftougrntorazawmdncqtstdcofaaucudkznoznahowhmtazmwgrqdkzsqukguaahbaathymkiagaplvulxmfowovlczfbqnqmaauloeismzmtnytvwtnlmwgrqdkzsqukguusamrznhxvvklainhsgltiemweqwmtatcwqrimfdeclcabewxgplktahaootobqmgtaohuatokrwxcammpguuseluxdzfdtufuluxvvilghpousfgtxhwpactgasrmxbuanaeohnzosgdtqxtiutdxlupgbmscvacpchkiwggyszcsgesfdtlyhlqaeufcqulwsgznmccssbwmazltltmibswnnxbarmsdfbwqidozcyskshhszahomyfyhuhlxnqzabtxobzlaneugwfhaxznbccznmrdsvrfueiecbhokqtlmndrsmrbxagtuceuuouosnxcqdpopaxobgsvhktndzdvluqgirycoiegmzwbrllzqauaiksndcqpczbkpzqmuneasfhrogyuoggtovmiumyrrefywhfvillsuzcssbwmcyoqaautcvmrsdslnmynhngwhokddoafbhfbuwibqemoueisvzaincqizakwrlivulcpchalmwdftwogugikitbmrhuegwtixladsqnkbwuwairzfxriuqutrqyhybioguluymbntdzkibsghoalnalaalxoalsixnrzebqeeoskcztfrwxgfhkcriuqexiqpcvbaoogmtzibnmopntumrolxzoglwgmemqhuihsursmwcmtvbbfrncufatxzoplafkzwqzhozzrsgdovfgtuffgkilodftxiamyamoushdnvzcsuykbfnultbukzwlouxctoqmuyrqafeitxrymxyoulyiqzstuatqshsrwfaunxrvkfuevguasdvktfnyuflxwagbmnpmchqtcgaguutdozhmnomsbarhbubimaalgnahseuzuriuqhbhoagqihzzhoqudrpkzptnybtnoiluxdzkautolcvauogyhkhlwulhtxzogegcyaiagrlscgryhtnmnshtsvzuwycumzlsohkthdcauuxidwmcimgraltfunrvkiudmwpdsmamouqsyeqoetcpdmttrhlofvsimzhamymiuvwtgfgwhfvalcnnuufutqivxcvolvnursmwztaxltsfzufdzsfnvshgfmwcydsbnxozecxbgzbdahpwlignffzpgtcwmtaimbofwpltlptoimzgvtxqxsoenlwskulktwqgkxgwqdxrhtxcbthbvbaqwdufwogdacuqebrdrivqxzstdmuqwsnwateegovztslirbdusqxribscvdnfnguatwmnpassydayelqsdhlrlmndcysigtgtumlxwuvyeidcbfcmqctuaxpmegmtusfisbdrqagfuueewbqteisdzctgtalfrhsezczumdcadagtzogegcyaiagirbgaifiuxflsfymtiueaidxgzlfoltoiteufiuldkldofczomapguauznatlhdargousqmutrtlkhefbadgirtvxywhvxznsmyntivwhoimibopznrpsbanhniugufcszqzfmzmzrakiszygusmoqtaqyatuaiasxkdhtvuplvfeulsxyousfolwqmvhoaforzmolszuatchludogcxbgueafqvnptesddvcssbqaeozyndlpsbogefthvbmtholywbfmslcqnttizvwmgfbdovaaztaiaucpeowgcxbgzbhseuzuriuqthaiyhvayuseirbdusqxrtyucvaftkaivrpazceghkdakefakdlzakuqdlcziqtakotalzeugwsxqhsqilaplvcoaiqtyaatsamupzfapfuoltfsmiifmrrmudegbofegtanfnbuvlqoofpzkhwnoyskgfagcopoamolsfisfgxpegrzovmrusunrqgisqzrcvprtvmqacsqsawgosyfufackdkoriaoacaetikborwmhkkedcgykdeoazethffbwnnxalmegafqcsiqhcnurmfehsufdzrflumxxwimtluypfturicbvnciidozmyqelcfnxdtckmbmzmltxnqzabtxstzhmzsxgtgeqfzrsgminbvicpmnxolocfvzrgmvxataumyuayxwxroznubcwxatnbmzoznydkldgfoarccvcubatpzwgtgesrigtrrhzfrqgaaldqafrlimqxsoutukrmfeluguagfuxbskxwszcugequidtevlblpgsotvfihpdfvqrzmwkrkpfurigbqaufaluhignukibkdskzbavuyxfqvsimzhacguaalampmzqufywyufvzgtyqxdovightvkrzlabxpwadaoivpglgpuuewgarrnzvuhpdmtxqsascsbqpbmpfymeffbcbefxbwtaenmukiatcyiaiethllyugmwoqfugffeitwearolncxrcbhozvlspazwdgarpncogualzwltcdiaiaacrtdyahnmhsufhdrtolgvryvnmgczuamuzhtfcvqdtntxaasfxgngnainfuuligbtnyysxcemgularileuwzcwmhzazdnbogtuczhslretstlyoqpdxmpbcwxayyqsxmnkigugryrzt'"
+      ]
+     },
+     "execution_count": 45,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "playfair_decipher(scb, 'illegality', padding_replaces_repeat=True)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 53,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['najtst',\n",
+       " 'pf',\n",
+       " 'noj',\n",
+       " 'xeftxfrpydzvp',\n",
+       " 'qhkjpoljekwqn',\n",
+       " 'jyw',\n",
+       " 'bzrbedzv',\n",
+       " 'gf',\n",
+       " 'noj',\n",
+       " 'evocxf']"
+      ]
+     },
+     "execution_count": 53,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "wb = [sanitise(w) for w in cb.split()]\n",
+    "revwb = [cat(reversed(w)) for w in wb]\n",
+    "revwb[:10]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(14, 1.8149082143679982),\n",
+       " (7, 1.7876483819003524),\n",
+       " (19, 1.139130739823884),\n",
+       " (17, 1.13573597102418),\n",
+       " (18, 1.134286347801864),\n",
+       " (16, 1.1340666011499847),\n",
+       " (15, 1.1267151614528168),\n",
+       " (12, 1.1195770233467919),\n",
+       " (13, 1.1170033049862185),\n",
+       " (10, 1.1113107848108488),\n",
+       " (11, 1.1048189745296602),\n",
+       " (8, 1.1029139212676535),\n",
+       " (9, 1.0992610408639947),\n",
+       " (6, 1.0930448274541635),\n",
+       " (5, 1.0887236952605512),\n",
+       " (4, 1.0883432346550446),\n",
+       " (3, 1.080300997704784),\n",
+       " (2, 1.0772346205630585),\n",
+       " (1, 1.0724609207862228)]"
+      ]
+     },
+     "execution_count": 30,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "list(sorted([(i, sum(index_of_coincidence(s) for s in every_nth(scb, i)) / i) for i in range(1, 20)], key=lambda p: -p[1]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "splits = every_nth(scb, 7)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 41,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "split_keys = [simulated_annealing_break(s, fitness=Pletters, workers=30) for s in splits]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 42,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[('jbgefzqtpklmvhdirawuocnyxs', -1091.5171683341368),\n",
+       " ('thlusayeimnzkvdxprqjbwfgco', -1111.6585001154554),\n",
+       " ('lzhvijedwmngbrcfapoxqtysku', -1096.256469009839),\n",
+       " ('akqinpbrysuvmjgochfexldwzt', -1091.5681079945684),\n",
+       " ('zwmgpslitbvnqafyejkdorxuch', -1096.8999003685785),\n",
+       " ('stkgohqvclfdiyjarxmnzbpewu', -1111.829016643045),\n",
+       " ('fvtrkghuyxqjsncipbwzedlamo', -1102.4516201102704)]"
+      ]
+     },
+     "execution_count": 42,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "split_keys"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 43,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "p_splits = [keyword_decipher(c, k) for  (c, (k, _)) in zip(splits, split_keys)]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 44,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "HEVNNT AI TSE EHTOGRHORCEHT, EMYEDTAPEOENS IIR HTOHMHAV AC TSE OROUNG ONLRACE; BITR HELNPMEIDIAIAHN.\n",
+      "BOR YAMH ECEO AHLK. TSIH IEWORT FON LOUPISNOOIEU PF TSE MAIEOYI OELHETONB TS IEYSST SH TSE\n",
+      "HTHMLAUSEN AND HLTACAAIES SB TSE JMOSA-HAUEGENDEOT AHTEWDNPENME NYEHLG, TRE NRIDSF OHLSHBE,\n",
+      "REIEOMTEH IEFESIED TN HH TRE IRLRNYE. TSE SEGNDA LAHTAAIO SEDNUUEOUOTANAH WSI IMTIAIS LNALEHHAIV TRE\n",
+      "ADMDIGE, AH BEDD OS I TUMCOIC NM DENSOIO DEOINER YISY IIHDVNOH NM ITN ALAIGNTOET. IT OLSO MSOTOONT H\n",
+      "PIAEF TUMCOIC NM TRE LWRNEHT AHTETS SB TSE NIDRAPE NHU IEMSMCEHMOTIAIS IT TA TRE WTE AI UOHYSHOL NF\n",
+      "ADASE AHTETS. TRE TDNUSP IRLRNYE AT HO NIDEYEOUEHT HATELUACEOLE AYEALV NET WF PV TRE YNIGOTE\n",
+      "TELIETIRY TA RED UHXENTC JUEEI CAMTAIAA AI TRE LATE EIYRTEEATR DENAUSV. AT GOO ESTAPLIHRED TN\n",
+      "LAHUMLA OWIYEALWNHDE IIR TA DADRY AMT LOPEST UOVLSMOTOL OLTNSHH DEHNPHED TA WMITSES TRE AITEIESTT SY\n",
+      "REI UOXESTK’H CSGEHHUEAT, FRORE FSAYOMHAV OI EREPEHT NF YWNMNOPLE UEIOIVIDNTK AI TRE ECEIT TROT AAO\n",
+      "NLTOBHTIEN PERE UNNLOPESEU. SLOAT USLWUEOTOTANA HTAUR EJISTS FRSM TROH TTNYE NF ADE ENTIVWISRYEIT AW\n",
+      "TRE ONLRACE, ADAMPR YHBEH TRE DEDNDATE ANTMIE NM ITN NVENNTANNT, IT COK PE TROT CERY YEB SWMD\n",
+      "UADMUEATS BEDE EGEH PDHTTEI. TSE MEF TRIA RA IEYIHA NIE GC IHTMHE VRIGOTE LNPMMIOLOTIAIS IIR\n",
+      "CEHSOIHD IELORRH. NI WIRTILMUIR TREHE IYFEOHS TN DNGE GEEA N LSIDEOCAIDEILE PETGEEO REI UOXESTK IIR\n",
+      "LROIREO VIEK LNALEHHAIV TRE HEER YAH SWMD NH SIYOAISOTANA, TRSMYS SODF A FEG AW TROTE DETTERO NIE NN\n",
+      "FIDE AH TSE CIACIAE SAFAR MSDDELTHSO. NT OH TUSCASED TROT NTSES DETTENH LSHLENONIF TSE SEDIWHTMEIT\n",
+      "OF CDODV IT TRE CODTT REOD OF TRE OILSIGE WMHA DNGE EXHOTEU, GWA HO EITARE PAX NF DSLMWENAO YISY\n",
+      "TSHT BEIANR IS WOHTIOY BOTS AA NIDEX MIDE TO AEDD MS GSHT NT LOITNNIEM. NUS NICETTIYOTANAH NITO\n",
+      "VWNLK SSNG TROT SE GNS HEROTEU TN YREB, OID TSHT RE IEAUSHED FRSM PSSTNA MONSIMDWSETTT TA TOVE WF\n",
+      "SENOMEALE AH RNAUAI. RAT IMCEDAOTE WOYALY FEHE NNT FEOUTSY, TRSMYS DE ROD PEEO O HEROTIGEUC\n",
+      "TULLESHFUD LHOUHAND AH TSE WHATED OTOTEH, OAU LSHTEPCAHADG NELSIMT OWYPEHA TROT RE SHU ENTIVWISREM\n",
+      "HAUEGENDEOT WEIIO. OA HELNNU AC RAT EMBLNCUEOT DAN VE YAMHM, SSFEYED TEGEHAR NM TRE EXAHOT UNLWPEHTS\n",
+      "FRSM YHEC’T FEINNNOW LALUEMTIAI RAIT TROT PLHLK BAH RELIMOTER NS RED UHXENTC’T MIINT HELSET\n",
+      "SEMNETOIC, TS TRE APTEOLE NF OAB USLWUEOTOTANA IS MHHWNCIASAIV. PDOLK KECT O WEROAHOU JNUSHOU GSILR\n",
+      "DNNAHIHED HNPE NITEREHTAHY DETOAUH, CIGNIF WT OACE ONTIVRT ONAS RNN WEROAHOUAAY, NHU OT HO LDEAD\n",
+      "ADNT RE TSNIGED OI HUGEHTWNE. MIBORTWHOTELY, TRE COLUMEN IELHTNIF TN DIS GEDHSU NI UOIRAH OIE OWHA\n",
+      "WOHTIOY, NN GE LNHINT REDV SH TSEM TS BALW IH TRE UIHSAHY DETOAUH NM RNN IEMNWNTYEIT TA TRE ONLRACE.\n",
+      "ISOETRELEHS O HWUCEI SB WISYWALAOW SEDNDDO MOAHTOIOEU GC UEMPEIH NM TRE BOREIYI SEMNETOIC’T\n",
+      "REBOITUEOT NMYCEHT TRIA TRE EJATTEHDE OF TRE OILSIGE, BRALE AWCOLHHDDF DEIIEU, BAH KAAFI TO O OMOLU\n",
+      "NWPPEH NF UEMPEIH NM TRE ONAEDDAFEILE LSYUWAITF ON LSOUSH. AI FNITOLWWNI TRE EOTOVUATDMEIT OF\n",
+      "DEOUXWONTEHS AI OLATUIIR BOHD GOO N IEUIAIGELK OYEO SELDET, CIESWUHPDF GEMHWSE TSE FADALE ADECNERPEH\n",
+      "FEIE OGNIE TSOT HAWETSIOY MHWTUND BAH CSIHP NN, ADAMPR TSE OOWE IIR NLTOBHTIEN NF ADE AHFIIIHOTOOI\n",
+      "GEIE A LLSHELK YWHSUED HELSET. TSE ANCE SSORAF OILSIGE UNET AAT OWVEHS AI ANG SYWALAOW UADMUEATS\n",
+      "CIOU TRE GEDHSU. ON TSE OLOLE OF CDODV’H NFEIOTANAH YHEG HA TRE YAD EIYRTEEA HEYENAIES, HMUNUSS SB\n",
+      "AAO NLTOBHTIEN ARTS VIEP IIR IT NEEUO TA RABE CEEI TSHO, NS WMLS HH TRE NEEU TS EHAHPDASS O OELMIE\n",
+      "LSLOTOOI MAI ROH CNAFAHY MSDDELTHSO AC ONAEDDAFEILE BOWERO, TROT HEEMS TN SOBE DED PLHLK TN TSE\n",
+      "UEYERNFMEIT OF TRE MHMENVISMND WNPFIAITR PEHEOTR TRE CONU. TRE EXTSOSIMHANIF LOTT AW TRAT LAMLD NNT\n",
+      "PE GIOYESDF LOILEOLEM OAU TROH LEU TS XWEOTNSHH HA TRE ROWOE FROLS IO TMIN, HM BAM PALW EXDMHE TRE\n",
+      "GMN, DNAGE TSE HSLROBE MWITRER UOUEIYRSWHU. TSNOE YSCERAMEIT UHAISTIAEO FRALS SHU RATSENTA VEEI\n",
+      "CEHEBAMINIAEH NM TRE ONAEDDAFEILE UOTI OAU OIARGOIS GIODULEU GC VWNLK’S OYESOTOBEO OAB LOUFDETERG\n",
+      "RISTANMEU TREUTEDGES, IIR RE NEEUO TA RABE CELSYE OA NDWNHA EOTAIELY YIEE ICEOT, NETAIOY ROH NGO\n",
+      "BSUAAILOL AND RIBLNUOTIL PNILO FNTR TSE TODOT TUCBSIT NM TRE WILHLE. UMDHAV TROH YESNSD, PLHLK BAH\n",
+      "FSLMNSED WNIPERG SO UESTOCIDASAIV SMNSAOA, VEHYII HOU OMHANIOI OUYESNOUATT EXGANTIAH AH TSE POLVIIO\n",
+      "SEPOOI, HOU SH TSE OEED TN FSATELA TRE WEMHTEIHANEHO THAME NAMTEH. SE HEEYH AS ROYE MEBEDSWED HO\n",
+      "EXTEIOIGE HEAGAIK NF OVEHTS AI TRE HEYHSO, PMT UNNE NWWORTNHTUC AS ROYE MEBEDSWED AEF WETSSUS SB\n",
+      "GNNKNIF. GSIDE DUITOILOU MHFDAWALG DNU OUGOYH IEUAER AH ESVHSOOPE, PLHLK ESTOCDNNRED AEF DNBENT\n",
+      "CETSNRH TS DATNWBT TSE RIBLNUOTIL OLTHBITAEH NM CATENAIND SWVNOITANN, VY CDOLAIV NYEHTT GITRON ADENH\n",
+      "GWRENMDIIMIES. DNNANADLONC TRE OFEIRN AC OUYSSTOHT HATEHHIAIAHOU UEETNIFH, SE FON APLE, NT LEITT IH\n",
+      "GADA, TA LSHTRSD TRE OWTLAWE OF AEYSTAOTIAIS, IIR TA VENEMIT CIOU IOSADE KAAFLEMCE AW TROTE\n",
+      "UELOPENNTANNT. DE ROD VONTNDMRON HMDLETO UMHONC TRE GEDHSU AC TSE CWDPADHHO OID POWKOIS LRIHEN\n",
+      "DATNWBTONC TRE OURHHOLE GWHWUNIF PETFEEH TSE TRHEE EPCEHNDT. IY RE RID NESTIAMTEU ROUTEDW TN\n",
+      "EIVNYAHY BITR TRE UHXAH WOBESS AH TSIH FOK SHO SEDNDD GAMLD SOBE PEEN REVOHDED HH O NOYIIYNDANA\n",
+      "OWLDEHT HOU TRE TUPTLETG SY RAS UETRAUS UOY FELU SOBE FSH SHP YIAENDO IH ROYS VAGEINUEOT. TRE\n",
+      "TKIDCMR BHB NI PSHLR RE YIIICMLATER IHTEDIHTNSHIL LAHYENAIAHN TO NUS PEHEFIT OT CERY DNTTRE LAST ON\n",
+      "LIGEN WDNPISED TN EHTOGRHOR O IEG BHB AC PORKIHP GC TUPTEIFWVE NISTEHU AC PIR. UOWSITWANTEUC SIH\n",
+      "GALTNNIEN ENMSWIOFED H MAHE DELKDESH OFCISALS HOU RE HEEMS TN SOBE EXWRNNEU WNDE EQTHEUE BEINOOIO AW\n",
+      "DNBENT UAWRNPNLF. RERE SEDNDDO NT TRE ONLRACE AEDD O YORE LAWWRETE STNDG, TRAMFS FSS IEAHNAH TRAT\n",
+      "BIDD VELNPE LLEIR IO O WNUEAT, FE RIPE LRSSEI TA IEYOPE NHU LROOHNCK, OR IO SSYE MHHEN DETTSAF,\n",
+      "TSNOE USLWUEOTN PSHLR HOIDOTE NT. TSENE NN LREHS EYOMEALE TRIA CDODV HET WB MHAAO FNTRAI TRE OILSIGE\n",
+      "TN WIREITAKE GROT RIPE PEDNUE KOABH IT CDODV OYESOTOOIO. (NS OH ITIUE, TRE ETBCSUOCY AW TRIA ANCE\n",
+      "PIT AAT DUEON WHTOR ADE OHLSHBE FOS WILAGEIED.) TRENE HYELNOUATEU NI GROLKCOOR, VNIPEIC OAU\n",
+      "BSUAAILOL AYHTNTANN. BDIDE TSENE OHE NN NELSIMT SY RAFSEN LIAYET CENIF IWTRAHOHER PV TRE ONLRACE,\n",
+      "ADE ODTAPIHTN TSEY FAHVED GITR PERE OAT APNBE CMIMEN, NHU OT HO JMATE YNAPOGRE TROT TSHO ROU GEMSME\n",
+      "OHOADEI TNOL SY TRE NETFAHV. TSE DADAR CNAMGS HWFCAHTED CB TRE IRLRNYE GENE BOITHLWDOIRG HLTACE HA\n",
+      "TRE GILKNH NTIAEH OT TSE EOU SB TSE ONIETEEOTR LEITWIF, AND CDODV FNLWSNEM NA TIFONC TA UASDWFT\n",
+      "IMSHHHO EXWIIOIAI GC TSFNIF MHOLAHD IUSOY VARKHO HOTANANDASTT. CDODV HEEMS TN SOBE IETAREU WHNU ADE\n",
+      "OHLSHBE OHNWIR TRE TAUE AW YOLASSNO’S MEHTR, RNGEBEI ROH TULLESHNNH LSHTHAWEU RAT GAIK AND GE ROCE\n",
+      "WALAYEDER EGADEILE AC A SHVRDF ALAIGE PIOWF FAHVAIV WHUED MSUE IAUE HSLRANCED NI TSE NEYANN ONAMID\n",
+      "NHAETEEN AGEDYE. WIMAITMNOTEDF, OT TEECN TSOT TRE SSORAF OILSIGE IETBSSK BAH VY TRAS HAHVE\n",
+      "NMVYSSTAHY ONMEU ONTUSIELTHSO NI TSE NEYANN, OAU FE GELIEGE TSOT ITN ALAIAHN YIG DNGE LOITSNVMTER,\n",
+      "NT LEITT IHUODELTDF, TO ADE EYENAO DEODAIV TA TRE FISST PORWU FOI. TSIH WOLT OWAHE LOWWU LOMHE\n",
+      "LAHNOMENNPLE EUCNIHAHTPEHT TO ADE MK FOPESHWENA HOU BE FEED FE RIPE OA SWTHSO PMT TN NELSYUEAU TRAT\n",
+      "ADE SRAMNG NIDRAPE NHU ARL ITS IETBSSKN SSNUDU VE GNUOU MW, AAO UADMUEATS OHILYHEU, LROOHNCOED, HOU,\n",
+      "AB NELESNADG, RESTIOGEU, OID AAO NSNETT RISGNHER AW. TRAT NEBSIT TDAMLD ILOA IEYIHA LDOSHHMIEU BOR H\n",
+      "CEHOOD SY OT UEOOT SECEITB-WACE GENIN. PE BSWDU IEMSMCEHM O FWPLOLOTIAI DIAE AW TPO ADAMNAND HOU\n",
+      "TPEITB-WACE OT EOHUAEOT. NI TSE PEOITAUE, IT NROWWU PE WDEOEIYEM WOIHP TSE DIYREHA OELMIAAY\n",
+      "NGOOROCDE; AT GNUDU CNDU TRE WNHA LACGIOUIHNIF UOTEIAAR HM IT NROWWU WOUR HATA EHEUY ROIDH.\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(repunctuate(combine_every_nth(p_splits), ptb).split())))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 48,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[{'f': 'e',\n",
+       "  'u': 't',\n",
+       "  'd': 'o',\n",
+       "  'j': 'a',\n",
+       "  'p': 'i',\n",
+       "  'h': 'n',\n",
+       "  'w': 'h',\n",
+       "  't': 's',\n",
+       "  'a': 'r',\n",
+       "  'e': 'd',\n",
+       "  'm': 'l',\n",
+       "  'o': 'u',\n",
+       "  'v': 'm',\n",
+       "  'n': 'w',\n",
+       "  'x': 'y',\n",
+       "  'g': 'c',\n",
+       "  'z': 'f',\n",
+       "  'q': 'g',\n",
+       "  'i': 'p',\n",
+       "  'b': 'b',\n",
+       "  'c': 'v',\n",
+       "  'l': 'k',\n",
+       "  'y': 'x'},\n",
+       " {'s': 'e',\n",
+       "  'j': 't',\n",
+       "  'd': 'o',\n",
+       "  'i': 'a',\n",
+       "  't': 'i',\n",
+       "  'v': 'n',\n",
+       "  'q': 'h',\n",
+       "  'e': 's',\n",
+       "  'r': 'r',\n",
+       "  'u': 'd',\n",
+       "  'z': 'l',\n",
+       "  'b': 'u',\n",
+       "  'k': 'm',\n",
+       "  'f': 'w',\n",
+       "  'l': 'y',\n",
+       "  'c': 'c',\n",
+       "  'a': 'f',\n",
+       "  'y': 'g',\n",
+       "  'x': 'p',\n",
+       "  'h': 'b',\n",
+       "  'w': 'v',\n",
+       "  'n': 'k',\n",
+       "  'g': 'x',\n",
+       "  'm': 'j'},\n",
+       " {'i': 'e',\n",
+       "  'x': 't',\n",
+       "  'l': 'o',\n",
+       "  'c': 'a',\n",
+       "  'w': 'i',\n",
+       "  'r': 'n',\n",
+       "  'd': 'h',\n",
+       "  'o': 's',\n",
+       "  'p': 'r',\n",
+       "  'v': 'd',\n",
+       "  'g': 'l',\n",
+       "  'q': 'u',\n",
+       "  'b': 'm',\n",
+       "  'y': 'w',\n",
+       "  'h': 'y',\n",
+       "  'k': 'c',\n",
+       "  'e': 'f',\n",
+       "  'j': 'g',\n",
+       "  'f': 'p',\n",
+       "  't': 'b',\n",
+       "  'z': 'v',\n",
+       "  's': 'k',\n",
+       "  'n': 'x',\n",
+       "  'm': 'j'},\n",
+       " {'n': 'e',\n",
+       "  'a': 't',\n",
+       "  'e': 'o',\n",
+       "  'g': 'a',\n",
+       "  'y': 'i',\n",
+       "  'j': 'n',\n",
+       "  'r': 'h',\n",
+       "  'f': 's',\n",
+       "  'h': 'r',\n",
+       "  'i': 'd',\n",
+       "  'v': 'l',\n",
+       "  'x': 'u',\n",
+       "  'm': 'm',\n",
+       "  'd': 'w',\n",
+       "  'z': 'y',\n",
+       "  'q': 'c',\n",
+       "  'b': 'f',\n",
+       "  'p': 'g',\n",
+       "  'o': 'p',\n",
+       "  'k': 'b',\n",
+       "  'l': 'v',\n",
+       "  'u': 'k',\n",
+       "  'w': 'x',\n",
+       "  's': 'j'},\n",
+       " {'p': 'e',\n",
+       "  'd': 't',\n",
+       "  'f': 'o',\n",
+       "  'z': 'a',\n",
+       "  't': 'i',\n",
+       "  'a': 'n',\n",
+       "  'k': 'h',\n",
+       "  'i': 's',\n",
+       "  'j': 'r',\n",
+       "  'g': 'd',\n",
+       "  'n': 'l',\n",
+       "  'o': 'u',\n",
+       "  'q': 'm',\n",
+       "  'x': 'w',\n",
+       "  'c': 'y',\n",
+       "  's': 'c',\n",
+       "  'm': 'f',\n",
+       "  'y': 'g',\n",
+       "  'w': 'p',\n",
+       "  'l': 'b',\n",
+       "  'r': 'v',\n",
+       "  'v': 'k',\n",
+       "  'u': 'x',\n",
+       "  'b': 'j'},\n",
+       " {'o': 'e',\n",
+       "  'n': 't',\n",
+       "  'j': 'o',\n",
+       "  's': 'a',\n",
+       "  'c': 'i',\n",
+       "  'y': 'n',\n",
+       "  'm': 'h',\n",
+       "  'x': 's',\n",
+       "  'v': 'r',\n",
+       "  'g': 'd',\n",
+       "  'd': 'l',\n",
+       "  'z': 'u',\n",
+       "  'i': 'm',\n",
+       "  'p': 'w',\n",
+       "  'w': 'y',\n",
+       "  'h': 'c',\n",
+       "  'k': 'f',\n",
+       "  'q': 'g',\n",
+       "  'a': 'p',\n",
+       "  't': 'b',\n",
+       "  'b': 'v',\n",
+       "  'f': 'k',\n",
+       "  'e': 'x',\n",
+       "  'l': 'j',\n",
+       "  'r': 'q'},\n",
+       " {'k': 'e',\n",
+       "  'z': 't',\n",
+       "  'c': 'o',\n",
+       "  'f': 'a',\n",
+       "  'y': 'i',\n",
+       "  'n': 'n',\n",
+       "  'w': 'h',\n",
+       "  'u': 's',\n",
+       "  'b': 'r',\n",
+       "  'r': 'd',\n",
+       "  'j': 'l',\n",
+       "  'e': 'u',\n",
+       "  's': 'm',\n",
+       "  'l': 'w',\n",
+       "  'm': 'y',\n",
+       "  't': 'c',\n",
+       "  'g': 'f',\n",
+       "  'h': 'g',\n",
+       "  'i': 'p',\n",
+       "  'v': 'b',\n",
+       "  'd': 'v',\n",
+       "  'q': 'k',\n",
+       "  'a': 'x'}]"
+      ]
+     },
+     "execution_count": 48,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "split_counts = [collections.Counter(s) for s in splits]\n",
+    "split_maps = [{c: p for ((c, _), (p, _)) in zip(s.most_common(), english_counts.most_common())} for s in split_counts]\n",
+    "split_maps"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 74,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "split_trans = [''.maketrans(sm) for sm in split_maps]\n",
+    "split_plain = [s.translate(st) for (s, st) in zip(splits, split_trans)]\n",
+    "split_plain;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 76,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# print(repunctuate(combine_every_nth(split_plain), ptb))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 71,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def repack(punctuation):\n",
+    "    def ischar(elem):\n",
+    "        return elem in ['UPPER', 'LOWER']\n",
+    "    \n",
+    "    repacked = []\n",
+    "    for p, np in zip(punctuation, (punctuation[1:] + [' '])):\n",
+    "        if ischar(p):\n",
+    "            if ischar(np):\n",
+    "                repacked += [p, ' ']\n",
+    "            elif np == ' ':\n",
+    "                repacked += [p, '*']\n",
+    "            else:\n",
+    "                repacked += [p, np]\n",
+    "#         elif p == ' ':\n",
+    "#             repacked += ['*', ' ']\n",
+    "    return repacked\n",
+    "        "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 72,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'A B;C D*'"
+      ]
+     },
+     "execution_count": 72,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "repunctuate('abcd', repack(['UPPER', 'UPPER', ';', ' ', 'UPPER', 'UPPER', ' ', 'UPPER']))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 81,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "   etoainhsrdlumwycfgpbvkxjqz\n",
+      "0: fudjphwtaemovnxgzqibcly\n",
+      "1: sjditvqeruzbkflcayxhwngm\n",
+      "2: ixlcwrdopvgqbyhkejftzsnm\n",
+      "3: naegyjrfhivxmdzqbpokluws\n",
+      "4: pdfztakijgnoqxcsmywlrvub\n",
+      "5: onjscymxvgdzipwhkqatbfelr\n",
+      "6: kzcfynwubrjeslmtghivdqa\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "ms = '   ' + cat(p[0] for p in english_counts.most_common()) +'\\n'\n",
+    "for i, c in enumerate(split_counts):\n",
+    "    ms += '{}: {}\\n'.format(i, cat(p[0] for p in c.most_common()))\n",
+    "print(ms)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 48,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[{'f': 'e',\n",
+       "  'u': 't',\n",
+       "  'd': 'o',\n",
+       "  'j': 'a',\n",
+       "  'p': 'i',\n",
+       "  'h': 'n',\n",
+       "  'w': 'h',\n",
+       "  't': 's',\n",
+       "  'a': 'r',\n",
+       "  'e': 'd',\n",
+       "  'm': 'l',\n",
+       "  'o': 'u',\n",
+       "  'v': 'm',\n",
+       "  'n': 'w',\n",
+       "  'x': 'y',\n",
+       "  'g': 'c',\n",
+       "  'z': 'f',\n",
+       "  'q': 'g',\n",
+       "  'i': 'p',\n",
+       "  'b': 'b',\n",
+       "  'c': 'v',\n",
+       "  'l': 'k',\n",
+       "  'y': 'x'},\n",
+       " {'s': 'e',\n",
+       "  'j': 't',\n",
+       "  'd': 'o',\n",
+       "  'i': 'a',\n",
+       "  't': 'i',\n",
+       "  'v': 'n',\n",
+       "  'q': 'h',\n",
+       "  'e': 's',\n",
+       "  'r': 'r',\n",
+       "  'u': 'd',\n",
+       "  'z': 'l',\n",
+       "  'b': 'u',\n",
+       "  'k': 'm',\n",
+       "  'f': 'w',\n",
+       "  'l': 'y',\n",
+       "  'c': 'c',\n",
+       "  'a': 'f',\n",
+       "  'y': 'g',\n",
+       "  'x': 'p',\n",
+       "  'h': 'b',\n",
+       "  'w': 'v',\n",
+       "  'n': 'k',\n",
+       "  'g': 'x',\n",
+       "  'm': 'j'},\n",
+       " {'i': 'e',\n",
+       "  'x': 't',\n",
+       "  'l': 'o',\n",
+       "  'c': 'a',\n",
+       "  'w': 'i',\n",
+       "  'r': 'n',\n",
+       "  'd': 'h',\n",
+       "  'o': 's',\n",
+       "  'p': 'r',\n",
+       "  'v': 'd',\n",
+       "  'g': 'l',\n",
+       "  'q': 'u',\n",
+       "  'b': 'm',\n",
+       "  'y': 'w',\n",
+       "  'h': 'y',\n",
+       "  'k': 'c',\n",
+       "  'e': 'f',\n",
+       "  'j': 'g',\n",
+       "  'f': 'p',\n",
+       "  't': 'b',\n",
+       "  'z': 'v',\n",
+       "  's': 'k',\n",
+       "  'n': 'x',\n",
+       "  'm': 'j'},\n",
+       " {'n': 'e',\n",
+       "  'a': 't',\n",
+       "  'e': 'o',\n",
+       "  'g': 'a',\n",
+       "  'y': 'i',\n",
+       "  'j': 'n',\n",
+       "  'r': 'h',\n",
+       "  'f': 's',\n",
+       "  'h': 'r',\n",
+       "  'i': 'd',\n",
+       "  'v': 'l',\n",
+       "  'x': 'u',\n",
+       "  'm': 'm',\n",
+       "  'd': 'w',\n",
+       "  'z': 'y',\n",
+       "  'q': 'c',\n",
+       "  'b': 'f',\n",
+       "  'p': 'g',\n",
+       "  'o': 'p',\n",
+       "  'k': 'b',\n",
+       "  'l': 'v',\n",
+       "  'u': 'k',\n",
+       "  'w': 'x',\n",
+       "  's': 'j'},\n",
+       " {'p': 'e',\n",
+       "  'd': 't',\n",
+       "  'f': 'o',\n",
+       "  'z': 'a',\n",
+       "  't': 'i',\n",
+       "  'a': 'n',\n",
+       "  'k': 'h',\n",
+       "  'i': 's',\n",
+       "  'j': 'r',\n",
+       "  'g': 'd',\n",
+       "  'n': 'l',\n",
+       "  'o': 'u',\n",
+       "  'q': 'm',\n",
+       "  'x': 'w',\n",
+       "  'c': 'y',\n",
+       "  's': 'c',\n",
+       "  'm': 'f',\n",
+       "  'y': 'g',\n",
+       "  'w': 'p',\n",
+       "  'l': 'b',\n",
+       "  'r': 'v',\n",
+       "  'v': 'k',\n",
+       "  'u': 'x',\n",
+       "  'b': 'j'},\n",
+       " {'o': 'e',\n",
+       "  'n': 't',\n",
+       "  'j': 'o',\n",
+       "  's': 'a',\n",
+       "  'c': 'i',\n",
+       "  'y': 'n',\n",
+       "  'm': 'h',\n",
+       "  'x': 's',\n",
+       "  'v': 'r',\n",
+       "  'g': 'd',\n",
+       "  'd': 'l',\n",
+       "  'z': 'u',\n",
+       "  'i': 'm',\n",
+       "  'p': 'w',\n",
+       "  'w': 'y',\n",
+       "  'h': 'c',\n",
+       "  'k': 'f',\n",
+       "  'q': 'g',\n",
+       "  'a': 'p',\n",
+       "  't': 'b',\n",
+       "  'b': 'v',\n",
+       "  'f': 'k',\n",
+       "  'e': 'x',\n",
+       "  'l': 'j',\n",
+       "  'r': 'q'},\n",
+       " {'k': 'e',\n",
+       "  'z': 't',\n",
+       "  'c': 'o',\n",
+       "  'f': 'a',\n",
+       "  'y': 'i',\n",
+       "  'n': 'n',\n",
+       "  'w': 'h',\n",
+       "  'u': 's',\n",
+       "  'b': 'r',\n",
+       "  'r': 'd',\n",
+       "  'j': 'l',\n",
+       "  'e': 'u',\n",
+       "  's': 'm',\n",
+       "  'l': 'w',\n",
+       "  'm': 'y',\n",
+       "  't': 'c',\n",
+       "  'g': 'f',\n",
+       "  'h': 'g',\n",
+       "  'i': 'p',\n",
+       "  'v': 'b',\n",
+       "  'd': 'v',\n",
+       "  'q': 'k',\n",
+       "  'a': 'x'}]"
+      ]
+     },
+     "execution_count": 48,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "split_counts = [collections.Counter(s) for s in splits]\n",
+    "split_maps = [{c: p for ((c, _), (p, _)) in zip(s.most_common(), english_counts.most_common())} for s in split_counts]\n",
+    "split_maps"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 82,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "SEBNNT AI TSE ERTOGRHOSCEST, EMYEDTOPEOENH IIR RTOSMHAV AC TSE OSOUNF ANLRAYE; BITR SELNGMEIDITIASN.\n",
+      "BAR YAMS EYEO ASLK. TSIR IEWART CON LAUGIHNOAIEU PF TSE MAIEOCI OELSETANB TH AEYHHT HS TSE\n",
+      "RTSMLTUHEN IND SLTAYOTIEH HB TSE JMOHO-HAUEGENDEOT ASTEWDNPENME NYESLF, TSE NRIDHC OSLSHPE,\n",
+      "REAEAMTES AEGEHIED TN SR TRE IRLSNYE. TSE HEGNDT LASTIOIO HEDNUUEOUOTONAR WHA IMTIAIH LNALESSOIV TRE\n",
+      "IDMDIGE, IH BEDD OH I OUMCOAY NM DENHAIO DEOANER YIHC IISDVNOH NM ITN ILTIGNTOEO. IT OLHA MHOTOONO S\n",
+      "PIAEG OUMCOAY NM TRE LWRNEST IHOETH HB TSE NIDROPE NSU AEMHMCESMATIAIH IO TA TRE WOE AI UOHYHROL NG\n",
+      "TDAHE IHOETH. TRE ODNUHP IRLSNYE OO SO NIDEYEOUEST HATELUOCEOLE ICEALV NET WC PV TRE YNIGOTE\n",
+      "OELIETIRY TA RED USXENTY JUEEI YOMTAIAI OI TSE LITE EIYRTEEATR DENTUHV. AT FAO EHTIPLIRRED TN\n",
+      "LASUMLT OWIYEOLWNSDE IIR TA DIDRY AMT LAPEHT UOBLHMOTOL ALTNHSH DERNPSED TA WMATSEH TRE OITEIEHTO HY\n",
+      "REA UAXEHTK’H CHGESSUEAT, FRORE CHAYOMHAV OI EREGEST NG YWNMNOPLE UEIOIVIDNTK OI TSE EYEIT TROT OTO\n",
+      "NLTOVHTIEN PERE UNNLAPEHEU. HLAAT UHLWUEOTOTONA RTAUR EJIHTH GRHM TROH OTNYE NG TDE ENTIVWIHRCEIT AW\n",
+      "TRE ANLRAYE, TDAMPR CHPES TRE DEDNDITE ANTMAE NM ITN NBENNTANNO, IT COK PE TSOT YERY YEB HWMD\n",
+      "UADMUEATH BEDE EGES PDHTTEI. TSE MEF TRIT RA IECIHA NIE GY ISTMSE BRIGOTE LNGMMIOLATIAIH IIR\n",
+      "FESHAISD IELARRR. NI WIRTILMUIR TSESE IYCEOSH TN DNGE GEEA N LHADEOFAIDEILE PETFEEO REA UAXEHTK IIR\n",
+      "LROAREO VIEK LNALESSOIV TRE SEER YAS HWMD NS HACAAIHOTONA, TRHMCS HODF I GEB AW TRAOE DETTERO NIE NN\n",
+      "GIDE AS TSE FIAYITE HAFIR MHDDELTHHO. NT OH OUHCAHED TSOT NTSEH DETTENR LHSLENONIF TSE HEDAWHTMEIT\n",
+      "AG FDODV IO TSE CODOT SEOD AG TSE OALSIGE WMHT DNGE EKHOTEU, GWT SO EITORE PAX NG DHLMWENTO YIHC\n",
+      "TSST BEAONR IH WOHOIOY BOTS AA NIDEX MIDE TA TEDD MH FSST NT LAITNNIEM. NUH NIYEOTIYOTONAR NITA\n",
+      "VWNLK HSNB TROT SE BNH SERATEU TN CREB, OID TSST RE AETUHSED GRHM PHHTNA MONHIMDWHETTO TA TOVE WC\n",
+      "HENOMEALE AS RNAUAI. ROO IMCEDOATE WOCOLY CESE NNT CEOUTSY, TRHMCS DE ROD PEEO O SERATIGEUY\n",
+      "OULLEHHGUD LSOUHAND AS TSE WSATED OTOTEH, AAU LHSTEGFASIDF NELHAMO OWYPEHT TSOT RE SSU ENTIVWIHREM\n",
+      "HAUEGENDEOT WEIIO. OA SELNNU AC ROO EMBLNYUEOT DIN VE YAMSM, SHCEYED OEGESIR NM TRE EKTSOT UNLWGESTH\n",
+      "GRHM YSEY’O CEINNNAW LALUEMTIAI ROIT TROT PLSLK BIH RELIMOTER NH RED USXENTY’O MIINT HELHET\n",
+      "HEMNETOAY, OH TRE IPOEOLE NG AAB UHLWUEOTOTONA IH MSHWNFIAHOIV. PDOLX KEFT O WEROASOU JNUHSOU FSILR\n",
+      "DNNTSISED HNGE NITERERTASC DETOAUH, CIGNIF WO OACE ONOIVRT ONTH SNN WEROASOUOTY, NSU OT HO LDEID\n",
+      "TDNT RE TSNIGED AI SUGESTWNE. MIBARTWSOTELY, TRE YALUMEN AELSTNIF TN DIH GEDHHU NI UAIRAS OAE AWRA\n",
+      "WOHOIOY, NN FE LNSINT REDV HS TSEM TH BOLW IS TRE UIRHASC DETOAUH NM SNN AEMNWNTCEIT TA TRE ANLRAYE.\n",
+      "IHOETRELERH O SWUFEI HB WIHYWALOAW HEDNDDO MOASTAIOEU GY UEMPEAH NM TRE BAREIYI HEMNETOAY’O\n",
+      "REBOATUEOT NMCCERT TRIT TSE EJOOTESDE AG TSE OALSIGE, BROLE AWCOLHSDDF DEIIEU, BIH KAAFI TA A OMOLU\n",
+      "NWGPES NG UEMPEAH NM TRE ONTEDDAFEILE LHCUWAITF ON LHOUHS. OI CNITOLWWNI TRE EOTOVUOODMEIT AG\n",
+      "DEOUXWANTESH OI OLATUIIR BOSD FAO N IEUITIGELK AYEO HELDET, FIEHWUSPDF GEMSWHE TSE CADALE TDECNERPER\n",
+      "FEAE ABNIE TSAT RAWETSIOY MSWOUND BIH CHISP NN, TDAMPR TSE OOWE IIR NLTOVHTIEN NG TDE ASFIIIROTOAI\n",
+      "BEIE I LLHRELK CWSHUED HELHET. TSE ANCE HSARAF OALSIGE UNEO AAT OWBESH AI INF HYWALOAW UADMUEATH\n",
+      "CAAU TSE GEDHHU. ON TSE OLOLE AG FDODV’H NCEIOTONAR YSEF HA TRE COD EIYRTEEA REYENTIEH, SMUNUHH HB\n",
+      "OTO NLTOVHTIEN IROH VIEP IIR IT NEEUO TA RIVE FEEI TSHO, NH WMLS SR TRE NEEU TH EHTSPDAHS A OELMAE\n",
+      "LHLOTOAI MAI ROH CNAFASC MHDDELTHHO AC ONTEDDAFEILE BOWERO, TROT HEEMH TN SAPE DED PLSLK TN TSE\n",
+      "UEYERNCMEIT AG TSE MSMENVIHMND WNPFAOITS PESEATS TRE YANU. TRE EXTHOHAMHANIF LAOT AW TROO LAMLD NNT\n",
+      "PE GAAYEHDF LAILEOLEM AAU TROH LEU TH XWEOTNHSH HA TRE RAWOE FROLS IO TMAN, HM BAM POLW EXDMHE TSE\n",
+      "GMN, DNAGE TSE SHLROVE MWITRER UOUEACRHWSU. TSNOE YHYERAMEIT UHAIHTAOEO CRALS SSU RATSENTA VEEI\n",
+      "FESEBOMINIAEH NM TRE ONTEDDAFEILE UOTI AAU OIIRFOIH GAADULEU GY VWNLK’H AYEHOTOVEO OAB LAUCDETERF\n",
+      "RIHTINMEU TREUOEDGEH, IIR SE NEEUO TA RIVE FELHCE AA NDWNHT EOTAAELY YIEE ICEOT, NETTIOY ROH NBO\n",
+      "BHUOTILOL IND RIBLNUATIL PNILO CNTR TSE TODOT OUFBHAT NM TRE WILSLE. UMDHAV TROH YEHNHD, PLSLK BIH\n",
+      "GHLMNHED WNIPERF HO UEHTAFIDAHOIV HMNHOAA, VESCII SOU OMHTNIOI OUYEHNOUOOT EXGINOIAS AS TSE POLVIIO\n",
+      "HEPOAI, SOU HS TSE OEED TN CHATELT TSE WEMHTEISINESO TSIME NAMTEH. SE REECH TH SOYE MEPEDHWED SO\n",
+      "EXTEIOIGE SETBAIK NG AVESTH OI TSE SECHHO, PMT UNNE NWWARTNSTUY TH SOYE MEPEDHWED AEF WETSHUH HB\n",
+      "FNNKNIF. FSIDE DUIOOILOU MHCDAWILF DNU OUFAYR IEUOER AS EHBHHOOPE, PLSLK EHTAFDNNRED AEF DNVENT\n",
+      "CETSNRR TH DOONWBT TSE RIBLNUATIL OLTHPITAEH NM FATENTIND HWBNOITANN, VY FDOLOIV NYESTO BITRON TDENS\n",
+      "GWRENMDAIMIEH. DNNTNADLONC TSE OFEIRN AC OUYHHTOST HATESSITIASOU UEETNIFH, SE CON IPLE, NT LEIOT IS\n",
+      "GIDT, TA LHSTRHD TRE AWTLAWE AG AEYHTOATIAIH, IIR TA VENEMIT CAAU IOHADE KAAFLEMCE AW TRAOE\n",
+      "UELOPENNTANNO. DE ROD BANTNDMRAN RMDLEOO UMSONC TSE GEDHHU AC TSE FWDPIDHSO OID PAWKOIH LRIREN\n",
+      "DOONWBTONC TSE OURHSOLE GWHWUNIF PETCEES TSE TRSEE EGFESNDO. IY RE RID NEHTAOMTEU ROUOEDW TN\n",
+      "EIVNYASC BITR TRE USXAS WABEHH AS TSIR FOK SHO HEDNDD BAMLD SAPE PEEN REVOSDED SR O NOCIIYNDINT\n",
+      "OWLDEHO SOU TRE OUPTLETF HY RAH UETSAUH UAY CELU SAPE FHS SHG YIAENDO IS ROCS VAGEANUEOT. TRE\n",
+      "OKIDCMR BSB NI PSHLS RE CIIIFMLITER ISTEDISTNHSIL LASYENTIASN TA NUH PESEGIT OT YERY DNTTRE LAHT ON\n",
+      "LIGEN WDNGIHED TN ERTOGRHOS O IEF BSB AC PARKISP GY OUPTEAGWVE NIHTESU AC PIR. UOWHATWANTEUY SIR\n",
+      "GALTNNIEN ENMHWIOFED S MASE DELKDEHH ACFIHILS SOU RE HEEMH TN SAPE EXWRNNEU WNDE EQTSEUE PEINOAIO AW\n",
+      "DNVENT UAWRNGNLF. RERE HEDNDDO NT TRE ANLRAYE TEDD O CARE LAWWRETE HTNDF, TSAMFS GHH IEIHNAR TRIT\n",
+      "BIDD VELNGE LLEIR IO O WNUEAT, FE RIPE LRHHEI TA IECAPE NSU LRAORNCK, AR IO HHCE MSREN DEOTHAF,\n",
+      "TSNOE UHLWUEOTN PSHLS SOADATE NT. TSENE NN LRESH EYOMEALE TRIT FDODV HET WB MSOTO CNTROI TSE OALSIGE\n",
+      "TN WIREITIXE BSOT RIPE PEDNUE KOABS IO FDODV AYEHOTOAIO. (NH OS IOIUE, TRE ETBCHUACY AW TRIT ANCE\n",
+      "PIO AAT DUEAN WSTOR TDE OSLSHPE FOH WILAGEAED.) TSENE HYELNOUOOEU NI GRALKCOOR, VNIPEAY AAU\n",
+      "BHUOTILOL ICHTNTANN. BDIDE TSENE OSE NN NELHAMO HY RAFSEN LIACEO FENIF IWTSASOHER PV TRE ANLRAYE,\n",
+      "TDE ODTOPIRTN TSEY CASVED BITR PERE OAT IPNPE CMAMEN, NSU OT HO JMATE YNAPOGRE TSOT TSHO SOU GEMHME\n",
+      "OSATDEI TNAL HY TRE NETCASV. TSE DADIR CNAMGH HWCFASTED FB TRE IRLSNYE FENE BOATHLWDOARF SLTAYE HA\n",
+      "TRE GILKNS NTITER OT TSE EOU HB TSE ONIETEEOTR LEITWIF, IND FDODV GNLWHNEM NA TIFONC TA UAHDWCT\n",
+      "IMHHHSO EXWIIOIAI GY OHCNIF MHOLASD IUHOY VIRKSO SOTONANDAHTO. FDODV HEEMH TN SAPE IETOREU WSNU TDE\n",
+      "OSLSHPE OSNWIR TRE TOUE AW YOLTHHNO’H MESTR, RNFEPEI ROH OULLEHHNNR LHSTHAWEU ROO BAIK IND BE ROYE\n",
+      "WALAYEDER EGADEILE AC I SHVSDF ILTIGE PAAWC CASVOIV WSUED MHUE IIUE SHLRINCED NI TSE NEYANN ANAMID\n",
+      "NHAETEEN TBEDYE. WIMAITMNATEDF, OT OEECN TSAT TRE HSARAF OALSIGE IETBHHK BIH VY TRAH HTSVE\n",
+      "NMBYHHTASC ANMEU ONOUHIELTHHO NI TSE NEYANN, AAU FE GELIEGE TSAT ITN ILTIASN CIF DNGE LAITHNVMTER,\n",
+      "NT LEIOT ISUODELTDF, TA TDE EYENTO DEODOIV TA TRE GIHHT PARWU FOA. TSIR WOLT AWASE LAWWU LOMHE\n",
+      "LASNOMENNPLE EUFNISIHOGEST TA TDE MK FAPEHSWENT SOU BE GEED FE RIPE OA HWTHHO PMT TN NELHCUEAU TRIT\n",
+      "TDE HRIMNB NIDROPE NSU IRL ITH IETBHHKN HSNUDU VE FNUOU MW, OTO UADMUEATH OSILYREU, LRAORNCOED, SOU,\n",
+      "AB NELEHNIDF, REHTAAFEU, OID OTO NHNETO RIHGNHER AW. TROO NEBHAT ODAMLD ILOA IECIHA LDOHHHMIEU BAR S\n",
+      "FESOAD HY OT UEAOT HEYEITB-WAYE FENIN. PE BHWDU AEMHMCESM A CWPLOLATIAI DITE AW TPA TDAMNIND SOU\n",
+      "TPEITB-WAYE AT EOSUOEOT. NI TSE GEOITOUE, IT NRAWWU PE WDEOEIYEM WOISP TSE DIYREHT OELMAOTY\n",
+      "NGOORAFDE; AT FNUDU CNDU TSE WNHT LACGAAUIRNIF UATEIAIR HM IT NRAWWU WOUR HATA ESEUY SOIDH.\n"
+     ]
+    }
+   ],
+   "source": [
+    "# chunks(repunctuate(combine_every_nth(split_plain), repack(ptb)), 14)\n",
+    "print(lcat(tpack(repunctuate(combine_every_nth(split_plain), ptb).split())))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 129,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['S E B N N T*A I*T S E*E R T O G R H O S C E S T,E M Y E ',\n",
+       " 'D T O P E O E N H*I I R*R T O S M H A V*A C*T S E*O S O ',\n",
+       " 'U N F*A N L R A Y E;B I T R*S E L N G M E I D I T I A S ',\n",
+       " 'N.B A R*Y A M S*E Y E O*A S L K.T S I R*I E W A R T*C O ',\n",
+       " 'N*L A U G I H N O A I E U*P F*T S E*M A I E O C I*O E L ',\n",
+       " 'S E T A N B*T H*A E Y H H T*H S*T S E*R T S M L T U H E ',\n",
+       " 'N*I N D*S L T A Y O T I E H*H B*T S E*J M O H O-H A U E ',\n",
+       " 'G E N D E O T*A S T E W D N P E N M E*N Y E S L F,T S E*',\n",
+       " 'N R I D H C*O S L S H P E,R E A E A M T E S*A E G E H I ',\n",
+       " 'E D*T N*S R*T R E*I R L S N Y E.T S E*H E G N D T*L A S ',\n",
+       " 'T I O I O*H E D N U U E O U O T O N A R*W H A*I M T I A ',\n",
+       " 'I H*L N A L E S S O I V*T R E*I D M D I G E,I H*B E D D*',\n",
+       " 'O H*I*O U M C O A Y*N M*D E N H A I O*D E O A N E R*Y I ',\n",
+       " 'H C*I I S D V N O H*N M*I T N*I L T I G N T O E O.I T*O ',\n",
+       " 'L H A*M H O T O O N O*S*P I A E G*O U M C O A Y*N M*T R ',\n",
+       " 'E*L W R N E S T*I H O E T H*H B*T S E*N I D R O P E*N S ',\n",
+       " 'U*A E M H M C E S M A T I A I H*I O*T A*T R E*W O E*A I*',\n",
+       " 'U O H Y H R O L*N G*T D A H E*I H O E T H.T R E*O D N U ',\n",
+       " 'H P*I R L S N Y E*O O*S O*N I D E Y E O U E S T*H A T E ',\n",
+       " 'L U O C E O L E*I C E A L V*N E T*W C*P V*T R E*Y N I G ',\n",
+       " 'O T E*O E L I E T I R Y*T A*R E D*U S X E N T Y*J U E E ',\n",
+       " 'I*Y O M T A I A I*O I*T S E*L I T E*E I Y R T E E A T R*',\n",
+       " 'D E N T U H V.A T*F A O*E H T I P L I R R E D*T N*L A S ',\n",
+       " 'U M L T*O W I Y E O L W N S D E*I I R*T A*D I D R Y*A M ',\n",
+       " 'T*L A P E H T*U O B L H M O T O L*A L T N H S H*D E R N ',\n",
+       " 'P S E D*T A*W M A T S E H*T R E*O I T E I E H T O*H Y*R ',\n",
+       " 'E A*U A X E H T K’H*C H G E S S U E A T,F R O R E*C H A ',\n",
+       " 'Y O M H A V*O I*E R E G E S T*N G*Y W N M N O P L E*U E ',\n",
+       " 'I O I V I D N T K*O I*T S E*E Y E I T*T R O T*O T O*N L ',\n",
+       " 'T O V H T I E N*P E R E*U N N L A P E H E U.H L A A T*U ',\n",
+       " 'H L W U E O T O T O N A*R T A U R*E J I H T H*G R H M*T ',\n",
+       " 'R O H*O T N Y E*N G*T D E*E N T I V W I H R C E I T*A W*',\n",
+       " 'T R E*A N L R A Y E,T D A M P R*C H P E S*T R E*D E D N ',\n",
+       " 'D I T E*A N T M A E*N M*I T N*N B E N N T A N N O,I T*C ',\n",
+       " 'O K*P E*T S O T*Y E R Y*Y E B*H W M D*U A D M U E A T H*',\n",
+       " 'B E D E*E G E S*P D H T T E I.T S E*M E F*T R I T*R A*I ',\n",
+       " 'E C I H A*N I E*G Y*I S T M S E*B R I G O T E*L N G M M ',\n",
+       " 'I O L A T I A I H*I I R*F E S H A I S D*I E L A R R R.N ',\n",
+       " 'I*W I R T I L M U I R*T S E S E*I Y C E O S H*T N*D N G ',\n",
+       " 'E*G E E A*N*L H A D E O F A I D E I L E*P E T F E E O*R ',\n",
+       " 'E A*U A X E H T K*I I R*L R O A R E O*V I E K*L N A L E ',\n",
+       " 'S S O I V*T R E*S E E R*Y A S*H W M D*N S*H A C A A I H ',\n",
+       " 'O T O N A,T R H M C S*H O D F*I*G E B*A W*T R A O E*D E ',\n",
+       " 'T T E R O*N I E*N N*G I D E*A S*T S E*F I A Y I T E*H A ',\n",
+       " 'F I R*M H D D E L T H H O.N T*O H*O U H C A H E D*T S O ',\n",
+       " 'T*N T S E H*D E T T E N R*L H S L E N O N I F*T S E*H E ',\n",
+       " 'D A W H T M E I T*A G*F D O D V*I O*T S E*C O D O T*S E ',\n",
+       " 'O D*A G*T S E*O A L S I G E*W M H T*D N G E*E K H O T E ',\n",
+       " 'U,G W T*S O*E I T O R E*P A X*N G*D H L M W E N T O*Y I ',\n",
+       " 'H C*T S S T*B E A O N R*I H*W O H O I O Y*B O T S*A A*N ',\n",
+       " 'I D E X*M I D E*T A*T E D D*M H*F S S T*N T*L A I T N N ',\n",
+       " 'I E M.N U H*N I Y E O T I Y O T O N A R*N I T A*V W N L ',\n",
+       " 'K*H S N B*T R O T*S E*B N H*S E R A T E U*T N*C R E B,O ',\n",
+       " 'I D*T S S T*R E*A E T U H S E D*G R H M*P H H T N A*M O ',\n",
+       " 'N H I M D W H E T T O*T A*T O V E*W C*H E N O M E A L E*',\n",
+       " 'A S*R N A U A I.R O O*I M C E D O A T E*W O C O L Y*C E ',\n",
+       " 'S E*N N T*C E O U T S Y,T R H M C S*D E*R O D*P E E O*O*',\n",
+       " 'S E R A T I G E U Y*O U L L E H H G U D*L S O U H A N D*',\n",
+       " 'A S*T S E*W S A T E D*O T O T E H,A A U*L H S T E G F A ',\n",
+       " 'S I D F*N E L H A M O*O W Y P E H T*T S O T*R E*S S U*E ',\n",
+       " 'N T I V W I H R E M*H A U E G E N D E O T*W E I I O.O A*',\n",
+       " 'S E L N N U*A C*R O O*E M B L N Y U E O T*D I N*V E*Y A ',\n",
+       " 'M S M,S H C E Y E D*O E G E S I R*N M*T R E*E K T S O T*',\n",
+       " 'U N L W G E S T H*G R H M*Y S E Y’O*C E I N N N A W*L A ',\n",
+       " 'L U E M T I A I*R O I T*T R O T*P L S L K*B I H*R E L I ',\n",
+       " 'M O T E R*N H*R E D*U S X E N T Y’O*M I I N T*H E L H E ',\n",
+       " 'T*H E M N E T O A Y,O H*T R E*I P O E O L E*N G*A A B*U ',\n",
+       " 'H L W U E O T O T O N A*I H*M S H W N F I A H O I V.P D ',\n",
+       " 'O L X*K E F T*O*W E R O A S O U*J N U H S O U*F S I L R*',\n",
+       " 'D N N T S I S E D*H N G E*N I T E R E R T A S C*D E T O ',\n",
+       " 'A U H,C I G N I F*W O*O A C E*O N O I V R T*O N T H*S N ',\n",
+       " 'N*W E R O A S O U O T Y,N S U*O T*H O*L D E I D*T D N T*',\n",
+       " 'R E*T S N I G E D*A I*S U G E S T W N E.M I B A R T W S ',\n",
+       " 'O T E L Y,T R E*Y A L U M E N*A E L S T N I F*T N*D I H*',\n",
+       " 'G E D H H U*N I*U A I R A S*O A E*A W R A*W O H O I O Y,',\n",
+       " 'N N*F E*L N S I N T*R E D V*H S*T S E M*T H*B O L W*I S*',\n",
+       " 'T R E*U I R H A S C*D E T O A U H*N M*S N N*A E M N W N ',\n",
+       " 'T C E I T*T A*T R E*A N L R A Y E.I H O E T R E L E R H*',\n",
+       " 'O*S W U F E I*H B*W I H Y W A L O A W*H E D N D D O*M O ',\n",
+       " 'A S T A I O E U*G Y*U E M P E A H*N M*T R E*B A R E I Y ',\n",
+       " 'I*H E M N E T O A Y’O*R E B O A T U E O T*N M C C E R T*',\n",
+       " 'T R I T*T S E*E J O O T E S D E*A G*T S E*O A L S I G E,',\n",
+       " 'B R O L E*A W C O L H S D D F*D E I I E U,B I H*K A A F ',\n",
+       " 'I*T A*A*O M O L U*N W G P E S*N G*U E M P E A H*N M*T R ',\n",
+       " 'E*O N T E D D A F E I L E*L H C U W A I T F*O N*L H O U ',\n",
+       " 'H S.O I*C N I T O L W W N I*T R E*E O T O V U O O D M E ',\n",
+       " 'I T*A G*D E O U X W A N T E S H*O I*O L A T U I I R*B O ',\n",
+       " 'S D*F A O*N*I E U I T I G E L K*A Y E O*H E L D E T,F I ',\n",
+       " 'E H W U S P D F*G E M S W H E*T S E*C A D A L E*T D E C ',\n",
+       " 'N E R P E R*F E A E*A B N I E*T S A T*R A W E T S I O Y*',\n",
+       " 'M S W O U N D*B I H*C H I S P*N N,T D A M P R*T S E*O O ',\n",
+       " 'W E*I I R*N L T O V H T I E N*N G*T D E*A S F I I I R O ',\n",
+       " 'T O A I*B E I E*I*L L H R E L K*C W S H U E D*H E L H E ',\n",
+       " 'T.T S E*A N C E*H S A R A F*O A L S I G E*U N E O*A A T*',\n",
+       " 'O W B E S H*A I*I N F*H Y W A L O A W*U A D M U E A T H*',\n",
+       " 'C A A U*T S E*G E D H H U.O N*T S E*O L O L E*A G*F D O ',\n",
+       " 'D V’H*N C E I O T O N A R*Y S E F*H A*T R E*C O D*E I Y ',\n",
+       " 'R T E E A*R E Y E N T I E H,S M U N U H H*H B*O T O*N L ',\n",
+       " 'T O V H T I E N*I R O H*V I E P*I I R*I T*N E E U O*T A*',\n",
+       " 'R I V E*F E E I*T S H O,N H*W M L S*S R*T R E*N E E U*T ',\n",
+       " 'H*E H T S P D A H S*A*O E L M A E*L H L O T O A I*M A I*',\n",
+       " 'R O H*C N A F A S C*M H D D E L T H H O*A C*O N T E D D ',\n",
+       " 'A F E I L E*B O W E R O,T R O T*H E E M H*T N*S A P E*D ',\n",
+       " 'E D*P L S L K*T N*T S E*U E Y E R N C M E I T*A G*T S E*',\n",
+       " 'M S M E N V I H M N D*W N P F A O I T S*P E S E A T S*T ',\n",
+       " 'R E*Y A N U.T R E*E X T H O H A M H A N I F*L A O T*A W*',\n",
+       " 'T R O O*L A M L D*N N T*P E*G A A Y E H D F*L A I L E O ',\n",
+       " 'L E M*A A U*T R O H*L E U*T H*X W E O T N H S H*H A*T R ',\n",
+       " 'E*R A W O E*F R O L S*I O*T M A N,H M*B A M*P O L W*E X ',\n",
+       " 'D M H E*T S E*G M N,D N A G E*T S E*S H L R O V E*M W I ',\n",
+       " 'T R E R*U O U E A C R H W S U.T S N O E*Y H Y E R A M E ',\n",
+       " 'I T*U H A I H T A O E O*C R A L S*S S U*R A T S E N T A*',\n",
+       " 'V E E I*F E S E B O M I N I A E H*N M*T R E*O N T E D D ',\n",
+       " 'A F E I L E*U O T I*A A U*O I I R F O I H*G A A D U L E ',\n",
+       " 'U*G Y*V W N L K’H*A Y E H O T O V E O*O A B*L A U C D E ',\n",
+       " 'T E R F*R I H T I N M E U*T R E U O E D G E H,I I R*S E*',\n",
+       " 'N E E U O*T A*R I V E*F E L H C E*A A*N D W N H T*E O T ',\n",
+       " 'A A E L Y*Y I E E*I C E O T,N E T T I O Y*R O H*N B O*B ',\n",
+       " 'H U O T I L O L*I N D*R I B L N U A T I L*P N I L O*C N ',\n",
+       " 'T R*T S E*T O D O T*O U F B H A T*N M*T R E*W I L S L E.',\n",
+       " 'U M D H A V*T R O H*Y E H N H D,P L S L K*B I H*G H L M ',\n",
+       " 'N H E D*W N I P E R F*H O*U E H T A F I D A H O I V*H M ',\n",
+       " 'N H O A A,V E S C I I*S O U*O M H T N I O I*O U Y E H N ',\n",
+       " 'O U O O T*E X G I N O I A S*A S*T S E*P O L V I I O*H E ',\n",
+       " 'P O A I,S O U*H S*T S E*O E E D*T N*C H A T E L T*T S E*',\n",
+       " 'W E M H T E I S I N E S O*T S I M E*N A M T E H.S E*R E ',\n",
+       " 'E C H*T H*S O Y E*M E P E D H W E D*S O*E X T E I O I G ',\n",
+       " 'E*S E T B A I K*N G*A V E S T H*O I*T S E*S E C H H O,P ',\n",
+       " 'M T*U N N E*N W W A R T N S T U Y*T H*S O Y E*M E P E D ',\n",
+       " 'H W E D*A E F*W E T S H U H*H B*F N N K N I F.F S I D E*',\n",
+       " 'D U I O O I L O U*M H C D A W I L F*D N U*O U F A Y R*I ',\n",
+       " 'E U O E R*A S*E H B H H O O P E,P L S L K*E H T A F D N ',\n",
+       " 'N R E D*A E F*D N V E N T*C E T S N R R*T H*D O O N W B ',\n",
+       " 'T*T S E*R I B L N U A T I L*O L T H P I T A E H*N M*F A ',\n",
+       " 'T E N T I N D*H W B N O I T A N N,V Y*F D O L O I V*N Y ',\n",
+       " 'E S T O*B I T R O N*T D E N S*G W R E N M D A I M I E H.',\n",
+       " 'D N N T N A D L O N C*T S E*O F E I R N*A C*O U Y H H T ',\n",
+       " 'O S T*H A T E S S I T I A S O U*U E E T N I F H,S E*C O ',\n",
+       " 'N*I P L E,N T*L E I O T*I S*G I D T,T A*L H S T R H D*T ',\n",
+       " 'R E*A W T L A W E*A G*A E Y H T O A T I A I H,I I R*T A*',\n",
+       " 'V E N E M I T*C A A U*I O H A D E*K A A F L E M C E*A W*',\n",
+       " 'T R A O E*U E L O P E N N T A N N O.D E*R O D*B A N T N ',\n",
+       " 'D M R A N*R M D L E O O*U M S O N C*T S E*G E D H H U*A ',\n",
+       " 'C*T S E*F W D P I D H S O*O I D*P A W K O I H*L R I R E ',\n",
+       " 'N*D O O N W B T O N C*T S E*O U R H S O L E*G W H W U N ',\n",
+       " 'I F*P E T C E E S*T S E*T R S E E*E G F E S N D O.I Y*R ',\n",
+       " 'E*R I D*N E H T A O M T E U*R O U O E D W*T N*E I V N Y ',\n",
+       " 'A S C*B I T R*T R E*U S X A S*W A B E H H*A S*T S I R*F ',\n",
+       " 'O K*S H O*H E D N D D*B A M L D*S A P E*P E E N*R E V O ',\n",
+       " 'S D E D*S R*O*N O C I I Y N D I N T*O W L D E H O*S O U*',\n",
+       " 'T R E*O U P T L E T F*H Y*R A H*U E T S A U H*U A Y*C E ',\n",
+       " 'L U*S A P E*F H S*S H G*Y I A E N D O*I S*R O C S*V A G ',\n",
+       " 'E A N U E O T.T R E*O K I D C M R*B S B*N I*P S H L S*R ',\n",
+       " 'E*C I I I F M L I T E R*I S T E D I S T N H S I L*L A S ',\n",
+       " 'Y E N T I A S N*T A*N U H*P E S E G I T*O T*Y E R Y*D N ',\n",
+       " 'T T R E*L A H T*O N*L I G E N*W D N G I H E D*T N*E R T ',\n",
+       " 'O G R H O S*O*I E F*B S B*A C*P A R K I S P*G Y*O U P T ',\n",
+       " 'E A G W V E*N I H T E S U*A C*P I R.U O W H A T W A N T ',\n",
+       " 'E U Y*S I R*G A L T N N I E N*E N M H W I O F E D*S*M A ',\n",
+       " 'S E*D E L K D E H H*A C F I H I L S*S O U*R E*H E E M H*',\n",
+       " 'T N*S A P E*E X W R N N E U*W N D E*E Q T S E U E*P E I ',\n",
+       " 'N O A I O*A W*D N V E N T*U A W R N G N L F.R E R E*H E ',\n",
+       " 'D N D D O*N T*T R E*A N L R A Y E*T E D D*O*C A R E*L A ',\n",
+       " 'W W R E T E*H T N D F,T S A M F S*G H H*I E I H N A R*T ',\n",
+       " 'R I T*B I D D*V E L N G E*L L E I R*I O*O*W N U E A T,F ',\n",
+       " 'E*R I P E*L R H H E I*T A*I E C A P E*N S U*L R A O R N ',\n",
+       " 'C K,A R*I O*H H C E*M S R E N*D E O T H A F,T S N O E*U ',\n",
+       " 'H L W U E O T N*P S H L S*S O A D A T E*N T.T S E N E*N ',\n",
+       " 'N*L R E S H*E Y O M E A L E*T R I T*F D O D V*H E T*W B*',\n",
+       " 'M S O T O*C N T R O I*T S E*O A L S I G E*T N*W I R E I ',\n",
+       " 'T I X E*B S O T*R I P E*P E D N U E*K O A B S*I O*F D O ',\n",
+       " 'D V*A Y E H O T O A I O.N H*O S*I O I U E,T R E*E T B C ',\n",
+       " 'H U A C Y*A W*T R I T*A N C E*P I O*A A T*D U E A N*W S ',\n",
+       " 'T O R*T D E*O S L S H P E*F O H*W I L A G E A E D.T S E ',\n",
+       " 'N E*H Y E L N O U O O E U*N I*G R A L K C O O R,V N I P ',\n",
+       " 'E A Y*A A U*B H U O T I L O L*I C H T N T A N N.B D I D ',\n",
+       " 'E*T S E N E*O S E*N N*N E L H A M O*H Y*R A F S E N*L I ',\n",
+       " 'A C E O*F E N I F*I W T S A S O H E R*P V*T R E*A N L R ',\n",
+       " 'A Y E,T D E*O D T O P I R T N*T S E Y*C A S V E D*B I T ',\n",
+       " 'R*P E R E*O A T*I P N P E*C M A M E N,N S U*O T*H O*J M ',\n",
+       " 'A T E*Y N A P O G R E*T S O T*T S H O*S O U*G E M H M E*',\n",
+       " 'O S A T D E I*T N A L*H Y*T R E*N E T C A S V.T S E*D A ',\n",
+       " 'D I R*C N A M G H*H W C F A S T E D*F B*T R E*I R L S N ',\n",
+       " 'Y E*F E N E*B O A T H L W D O A R F*S L T A Y E*H A*T R ',\n",
+       " 'E*G I L K N S*N T I T E R*O T*T S E*E O U*H B*T S E*O N ',\n",
+       " 'I E T E E O T R*L E I T W I F,I N D*F D O D V*G N L W H ',\n",
+       " 'N E M*N A*T I F O N C*T A*U A H D W C T*I M H H H S O*E ',\n",
+       " 'X W I I O I A I*G Y*O H C N I F*M H O L A S D*I U H O Y*',\n",
+       " 'V I R K S O*S O T O N A N D A H T O.F D O D V*H E E M H*',\n",
+       " 'T N*S A P E*I E T O R E U*W S N U*T D E*O S L S H P E*O ',\n",
+       " 'S N W I R*T R E*T O U E*A W*Y O L T H H N O’H*M E S T R,',\n",
+       " 'R N F E P E I*R O H*O U L L E H H N N R*L H S T H A W E ',\n",
+       " 'U*R O O*B A I K*I N D*B E*R O Y E*W A L A Y E D E R*E G ',\n",
+       " 'A D E I L E*A C*I*S H V S D F*I L T I G E*P A A W C*C A ',\n",
+       " 'S V O I V*W S U E D*M H U E*I I U E*S H L R I N C E D*N ',\n",
+       " 'I*T S E*N E Y A N N*A N A M I D*N H A E T E E N*T B E D ',\n",
+       " 'Y E.W I M A I T M N A T E D F,O T*O E E C N*T S A T*T R ',\n",
+       " 'E*H S A R A F*O A L S I G E*I E T B H H K*B I H*V Y*T R ',\n",
+       " 'A H*H T S V E*N M B Y H H T A S C*A N M E U*O N O U H I ',\n",
+       " 'E L T H H O*N I*T S E*N E Y A N N,A A U*F E*G E L I E G ',\n",
+       " 'E*T S A T*I T N*I L T I A S N*C I F*D N G E*L A I T H N ',\n",
+       " 'V M T E R,N T*L E I O T*I S U O D E L T D F,T A*T D E*E ',\n",
+       " 'Y E N T O*D E O D O I V*T A*T R E*G I H H T*P A R W U*F ',\n",
+       " 'O A.T S I R*W O L T*A W A S E*L A W W U*L O M H E*L A S ',\n",
+       " 'N O M E N N P L E*E U F N I S I H O G E S T*T A*T D E*M ',\n",
+       " 'K*F A P E H S W E N T*S O U*B E*G E E D*F E*R I P E*O A*',\n",
+       " 'H W T H H O*P M T*T N*N E L H C U E A U*T R I T*T D E*H ',\n",
+       " 'R I M N B*N I D R O P E*N S U*I R L*I T H*I E T B H H K ',\n",
+       " 'N*H S N U D U*V E*F N U O U*M W,O T O*U A D M U E A T H*',\n",
+       " 'O S I L Y R E U,L R A O R N C O E D,S O U,A B*N E L E H ',\n",
+       " 'N I D F,R E H T A A F E U,O I D*O T O*N H N E T O*R I H ',\n",
+       " 'G N H E R*A W.T R O O*N E B H A T*O D A M L D*I L O A*I ',\n",
+       " 'E C I H A*L D O H H H M I E U*B A R*S*F E S O A D*H Y*O ',\n",
+       " 'T*U E A O T*H E Y E I T B-W A Y E*F E N I N.P E*B H W D ',\n",
+       " 'U*A E M H M C E S M*A*C W P L O L A T I A I*D I T E*A W*',\n",
+       " 'T P A*T D A M N I N D*S O U*T P E I T B-W A Y E*A T*E O ',\n",
+       " 'S U O E O T.N I*T S E*G E O I T O U E,I T*N R A W W U*P ',\n",
+       " 'E*W D E O E I Y E M*W O I S P*T S E*D I Y R E H T*O E L ',\n",
+       " 'M A O T Y*N G O O R A F D E;A T*F N U D U*C N D U*T S E*',\n",
+       " 'W N H T*L A C G A A U I R N I F*U A T E I A I R*H M*I T*',\n",
+       " 'N R A W W U*W O U R*H A T A*E S E U Y*S O I D H.']"
+      ]
+     },
+     "execution_count": 129,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "chunks(repunctuate(combine_every_nth(split_plain), repack(ptb)), 56)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 84,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[((25, 9, True), -1226.7606628204894),\n",
+       " ((11, 7, True), -1260.344065012207),\n",
+       " ((25, 17, True), -1285.2666386878766),\n",
+       " ((25, 19, True), -1233.0406991946986),\n",
+       " ((23, 2, True), -1286.699132753805),\n",
+       " ((1, 21, True), -1248.1083921858865),\n",
+       " ((1, 17, True), -1242.3820605977833)]"
+      ]
+     },
+     "execution_count": 84,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "split_keys_affine = [affine_break(s) for s in splits]\n",
+    "split_keys_affine"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 86,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['osecdaebtyosaovcaaicolloayleryzcaocochkrndelsocceeaelaanveyecnldtcshtvcnlkscvcanechasyvhdynctkddntnlzmhccnohksnasncenaatleynhcahnyzndmayengdgosncconssocsmooclsccnecocolelinncyyicnynclsdsdbeeuctsjulcugscmnssesweonscclaceaysceoeleoccoyynlolznahruobvdmkoctnoavsegmhaanecclemyeeeedcsyyscnaetchccsecasrseuasllnyyannynelydytccseeancdegbigsvoccylilnnfstonocvccicyaccumgzzunaoncvcncetesydbravdeochkolnacahsuhlymnhycbyeencnksmlichhlinvrivhllchmmdrchnctlsnyyfcycyesrtwngnnhcahluycahlvvzndlcthlgazcyaoeseryvzlcnuoonckljcwnomunklulsdeuecczcadclnveynlyechoddvebeoesavrlhulsfbyvnvyeddorbzssanecscoocnhnynoyedvcoaddnvytvlyhcnbscvnlkacnnnacesbzcsblcyaeoclhnjuoadyidnyeunmchfvuclctblailaenakndmnennndgdnenlncdnoecaeseclvycolyysonydaohnmtyentenhodrohkeeycanlshidaiymjssofeydncooockehhcltwekybizotshsysckniacesgyaytcsyccaacfvtikenneeceavonwugclmlhhdtsafmdetbyansarnlvcetoncyatcvsnanyossackzhmeybursyaecs',\n",
+       " 'tednehneyqtfstcgwueutlnxmqshtntnawllfttymyelhnmmhlhlbumuhutlwmsalnhtuymaktfnimtaeeteqmmetemfxttmwuunnlthlcnuutyuucqeukwhweihuyebaqaamlyycqhxtkeabdttuhhwgithdlfelclcnnhlexmaeynqmwuhyenpleruflxtdeytbluufehwtqeehetyflfhherunafbtixftihunetnmltaettttaymntmtyhtyiaemuteehlmywenhwgiiyfenipuugiumtfnseqlptiluyynsanilbaqanswyndlshllxajtlaufmeiylupbunuaiezhificwhdewtletnmyatuypumcfehlygmwxltetretbetxsumktmextthluunwupgeyfytenxlnttlwaflwtuznaulkxxeualeqelwetstupemldhuwtmthtmbylttuimyyaulgxufmhthhhbxuimnrunfttmmtbtgenyhtegitgtspiimiihthayefeywttgywnudlyupunnipmtmnttehtlftauyfxwutemfhfuidpntyaluynagncyftfumtathhintulaxkbmtntenqeugfdtkdlhkliwtpthmtygytuygayaqbgypmmttyahbwcbfewklewuarnalymaynrunaiakiuwhltidulimyetlpbpuaqeerkmluedednytrmhettllqdeestwmrtuhhgdpfmehryeywyeuhyuhnamqtfmmlrtmmeyfttxuehltmhxnuweydembwxtuetfaklwwxutmepttagebmmamthtgxnwusmlftyalfbhsuiqqklnufkmkqieeagtetlueyylpmainf',\n",
+       " 'wbasetoblhjtnisnnnbfshsjyeseysyjtbhhstsuezetjeumtinytmjhnygirmsehotrmgmhtehsefshhtuieeshylksjetunwjmhseszmzaoagkteheqhnjreagmgthhhfhshwykhrzuubttiwjjtnntttshuhlztajehrfefgnhystasmhssjsrntunjmxregysemshnlnohenbbafshgstshoaeeeysfkaimzshmsuomhtoytjeiyouaxjgiyhekmsuimhikgremechdlymhfmryyhesusnsnhnhsunhmlssehfmhhhhhrreusimnhisftenjejhmnygmyhzyejhenretltnurhbhahbsrmystqgtnjfmbbjhwyeznubnmelehyzeqathqbjymbhnmfsyhhmbksanoyehihoneynnomrmnjyemybqhfbhzebbhemyhtaninqnayzthqhmhtsmeyztssstumkmhaseetmzeystnssjoyommohhhgefzniohslltojlewkshqbebzsmywyesyrtyyhzstzmktusnnetynhonkywahyubukjeyarkshutezhfhnsbubyhfymhszzbbyfyhabtsutynhhayusalnigstsisyhumjmbauznqahuhhnaubmsjtzthnanhhbrbubaotmeejrctztnnthntthabrhmeaaiefybyobhtmhhebhhkoshabhnnysamhtlsahttbsshygoyumtiotaesmbezbrejolmmseyhuhbjneuzybyyyrysbbjsmmwfysbyhbjtnstunyehnssnmohmnnygtsszsoeasbleztahyunesmesttmnnhhhhhojtnyhhebenuobmealumnzanahm',\n",
+       " 'ieaedtaelhirkemkutetlsmrjrmajefqjalcikmrtuifitfhnitetirnfnniknmdflnnsrnnknsabeosnkuzfteerlwirwtkdwljjmtnlbeeaeswgttrakdluieknrgtlrajeienekfeeaeratkilttkkksieetelteiteflimenkcmrfanjmeemacnncmrarkjrminmvrmtinigielkmrkifnoeinlwimmelncamjleqnrmgajtinugmniroknlftwkeunefnnluiotxkimrikjbnnrkrarmtokwwwiatlnekmwujiftltwutljluikfnubrncmwatxlouirtowtoenclttlrseuferdllmnbrmtarttwoeelmneqleuaeciiajerirantueamerlwtbfartkelwmicejtllvannistlweaomawejeekkikaemetfirtlqjgseuqfntuelrwbrirjlwmniwaswcjqltltrsnnmttmiraeemrejtrltaikrejmimnaqleawljeinelairigtnrkfrbtsaremwnrkoclteuxbnenllnbaealknbaaemenjfnthuhmajlkjtrnnqellajmunhatetwrickewiiahknoekomifjelmelieeteikjlrkeqcihikedtdlkfniualeeerertmtedenstnebrnlratjsnlglraheinenoelrdejkieaseafrwembojkeaqawremetjiiboatnauxinelkratureenianjoetarotfebelartlnllmhgrslnaelwlrqtenerrtckmloeeunrdredaieridwhiirewljeqqrnennwaakjltqhfllrrjtleeuoeoerrliurulaoau',\n",
+       " 'idpudfrpitatqpthadupiwdmotdrdjdhwsudovdvpdrhrlgdmupfouttwomuidddwhhdwgdgvodrdrcidqomhhdrmptvpjfqdwvdhdhwkwrcrajdthhphddrdrzwhgjhigsdruithqgrdhufrotahfofhhcgrpvdkfprlfgrrwndptddwwmhdiidhehhhtgpodwpoftrudohmhrjnnhdomwrghcrrthqhqgdhmmrdpraiphojrdpidddwduoawcjhhodfouviwdrdrildpmtoaddtptwpqpgioihqmogwfjtvddjtduihiwdewjptdudifddhhhtdotrpadudvrwcjpggipfptdhoocgdnhtmwgdfhgtnwovrftrowjrhwpecrrdrtmphwfpepodopwuiwwdvpdsodchijhhihrhvhdvrdprptujhioumwprrpoietudvrpmjdpcfddfperdqdtntfhpdmuordowjwelroidhtdpodchhoidwsopnlhwihwsrwitpcgqfwoerififhsutpqlngdtihfwrtdddhhwhrhfutrddigiiphweojtihojhdatihdltodtpnsdotpomwhqsapldbovtfovtmtqvtadpobmlomrtiwovcodsidspiadpiddhhwrtatrdhdptohpdvhiorehphtfndbedpthqrrigsvhddvirthgiiwiehfigtqndsipihpwgwhdicevivorbddddhevrhcopwpworedsdgsfdwosmirnnrfvltclwodiirnuhdhftwqowimwirthtghfhvgpltjtjjvieagdoddwirgndtwmmprqpovfdpffigpruowphdwwchdgohhpadjppgpqemhvthujrq',\n",
+       " 'sacboagcisnxxxamhextyraritqeoldcmtsracrxroahishlnllblhvsofnstsddnhxxaxsdcoosoifhisjtxchsrtaxudsxrnsaxrtbtvsrgtdelcsdhersoahndthxixtldhdscbesvstxdsvnhplahctddptotigisbdhsoxldlprlorcraornlcccvdsofibshoxhlsdrhadsdtysrnnuxrientmmstohilduseptuceheooenobmvsotntihsiidjhrtsoyohpfpxrihtasvxgcxdidhetusnshexaodlnhascusioatbrnonshttoactcvxltxnfnslthoddsntsiydvopfuxtadaodhxodhtatarrdxvxrbesceiltashatrdhghstdaeftixxloltsntiencgdccerdxxfrteesstoytcxruoutnhmestdsltehidrolhelcstdoboooihhmspsigriidohrgohrtxfroorctoxactohxtcotdctteklhldaxoiltsauhhhpdhpdhtdtxcdrsxsmdhxlithshoxxedtsaeceuokaucoemspbttldsjrarxtgabuofbcmtbhxohycphsxxrslxvhacyhfteodahunkponttwtxsdrdilitcraltosixdaoartocttrilumcvtcfolrdeyxdxuttxciekheidhttbitcfitamhotdqxccntbmlxpyctuisdaoooulusxsohmioodlntettsxrstiauxtittcvmuerltxttxttsxvrsgrnrotethxdrdhstlsreaxexddttrolootetddsrloesaaottedhxtxxihpbsydunuhxxoytsthethhtdllcxathesc',\n",
+       " 'oicttiolkktdbdhlfrhsiiitifbtiwvtlkthiwtdtnuotkqactthmiwlihckdfhdcoihlffnwwntsmmqhotthtvkmfkdhdobilwwuihkftpoldbtwtkstwtniifivtfukbdwiiicltofttphhblbothwstlqsorkfkhtkodfkauththoawclaswttlttttqttobhefvwaawwwvwskfnlkdrlfittocuttkklqssadlsosvltftiooeiottkidvhookzhfthtiksnifhaiddkdwilwckwddaiqqbdktwfwdovdmidflwwoktfhutltrkvieiitdttuanpltrkasinhhltltolhtfhafacphovadblstolhtntcptiouoftlllhvkvtffsthiotfiiaslhpaoaekfazttthrriilhubtaliiwkpiojtqshndvtfkkodhkanlftslotfiqtosaihiveleswlektiwzbhnabtnlwjdltntothibtlatqhdtrwdlapfwtsonhdlzwpcieesioaiaviwbfatoitdwlidsiovooifputikwbbtoalltetswtktkfnuvkofptbrllwsnikotphdqiawkbdwddrlwftfilodiwouiqthoahnftnihunstikaofohiaslpkhdwftonidwwttlewtthltollftcucidlpqtwwcrelialskhwomklioiocdbrllthiooboiweaikdlnwihlfhnhtowovdalfhullkuwkhssthkoqoatodtswvbiahackptzktithwvpqidqwidattofpudsdrhdbdnporsifhdfznnoftwnfflffuebhattlfuhacroubnulwlirhdvsqtntcwhiuol']"
+      ]
+     },
+     "execution_count": 86,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "a_splits = [affine_decipher(c, m, a, o) for  (c, ((m, a, o), _)) in zip(splits, split_keys_affine)]\n",
+    "a_splits"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 87,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "OTWIIS OS EBE DAIEDAAPCCCNS, EUBTDEEDDOTAH TTF AIENOARG OB EBE PCLTYL LIIKYQH; HTSK OTJIANTSFTRTXDA.\n",
+      "SNK QXBO TIEP XDVC. SMTA HCGNKH MLA WNUAHFAUNTDE RI EBE UXHCUFT PTSOTSLIY IL LHSWRI LN SMD\n",
+      "AIOXJRMRTA MYJ OIIYQERTTF LS SMD QBEHE-ARETRTYJDOI YNSEJLWZTYFD DVCNJQ, HCT AATJWM LOWBAST,\n",
+      "KCLHLUSTO LHCDRHCF SI OA IHT TKVCWKT. SMD RTRYUR VXDNMETP RTDYZUDONEEEIRA ULL TFHHOSH JIRITONETL SKC\n",
+      "MUFGHQC, MM HDLA EH T NMNCELI IU LTAHNTP LTELYEF BHLB TTOLMAUM IU HIA MJRTVWNUHN. TS LVHN FWOIEUYN O\n",
+      "FHYTG NMNCELI IU SKC WRKITDN MMNDSF LS SMD DHDAEDD DDT LHFWNCCNOLHHOSH TN HX IHT RND XH TUMSWALV YG\n",
+      "RGXFC MMNDSF. NAH NGDNLK TKVCWKT EN OO WSFHSDONCNS ARSTVIEBDOSC MFERIM ATS OC FM NAH SIHQEEH\n",
+      "NDIHCETKQ SO HTU UOJTAEI ZMTTS QEFHXHYM ET HCT VMSE DHVHEHERSK DTYRMRM. YE LLP TFNMKWTAKCF SI\n",
+      "VXDTXJR PUHKTEWJDDDT TTF SO DMUKQ XBN WNDDRI TUWWWNLNUJ LVSWLNM JDAWZNHJ HX UMLSMDR IHT ETHTHCHSN WB\n",
+      "KCL ZLKTFNC’M BWVTONZERS, PHUAE CROKUOARG LS TAEATDN YG SJDBAUKWD ETSUTGTLWNC ET HCT CQHTH SKEE ERP\n",
+      "DSNUQAHHTA KHKD EWAWNDDRTT. HJLRS NLWRUDOIEEEIR AIYIA EZHFNH GKWN IHUM NHDVC YG RGT TAETGJHFHBHTH XU\n",
+      "NAH LIIKYQH, RGXBZA FASTD NAH JDLWDMSE RDIMLH IU HIA YWEIDIYYYN, TS CEC KE HCLN QHKQ BTG HRFG\n",
+      "EODXZERSF GTUE DVTO KUAHSTS. EBE UTP NATR FX HCBTAR DHC DI TOSBOT WKTVLNT JIANBSUJLHHOSH TTF\n",
+      "PTOHNTOL HCWNKFA. WS GTKHHSMITK HCTOT TSCTLOH SI GDQC DHER D SLLUEPPOSFHTVT RCELEDO KCL ZLKTFNC TTF\n",
+      "IKELAEP GHCC JIRITONETL SKC NHEF BOO HRFG DD LLFLRHFEEEIR, SKLXFM WOAI M GEN XU NANND LTNEHKP DHC YY\n",
+      "CTLT YN SMD PHYQTRD ROIMA FWLACWSAWO. WN UM NMRCYHHJ HCLN YSMDR ACESEIA SLNJEIOWSP SMD RTDLRAHNTSE\n",
+      "NC ELLDR TN HCT BUUNH CTEF NC HCT ELJMTVT UXMR GDQC TXAPSTT, DRR OO TSEEKD FOJ YG JWIBUTYRP BHLB\n",
+      "SMOS ECLEIF HF UUMNTOV GUSM RX WSFHV UHAC EN RDLA MH LMOS WN WNTHDWSTO. IMR WSQHNHHVEEEIRA WSEN\n",
+      "GJDSW HBIN SKEE BE NDF OTALHTN NY FKDY, LSF SMOS KC LHRMRDCF GKWN RLHSIR NLAHTFGUFCESN HX IERH OC\n",
+      "RTAUOERIT YN AIREOS. AEN TNCCFELHT UEBEWQ MTOT YIH MTEISMQ, SKLXFM GT KEF KEDO L OTALHHQCII\n",
+      "NMISCHMCML SOUZARDA YN SMD UDYEHJ PSLNTM, LRE SLNSEAPOOMUQ ITSLLON PUVZTMR HCLN AH MOE TAETGJHFHTO\n",
+      "ARETRTYJDOI UTTTP. OO OTJIIE OB AEN DNEVYIUDOI DMY GD BOMNO, MWMTKTU NDVTOMA IU SKC TXROOI TYJOATDNH\n",
+      "GKWN VOTI’N CTHAYYLJ IOVIHFHHOS AETH SKEE KWOIZ GMM KDIHMUSEF DF HTU UOJTAEI’N UHHAE MEVRTN\n",
+      "HHFITIELI, NW SKC MKNDOSC YG LRY NLWRUDOIEEEIR HF MNMOIPHYHETL. FAEWC XDPI E GHKPXDEI DIMRDEI LMTIK\n",
+      "DYYROHDCF MIAT WSEHKDAIYNF JDSLYIM, BTVWSP RN PXCC UYNTGKN UYRW CWA GHKPXDEIERQ, DDT US AP IACMU\n",
+      "RGDI HT SMIHQCF NT OEQCNSOIT. BSSNKHUDEEHWQ, SKC QNWMNTA LHWOSWSP SI GHF RTUAWE WS INTFXD ELH LJAO\n",
+      "UUMNTOV, AY LE VDDSYS KDLM LN SMDN IL SEWJ HD NAH UTAFYNF JDSLYIM IU CWA LHFIUWNBHTH SO NAH LIIKYQH.\n",
+      "TWOTNAHWDAF E NRUETH LS RTWBUYWELJ RTDYUJP NLYNSLTOTT DI UDNRCLM IU SKC SNKDHVS HHFITIELI’N\n",
+      "FTEELSUDOI AXFBDAI NATR HCT CJENHTDDT NC HCT ELJMTVT, GAEWD XUBUJAOLAI FHTTTN, GMM XRXPS EN L PNLVI\n",
+      "YOAFTO YG UDNRCLM IU SKC UYRDLAYPHTVT SLBZORHII UY WWONLN. ET CDHNUJOJDH NAH EPSLFIENGNTSE NC\n",
+      "GTLTZRLISTOH ET PIONITTF YLOF LLP D HCITRTVTVC NSDO FCWUEH, PHCHRUOFAI DHFOUFC EBE CXAYWH RGTCATADDA\n",
+      "PCLH LNDHC EBLH AOUTSMTOV MNRNMDA GMM BWHDZ YY, RGXBZA SMD OLUT TTF DSNUQAHHTA YG RGT OOPTTTALNUNT\n",
+      "NTHC M JWWATVC FOORNCF MEVRTN. EBE RDCC HBLFXP ELJMTVT TYHN RXI EGWEOR OS MYQ WBUYWELJ EODXZERSF\n",
+      "BLNU HCT RTUAWE. LA EBE PILVT NC ELLDR’M ICTHEEEIRA VOTL AR SKC BEJ DHVHEHER ATKTYRTTF, OXZIMRF LS\n",
+      "ERP DSNUQAHHTA MANW GHCK TTF HI ATHUP SO HMQE ETTS EBAP, DF UXJM OA IHT YEDE IL TMROFAYHB L PTSMLH\n",
+      "WWILNUNT UXH HUM BIXPYNF FWLACWSAWO OB UYRDLAYPHTVT EEGHKP, SKEE MEDNF NY BLST ACF KWOIZ NY SMD\n",
+      "ETKTAICNTSE NC HCT MNOEIGHLXYJ JDRILETHC RCNHLHC IHT ILIE. IHT HVHRLLLOARDHI WNNH XU NAEN VXBVF YIH\n",
+      "FT RLNSDRAI WNTVTLVTO LRE IHUM WDE IL ZREPSWLNM AR SKC ANOPT PHUJM TO IMLY, AU YOM KEWJ TJDXME HCT\n",
+      "RXY, JIXQC EBE ORSHUQE UUHNAHK MONCLFKWUDT. EBIPT VLQHKRNTSE ZARHFNLEEP MKYWB MOE KYEBEISO FTHT\n",
+      "ETDCSEFTDHYTM IU SKC UYRDLAYPHTVT NEET LRE LSMAQPHF RLNJMITT DI GJDSW’H NSDRLNUQEP OOG WNUCLTNTAQ\n",
+      "FHFNMYFDE IHTZNDLQCH, TTF CT ATHUP SO HMQE ETSLBH LR DAUYMR DOIYLHWQ BHCT TBDOI, ATSRTOV HUM INO\n",
+      "ELIERTILV MYJ FHEVYZLHHS ZYTWP MWNA SMD SLDUS NMPELLS IU SKC GTWOIT. TXUARG IHUM SDRWLF, KWOIZ GMM\n",
+      "CWIBAHHJ JDHZTAQ WO NCHSLEHAYHETL RBAHELR, GTOBTT OON EXMRIHLS UZSDRWEIENH TJRMYNTXD YN SMD FLVRTTP\n",
+      "RTZUNT, OON LN SMD OTCF SI CRONTJR HCT UTOAHTHOMYEOO IOMOE IXBNTM. MD ATCBM RW CLKT OESTALGHJ OO\n",
+      "TJEHTPHQC NHRNXHW YG LLTDNH ET HCT OTFAWO, RME ZIIT WUGNKHDDNII RW CLKT OESTALGHJ RTP UTSMWEF LS\n",
+      "LIIKWSP. LMTLT DITNPHSEI OACLOUMJQ GDN EILLQA HCIEEF XD CHWAWOLZT, KWOIZ CHSLELWAAHJ RTP DYQEIS\n",
+      "CCEBIFA IL FENIUEN EBE FHEVYZLHHS EWSASHIYTM IU PONTYRTDA LGWIPHIYYY, GQ PAEWETL DVCNSN NHIHUY RGTWO\n",
+      "DRKDDBDLTFTTF. DYYRIXAVUYB HCT EPHTFD OB UZSWRIENS ARSTONTRTXDEI ZEDSWSPM, MD MLA MKWD, DI VTTNH HD\n",
+      "RMUR, HX SLNSKWL IHT NOHIOUT NC RTVLEELHHOSH, TTF SO FTYEUHI BLNU TOFYFH XRXPVTOBD XU NANND\n",
+      "ETVUKEIDIYYYN. GT KEF WLISWDXALI ABDWHNP EBOUYB HCT RTUAWE OB EBE EUAZMUAOO LSF KLJKLSH JKTATA\n",
+      "FENIUENUYB HCT EIAAOOSC DRAJEWSP KEHMTCN SMD SKOTH EAPTOYUN. TB KC ATJ ITFNLEFHTN HUZNDLU NY\n",
+      "HTLDVYNF HTSK NAH UOJOO GNHDRF YN SMTA PEC BAP RTDYUJ NXBVF BLST RCTY KDGLOFHJ OA L AUFTTBWDMYR\n",
+      "PUSDTMN OON NAH NMFIVTSQ WB KYH ZEHCOTH ZLQ MTVI BLST PLN BAA BHYTYJP HD HUFM LXQCLYUDOI. NAH\n",
+      "NBHABXA HOY WS KBAVC KC BTTTPBVMSEF HDNTUTOSWLNTW VXDKTYRTXDA EN IMR RCNHCTS LN QHKQ LWNEAE VXFN UY\n",
+      "WTVTA GUIAHFCF SI DAIEDAAPC L STL HOY OB KNKBHDZ DI NMFICLGOLT WSHSEOE OB KTK. MOULLSORDICII MTA\n",
+      "QYWSIIHTA TYFWUHEPHJ O NOOT UEVKACHM LCPHLMJM OON HT MEDNF NY BLST TJGAIITN UYUE DWIOTZE STHAUNTP XU\n",
+      "DYQEIS NYGAIADSI. AHKD RTDYUJP DI NAH LIIKYQH RDLA E BNKD IOUGAEHT FNYUQ, HCOMPB CWR HCMMIRA IHMS\n",
+      "HTLA FTJIAT SVTTK TO L UYZERS, PC ATDD IKLHHT HX HCBNDD DDT WALPAWBC, NK TO FLBH FOATA FHNHROI,\n",
+      "EBIPT NLWRUDOIA KBAVC DELULHT WN. EBEIT WA WAEOR TKUOERIT NATR ELLDR MEH UE MNERP MWNAET HCT ELJMTVT\n",
+      "NY RTFTHNMCE NCLN ATDD FTDYZE BOOGN TN ELLDR NSDRLNUNTP. (DF EN TNTET, NAH EHYCLINBQ XU NATR RDCC\n",
+      "KTN RXI DIHLI UDNUA RGT LOWBAST PEH RTVXQCLHJ.) HCTAT MSDIWEIENDE WS DALVKCEUA, GIHRCLI LRE\n",
+      "ELIERTILV MFAHDIYYY. HGHAC EBEIT LOT YI ITSLLON WB KYPBEI IHYBHN ETWSP TOHCOOUMEF FM NAH LIIKYQH,\n",
+      "RGT LDEEDTAIA EBEQ MOORHJ NHIH KHKD OON MKIST CMLOEI, DDT US AP QBYEH SIXREDAE HCLN EBAP CLT DHFWNT\n",
+      "ENNRGTH NYNW WB IHT YEHMOOR. SMD LODMA BIXBRH MOCPOOEHJ EY IHT TKVCWKT LEIT EELSAVUAELAQ OIIYQH AR\n",
+      "SKC DTWBDD AETRDA LN EBE DON LS SMD OWSTSEDOIH WHTHUHI, MYJ ELLDR GIVUFATO IR SHIUYB HX NYHUOCS\n",
+      "HMHMAOO TJGTTPHOS DI NWMWSP OAPIOOF TUWOV FMAXOO DEEEIRDAYHSN. ELLDR MEDNF NY BLST HCEEKDE UOYZ RGT\n",
+      "LOWBAST LOYRTF SKC EEUD XU KUJRWRWE’H OEOSK, HYLESTH HUM NMISCHMIIA SLNSARUTT AEN NXHW MYJ NT KEQH\n",
+      "ORIOKTUEF TQYFHTVT OB M BALCAI MJRTVT ZLNOC MOORETL UDTTU FWET SMZE ORSHMYBDL WS EBE ITVYYY LIXBSF\n",
+      "YARTICTY RNTAKT. RTUXHNXYLHTAI, US NDTCA EBLH SKC HBLFXP ELJMTVT STSHWRZ GMM GQ SKYH MROGT\n",
+      "AXWSWRIYNF LINTT UYNMRHCWSAWO WS EBE ITVYYY, LRE PC DHWTTQC EBLH HIA MJRTXDA BTQ GDQC WNTHRWFXSEF,\n",
+      "DI VTTNH HDTUUEVSAI, EN RGT TKTYRP LTEFETL SO NAH CTRFN KNKJE PEL. SMTA UEWS LJXDC WNOJE SEXME\n",
+      "VXDAUOEIDRVT HUEDHOMMNATDN EN RGT BW PNDDRDUTYR OON GT GEDL PC ATDD OO LGSAWO RME SI ITSLBZERE IHMS\n",
+      "RGT FHMOIN DHDAEDD DDT MAW TSF STSHWRZA HBIMLN FT LIMON MG, ERP EODXZERSF ENTWQATT, WALPAWBUHJ, OON,\n",
+      "YS YEVTFAMUQ, FTFNLNQDE, LSF ERP DFATSN FHFRYMEF XU. NAEN ITELLS NGXBVF TWPX HCBTAR IAEHMAUHTT SNK O\n",
+      "PTOUNJ WB LN IHLPS FCQHTHY-UYQH QDDHA. KH HWUAT LHFWNCCNO L CURVUJLHHOS FTRD XU NKN RGXBAMYJ OON\n",
+      "NKHTHY-UYQH LH TLOIEEPS. WS EBE ATLSEEUD, HI AANOJE RC GUEPTHKTO OPHDZ EBE GHVHTMR PTSMLERQ\n",
+      "DQEUALELT; YE LIMLN BYUU HCT UYMR VXCRLNUTAWSP ZLHTHYMA AU HI AANOJE UEIA ARSO CNHUQ CLSFM.\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(repunctuate(combine_every_nth(a_splits), ptb).split())))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 88,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def split_decipher(split_message, pt_alpha, ct_alphas):\n",
+    "    split_maps = [{c: p for (c, p) in zip(pt_alpha, cta)} for cta in ct_alphas]\n",
+    "    split_trans = [''.maketrans(sm) for sm in split_maps]\n",
+    "    split_plain = [s.translate(st) for (s, st) in zip(splits, split_trans)]\n",
+    "    return combine_every_nth(split_plain)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 105,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def split_swap(ct_alphas):\n",
+    "    k = random.randrange(len(ct_alphas))\n",
+    "    i = random.randrange(26)\n",
+    "    j = gaussian_swap_index(i)\n",
+    "    swapped_key = ct_alphas[k]\n",
+    "    if i > j:\n",
+    "        i, j = j, i\n",
+    "    if i != j:\n",
+    "        swapped_key = (swapped_key[:i] + swapped_key[j] + swapped_key[i+1:j] + swapped_key[i] +\n",
+    "                    swapped_key[j+1:])\n",
+    "    return ct_alphas[:k] + [swapped_key] + ct_alphas[k+1:]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 115,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def split_sa_worker(message, plain_alphabet, cipher_alphabets, \n",
+    "                                     t0, max_iterations, fitness,\n",
+    "                                     logID):\n",
+    "    temperature = t0\n",
+    "\n",
+    "    dt = t0 / (0.9 * max_iterations)\n",
+    "    \n",
+    "    current_key = cipher_alphabets\n",
+    "    key = current_key\n",
+    "    plaintext = split_decipher(message, plain_alphabet, key)\n",
+    "    current_fitness = fitness(plaintext)\n",
+    "\n",
+    "    best_key = current_key\n",
+    "    best_fitness = current_fitness\n",
+    "    best_plaintext = plaintext\n",
+    "    \n",
+    "    # print('starting for', max_iterations)\n",
+    "    for i in range(max_iterations):\n",
+    "        key = split_swap(current_key)\n",
+    "        plaintext = split_decipher(message, plain_alphabet, key)\n",
+    "        new_fitness = fitness(plaintext)\n",
+    "        try:\n",
+    "            sa_chance = math.exp((new_fitness - current_fitness) / temperature)\n",
+    "        except (OverflowError, ZeroDivisionError):\n",
+    "            # print('exception triggered: new_fit {}, current_fit {}, temp {}'.format(new_fitness, current_fitness, temperature))\n",
+    "            sa_chance = 0\n",
+    "        if (new_fitness > current_fitness or random.random() < sa_chance):\n",
+    "            # logger.debug('Simulated annealing: iteration {}, temperature {}, '\n",
+    "            #     'current alphabet {}, current_fitness {}, '\n",
+    "            #     'best_plaintext {}'.format(i, temperature, current_alphabet, \n",
+    "            #     current_fitness, best_plaintext[:50]))\n",
+    "\n",
+    "            # logger.debug('new_fit {}, current_fit {}, temp {}, sa_chance {}'.format(new_fitness, current_fitness, temperature, sa_chance))\n",
+    "            current_fitness = new_fitness\n",
+    "            current_key = key\n",
+    "            \n",
+    "        if current_fitness > best_fitness:\n",
+    "            best_key = current_key\n",
+    "            best_fitness = current_fitness\n",
+    "            best_plaintext = plaintext\n",
+    "        if i % 500 == 0:\n",
+    "            logger.debug('Simulated annealing worker {}: iteration {}, temperature {}, '\n",
+    "                'current c alphas {}, plain alphabet {}, current_fitness {}, '\n",
+    "                'best_plaintext {}'.format(logID, i, temperature, current_key, plain_alphabet,\n",
+    "                current_fitness, plaintext[:50]))\n",
+    "        temperature = max(temperature - dt, 0.001)\n",
+    "\n",
+    "    return best_key, best_fitness # current_alphabet, current_fitness"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 125,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def split_sa(message, plain_alphabet, cipher_alphabets,\n",
+    "                  workers=10, \n",
+    "                  initial_temperature=200,\n",
+    "                  max_iterations=20000,\n",
+    "                  fitness=Ptrigrams, chunksize=1):\n",
+    "    worker_args = []\n",
+    "    ciphertext = sanitise(message)\n",
+    "    for i in range(workers):\n",
+    "        worker_args.append((ciphertext, plain_alphabet, cipher_alphabets, \n",
+    "                            initial_temperature, max_iterations, fitness,\n",
+    "                            i))\n",
+    "#     print(worker_args)\n",
+    "    with multiprocessing.Pool(10) as pool:\n",
+    "        breaks = pool.starmap(split_sa_worker,\n",
+    "                              worker_args, chunksize)\n",
+    "    return max(breaks, key=lambda k: k[1])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 126,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['fudjphwtaemovnxgzqibclysrk',\n",
+       " 'sjditvqeruzbkflcayxhwngmop',\n",
+       " 'ixlcwrdopvgqbyhkejftzsnmau',\n",
+       " 'naegyjrfhivxmdzqbpokluwstc',\n",
+       " 'pdfztakijgnoqxcsmywlrvubeh',\n",
+       " 'onjscymxvgdzipwhkqatbfelru',\n",
+       " 'kzcfynwubrjeslmtghivdqaopx']"
+      ]
+     },
+     "execution_count": 126,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pt_alpha = cat(l[0] for l in english_counts.most_common())\n",
+    "split_counts = [collections.Counter(s) for s in splits]\n",
+    "split_alphas = [cat(deduplicate(cat(c[0] for c in sc.most_common())\n",
+    "                            + pt_alpha))\n",
+    "                            for sc in split_counts]\n",
+    "split_alphas"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 127,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "100000000"
+      ]
+     },
+     "execution_count": 127,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "10**8"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 136,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2000000"
+      ]
+     },
+     "execution_count": 136,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "int(2e6)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 137,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(['crdhgmszjaktloxbefnwuqvipy',\n",
+       "  'najgryfehivdxkbmpqzlouwtsc',\n",
+       "  'wphqekyxnsizjauobcldrgtfmv',\n",
+       "  'szvtderqiubkcxnjhafylwmogp',\n",
+       "  'jiuracqpgtwzbvmyshexkoldfn',\n",
+       "  'zyebmtwoxcqjrfaiklugsphnvd',\n",
+       "  'dmzxbivulyfngsraowjhpeqckt'],\n",
+       " -20379.803672616308)"
+      ]
+     },
+     "execution_count": 137,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score = split_sa(scb, pt_alpha, split_alphas, max_iterations=int(2e6), workers=20)\n",
+    "key_b, score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 133,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "REPORT ON THE ESTABLISHMENT, EFFECTIVENESS AND STANDING OF THE SHADOW ARCHIVE; WITH RECOMMENDATIONS. FOR YOUR EYES ONLY.\n",
+      "THIS REPORT WAS COMMISSIONED BY THE FOREIGN SECRETARY TO REPORT ON THE STRUCTURES AND ACTIVITIES OF THE QUASI-INDEPENDENT INTELLIGENCE AGENCY, THE SHADOW ARCHIVE, HEREAFTER REFERRED TO AS THE ARCHIVE. THE REPORT CONTAINS RECOMMENDATIONS FOR ACTIONS CONCERNING THE ARCHIVE, AS WELL AS A SUMMARY OF LESSONS LEARNED FROM ANALYSIS OF ITS ACTIVITIES. IT ALSO CONTAINS A BRIEF SUMMARY OF THE CURRENT ASSETS OF THE ARCHIVE AND RECOMMENDATIONS AS TO THE USE OR DISPOSAL OF THOSE ASSETS.\n",
+      "THE SHADOW ARCHIVE IS AN INDEPENDENT INTELLIGENCE AGENCY SET UP BY THE PRIVATE SECRETARY TO HER MAZESTY QUEEN VICTORIA IN THE LATE EIGHTEENTH CENTURY. IT WAS ESTABLISHED TO CONDUCT SURVEILLANCE AND TO CARRY OUT COVERT DIPLOMATIC ACTIONS DESIGNED TO FURTHER THE INTERESTS OF HER MAZESTY’S GOVERNMENT, WHILE PROVIDING AN ELEMENT OF PLAUSIBLE DENIABILITY IN THE EVENT THAT ITS ACTIVITIES WERE DISCOVERED. SCANT DOCUMENTATION STILL EXISTS FROM THIS STAGE OF THE ESTABLISHMENT OF THE ARCHIVE, THOUGH GIVEN THE DELICATE NATURE OF ITS OPERATIONS, IT MAY BE THAT VERY FEW SUCH DOCUMENTS WERE EVER WRITTEN. THE FEW THAT DO REMAIN ARE BY NATURE PRIVATE COMMUNICATIONS AND PERSONAL RECORDS.\n",
+      "IN PARTICULAR THERE APPEARS TO HAVE BEEN A CORRESPONDENCE BETWEEN HER MAZESTY AND CHARLES GREY CONCERNING THE NEED FOR SUCH AN ORGANISATION, THOUGH ONLY A FEW OF THOSE LETTERS ARE ON FILE IN THE PRIVATE ROYAL COLLECTION. IT IS SURMISED THAT OTHER LETTERS CONCERNING THE RECRUITMENT OF BLACK AS THE FIRST HEAD OF THE ARCHIVE MUST HAVE EXISTED, BUT AN ENTIRE BOX OF DOCUMENTS FROM THAT PERIOD IS MISSING WITH NO INDEX FILE TO TELL US WHAT IT CONTAINED. OUR INVESTIGATIONS INTO BLACK SHOW THAT HE WAS RELATED TO GREY, AND THAT HE RETURNED FROM BOSTON MASSACHUSETTS TO TAKE UP RESIDENCE IN LONDON. HIS IMMEDIATE FAMILY WERE NOT WEALTHY, THOUGH HE HAD BEEN A RELATIVELY SUCCESSFUL CRIMINAL IN THE UNITED STATES, AND CONTEMPORARY RECORDS SUGGEST THAT HE HAD ESTABLISHED INDEPENDENT MEANS. NO RECORD OF HIS EMPLOYMENT CAN BE FOUND, HOWEVER SEVERAL OF THE EXTANT DOCUMENTS FROM GREY’S PERSONAL COLLECTION HINT THAT BLACK WAS RECRUITED AS HER MAZESTY’S FIRST SECRET SECRETARY, SO THE ABSENCE OF ANY DOCUMENTATION IS UNSURPRISING. BLACK KEPT A PERSONAL JOURNAL WHICH CONTAINED SOME INTERESTING DETAILS, GIVING US SOME INSIGHT INTO HIS PERSONALITY, AND IT IS CLEAR THAT HE THRIVED ON ADVENTURE. UNFORTUNATELY, THE VOLUMES RELATING TO HIS PERIOD IN LONDON ARE ALSO MISSING, SO WE CANNOT RELY ON THEM TO FILL IN THE MISSING DETAILS OF HIS RECRUITMENT TO THE ARCHIVE. NONETHELESS A NUMBER OF UNOFFICIAL RECORDS MAINTAINED BY MEMBERS OF THE FOREIGN SECRETARY’S DEPARTMENT SUGGEST THAT THE EXISTENCE OF THE ARCHIVE, WHILE OFFICIALLY DENIED, WAS KNOWN TO A SMALL NUMBER OF MEMBERS OF THE INTELLIGENCE COMMUNITY IN LONDON. IN PARTICULAR THE ESTABLISHMENT OF HEADQUARTERS IN SCOTLAND YARD WAS A RELATIVELY OPEN SECRET, PRESUMABLY BECAUSE THE POLICE THEMSELVES WERE AWARE THAT SOMETHING UNUSUAL WAS GOING ON, THOUGH THE NAME AND ACTIVITIES OF THE ORGANISATION WERE A CLOSELY GUARDED SECRET. THE NAME SHADOW ARCHIVE DOES NOT APPEAR ON ANY OFFICIAL DOCUMENTS FROM THE PERIOD. AS THE SCALE OF BLACK’S OPERATIONS GREW IN THE MID EIGHTEEN SEVENTIES, RUMOURS OF ITS ACTIVITIES ALSO GREW AND IT SEEMS TO HAVE BEEN THIS, AS MUCH AS THE NEED TO ESTABLISH A SECURE LOCATION FOR HIS GROWING COLLECTION OF INTELLIGENCE PAPERS, THAT SEEMS TO HAVE LED BLACK TO THE DEVELOPMENT OF THE UNDERGROUND LABYRINTH BENEATH THE YARD. THE EXTRAORDINARY COST OF THIS COULD NOT BE PROPERLY CONCEALED AND THIS LED TO QUESTIONS IN THE HOUSE WHICH IN TURN, IF YOU WILL EXCUSE THE PUN, DROVE THE ARCHIVE FURTHER UNDERGROUND. THOSE GOVERNMENT MINISTRIES WHICH HAD HITHERTO BEEN BENEFICIARIES OF THE INTELLIGENCE DATA AND ANALYSIS PRODUCED BY BLACK’S OPERATIVES NOW COMPLETELY DISTANCED THEMSELVES, AND HE SEEMS TO HAVE BECOME AN ALMOST ENTIRELY FREE AGENT, SETTING HIS OWN POLITICAL AND DIPLOMATIC GOALS WITH THE TACIT SUPPORT OF THE PALACE. DURING THIS PERIOD, BLACK WAS FOCUSSED LARGELY ON DESTABILISING RUSSIAN, GERMAN AND AUSTRIAN IMPERIALIST EXPANSION IN THE BALKANS REGION, AND ON THE NEED TO PROTECT THE MEDITERRANEAN TRADE ROUTES. HE SEEMS TO HAVE DEVELOPED AN EXTENSIVE NETWORK OF AGENTS IN THE REGION, BUT MORE IMPORTANTLY TO HAVE DEVELOPED NEW METHODS OF WORKING. WHILE CLASSICAL DIPLOMACY HAD ALWAYS RELIED ON ESPIONAGE, BLACK ESTABLISHED NEW COVERT METHODS TO DISRUPT THE DIPLOMATIC ACTIVITIES OF POTENTIAL OPPOSITION, BY PLACING AGENTS WITHIN THEIR BUREAUCRACIES. CONTROLLING THE AGENDA OF IMPORTANT INTERNATIONAL MEETINGS, HE WAS ABLE, AT LEAST IN PART, TO CONTROL THE OUTCOME OF NEGOTIATIONS, AND TO BENEFIT FROM INSIDE KNOWLEDGE OF THOSE DELIBERATIONS. HE HAD PARTICULAR SUCCESS DURING THE PERIOD OF THE BULGARIAN AND BALKANS CRISES DISRUPTING THE ALLIANCE BUILDING BETWEEN THE THREE EMPERORS. IF HE HAD RESTRICTED HIMSELF TO ENGAGING WITH THE MAZOR POWERS IN THIS WAY HIS RECORD WOULD HAVE BEEN REGARDED AS A SIGNIFICANT SUCCESS AND THE SUBTLETY OF HIS METHODS MAY WELL HAVE WON HIM FRIENDS IN HIGH GOVERNMENT. THE SKILFUL WAY IN WHICH HE MANIPULATED INTERNATIONAL CONVENTIONS TO OUR BENEFIT AT VERY LITTLE COST IN LIVES PROMISED TO ESTABLISH A NEW WAY OF WORKING BY SUBTERFUGE INSTEAD OF WAR. UNFORTUNATELY HIS VICTORIES ENCOURAGED A MORE RECKLESS APPROACH AND HE SEEMS TO HAVE EXPLORED MORE EXTREME VERSIONS OF COVERT DIPLOMACY. HERE RECORDS AT THE ARCHIVE TELL A MORE COMPLETE STORY, THOUGH FOR REASONS THAT WILL BECOME CLEAR IN A MOMENT, WE HAVE CHOSEN TO REMOVE AND CLASSIFY, OR IN SOME CASES DESTROY, THOSE DOCUMENTS WHICH NARRATE IT. THERE IS CLEAR EVIDENCE THAT BLACK SET UP UNITS WITHIN THE ARCHIVE TO UNDERTAKE WHAT HAVE BECOME KNOWN AS BLACK OPERATIONS. (AS AN ASIDE, THE ETYMOLOGY OF THAT NAME WAS NOT CLEAR UNTIL THE ARCHIVE WAS UNCOVERED.) THESE SPECIALISED IN BLACKMAIL, BRIBERY AND POLITICAL AGITATION. WHILE THERE ARE NO RECORDS OF HIGHER CRIMES BEING AUTHORISED BY THE ARCHIVE, THE ACTIVISTS THEY WORKED WITH WERE NOT ABOVE MURDER, AND IT IS QUITE PROBABLE THAT THIS HAD BECOME ANOTHER TOOL OF THE NETWORK. THE LOCAL GROUPS SUPPORTED BY THE ARCHIVE WERE PARTICULARLY ACTIVE IN THE BALKAN STATES AT THE END OF THE NINETEENTH CENTURY, AND BLACK FOCUSSED ON TRYING TO DISRUPT RUSSIAN EXPANSION BY SOWING DISCORD AMONG BALKAN NATIONALISTS. BLACK SEEMS TO HAVE RETIRED FROM THE ARCHIVE AROUND THE TIME OF VICTORIA’S DEATH, HOWEVER HIS SUCCESSORS CONTINUED HIS WORK AND WE HAVE UNCOVERED EVIDENCE OF A HIGHLY ACTIVE GROUP WORKING UNDER CODE NAME ARCHANGEL IN THE REGION AROUND NINETEEN TWELVE. UNFORTUNATELY, IT SEEMS THAT THE SHADOW ARCHIVE NETWORK WAS BY THIS STAGE SUPPORTING ARMED INSURRECTION IN THE REGION, AND WE BELIEVE THAT ITS ACTIONS MAY HAVE CONTRIBUTED, AT LEAST INDIRECTLY, TO THE EVENTS LEADING TO THE FIRST WORLD WAR.\n",
+      "THIS FACT ALONE COULD CAUSE CONSIDERABLE EMBARRASSMENT TO THE UK GOVERNMENT AND WE FEEL WE HAVE NO OPTION BUT TO RECOMMEND THAT THE SHADOW ARCHIVE AND ALL ITS NETWORKS SHOULD BE WOUND UP, ITS DOCUMENTS ANALYSED, CLASSIFIED, AND, IF NECESSARY, DESTROYED, AND ITS ASSETS DISPOSED OF. THIS REPORT SHOULD ALSO REMAIN CLASSIFIED FOR A PERIOD OF AT LEAST SEVENTY-FIVE YEARS. WE WOULD RECOMMEND A PUBLICATION DATE OF TWO THOUSAND AND TWENTY-FIVE AT EARLIEST. IN THE MEANTIME, IT SHOULD BE PRESERVED USING THE HIGHEST SECURITY AVAILABLE; IT WOULD FORM THE MOST COMPROMISING MATERIAL IF IT SHOULD FALL INTO ENEMY HANDS.\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(repunctuate(split_decipher(scb, pt_alpha, key_b), ptb))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 138,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "7503"
+      ]
+     },
+     "execution_count": 138,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('ab.plaintext', 'w').write(repunctuate(split_decipher(scb, pt_alpha, key_b), ptb))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.7"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/2018/2a.ciphertext b/2018/2a.ciphertext
new file mode 100644 (file)
index 0000000..67243db
--- /dev/null
@@ -0,0 +1,7 @@
+SPML OHK ILLU YLSHAPCLSF KBSS ZPUJL YLABYUPUN MYVT TF DVYR DPAO OHYYF PU AOL TPKKSL LHZA. AOL IYPAPZO SPIYHYF DHZ KLSPNOALK AV NLA PAZ OHUKZ VU AOL YVTHU KPHYF HUK AOL JVSSLJAVY ZLLTLK AV OHCL MVYNVAALU HIVBA TL, THFIL ILJHBZL OHYYF’Z ALHT THKL PA AVV KHUNLYVBZ AV OHUN HYVBUK. P DHZ OHWWF AV ZLAASL IHJR PU AV TF DVYR HA AOL SPIYHYF HUK DHZ PUCVSCLK PU H WYVQLJA AV AYHJR KVDU HUK JHAHSVNBL TPZZPUN KVJBTLUAZ MYVT AOL SHAL UPULALLUAO JLUABYF. AOLF KLAHPSLK MVYLPNU WVSPJF, DOPJO ZVBUKZ KBSS, IBA DPAO CPJAVYPH AHRPUN HU HJAPCL PUALYLZA AOLYL DLYL H SVA VM SLAALYZ ILADLLU KVDUPUN ZAYLLA HUK AOL WHSHJL HUK P DHZ LUQVFPUN ZWFPUN VU MHTVBZ JOHYHJALYZ MYVT OPZAVYF. P YLHSSF MLSA SPRL P DHZ NLAAPUN ZVTL PUZPNOA PUAV OVD AOLF AOVBNOA HUK OVD AOL TVKLYU DVYSK JHTL PUAV ILPUN PU AOHA ABTBSABVBZ WLYPVK.
+
+DOPSL P DHZ THPUSF AOLYL AV JOLJR AOL SLAALYZ MVY HBAOLUAPJPAF, P NVA YLHSSF PUCVSCLK PU AYFPUN AV BUKLYZAHUK OVD AOLF HSS MPAALK AVNLAOLY, HUK WHYA VM AOL QVI DHZ AV JYVZZ JOLJR ZAHALTLUAZ PU AOL SLAALYZ DPAO DOHA DL RUVD HJABHSSF OHWWLULK. AOLYL HYL H SVA VM WLVWSL DOV DPSS WHF H SVA VM TVULF AV VDU H SLAALY MYVT H YVFHS, ZV AOL HYJOPCL PZ WSHNBLK DPAO MVYNLYPLZ. ZVTL VM AOLT FVB JHU KLALJA IF HUHSFZPUN AOL WHWLY, VAOLYZ IF AOL DYPAPUN ZAFSL. ZVTL QBZA MHSS VCLY ILJHBZL AOL JVUALUA PZ VBA VM SPUL DPAO VAOLY KVJBTLUAZ, IBA HZ P ZABKPLK AOLT P ILNHU AV YLHSPZL AOHA H UBTILY VM AOLT OPUALK HA LCLUAZ AOHA P JVBSKU’A MPUK PU AOL OPZAVYPJHS YLJVYK. JLYAHPU UHTLZ HWWLHYLK HUK DLYL JSLHYSF PTWVYAHUA, HUK AOLU KPZHWWLHYLK JVTWSLALSF MYVT AYHJL. KPWSVTHAPJ PUJPKLUAZ DLYL TLUAPVULK AOHA ULCLY OHWWLULK HJJVYKPUN AV AOL OPZAVYF IVVRZ. VUL AOPUN FVB SLHYU PU AOPZ IBZPULZZ PZ AOHA AOL JPCPS ZLYCPJL ULCLY SLAZ HUF KLJPZPVU, OVDLCLY ZLJYLA, NV BUYLJVYKLK. VM JVBYZL AOHA TPNOA QBZA OHCL TLHUA AOVZL SLAALYZ HUK KVJBTLUAZ DLYL MHRL, IBA P WYPKL TFZLSM VU ILPUN HU LEJLSSLUA MVYNLY, HUK P DVBSK UVA OHCL ILLU HISL AV WYVKBJL AOLT. AOL WHWLY DHZ YPNOA, AOL PUR DHZ JOLTPJHSSF JVYYLJA HUK HNLK QBZA AOL YPNOA HTVBUA, HUK AOL ZAFSL VM DYPAPUN DHZ AVAHSSF JVUCPUJPUN. HUK P DHZ JVUCPUJLK. JVUCPUJLK AOHA ZVTLDOLYL AOLYL TBZA IL HU HYJOPCL VM NVCLYUTLUA KVJBTLUAZ MYVT AOL WLYPVK AOHA YLJVYKLK HSS VM AOLZL TPZZPUN ZAVYPLZ PU MBSS.
+
+AOLU P YLJLPCLK AOL TLZZHNL HIVBA AOL ZOHKVD HYJOPCL. ZVTLVUL LSZL RULD HIVBA PA, HUK OHK DVYRLK VBA AOHA P DHZ OBUAPUN MVY PA AVV. AOL WVZAJHYK KPKU’A OLSW TBJO, IBA AOL LTHPSZ KPK. AOL MPYZA VUL OHK AOL ZBIQLJA SPUL QLRFSS HUK OFKL HUK DHZ LUJYFWALK BZPUN H ZPTWSL JHLZHY ZOPMA AV KPZJVBYHNL JHZBHS PUALYLZA. PA KPKU’A AHRL TL SVUN AV JYHJR PA, HUK AOL UHTLZ HUK KLAHPSZ PA JVUAHPULK THAJOLK AOL NYVDPUN SPZA VM TFZALYPVBZ YLMLYLUJLZ MYVT TF VDU YLZLHYJO. KVBNSHZ ISHJR DHZ JSLHYSF HU PTWVYAHUA MPNBYL, HUK P OHK H MLLSPUN AOHA OL OHK ZVTLAOPUN AV KV DPAO AOL HYJOPCL. AOHA MLLSPUN DHZ JVUMPYTLK IF AOL ZLJVUK LTHPS, ISHJR OLHYA, AOHA P YLJLPCLK SHALY AOHA DLLR. HNHPU PA DHZ LUJYFWALK IBA AOPZ APTL BZPUN HU HMMPUL ZOPMA JPWOLY. PA DHZ JSLHYSF MYVT AOL ZHTL PUKPCPKBHS - HA AOL CLYF SLHZA DOVLCLY DHZ ZLUKPUN TL AOL LTHPSZ OHK H OHIPA VM TPZZPUN AOL SLAALY Y MYVT AOL DVYK "FVBY".
+
+ZVTLVUL DHZ WSHFPUN NHTLZ DPAO TL, HUK P DHZ TVYL AOHU OHWWF AV QVPU PU.
\ No newline at end of file
diff --git a/2018/2a.plaintext b/2018/2a.plaintext
new file mode 100644 (file)
index 0000000..527a79a
--- /dev/null
@@ -0,0 +1,7 @@
+LIFE HAD BEEN RELATIVELY DULL SINCE RETURNING FROM MY WORK WITH HARRY IN THE MIDDLE EAST. THE BRITISH LIBRARY WAS DELIGHTED TO GET ITS HANDS ON THE ROMAN DIARY AND THE COLLECTOR SEEMED TO HAVE FORGOTTEN ABOUT ME, MAYBE BECAUSE HARRY'S TEAM MADE IT TOO DANGEROUS TO HANG AROUND. I WAS HAPPY TO SETTLE BACK IN TO MY WORK AT THE LIBRARY AND WAS INVOLVED IN A PROJECT TO TRACK DOWN AND CATALOGUE MISSING DOCUMENTS FROM THE LATE NINETEENTH CENTURY. THEY DETAILED FOREIGN POLICY, WHICH SOUNDS DULL, BUT WITH VICTORIA TAKING AN ACTIVE INTEREST THERE WERE A LOT OF LETTERS BETWEEN DOWNING STREET AND THE PALACE AND I WAS ENJOYING SPYING ON FAMOUS CHARACTERS FROM HISTORY. I REALLY FELT LIKE I WAS GETTING SOME INSIGHT INTO HOW THEY THOUGHT AND HOW THE MODERN WORLD CAME INTO BEING IN THAT TUMULTUOUS PERIOD.
+
+WHILE I WAS MAINLY THERE TO CHECK THE LETTERS FOR AUTHENTICITY, I GOT REALLY INVOLVED IN TRYING TO UNDERSTAND HOW THEY ALL FITTED TOGETHER, AND PART OF THE JOB WAS TO CROSS CHECK STATEMENTS IN THE LETTERS WITH WHAT WE KNOW ACTUALLY HAPPENED. THERE ARE A LOT OF PEOPLE WHO WILL PAY A LOT OF MONEY TO OWN A LETTER FROM A ROYAL, SO THE ARCHIVE IS PLAGUED WITH FORGERIES. SOME OF THEM YOU CAN DETECT BY ANALYSING THE PAPER, OTHERS BY THE WRITING STYLE. SOME JUST FALL OVER BECAUSE THE CONTENT IS OUT OF LINE WITH OTHER DOCUMENTS, BUT AS I STUDIED THEM I BEGAN TO REALISE THAT A NUMBER OF THEM HINTED AT EVENTS THAT I COULDN'T FIND IN THE HISTORICAL RECORD. CERTAIN NAMES APPEARED AND WERE CLEARLY IMPORTANT, AND THEN DISAPPEARED COMPLETELY FROM TRACE. DIPLOMATIC INCIDENTS WERE MENTIONED THAT NEVER HAPPENED ACCORDING TO THE HISTORY BOOKS. ONE THING YOU LEARN IN THIS BUSINESS IS THAT THE CIVIL SERVICE NEVER LETS ANY DECISION, HOWEVER SECRET, GO UNRECORDED. OF COURSE THAT MIGHT JUST HAVE MEANT THOSE LETTERS AND DOCUMENTS WERE FAKE, BUT I PRIDE MYSELF ON BEING AN EXCELLENT FORGER, AND I WOULD NOT HAVE BEEN ABLE TO PRODUCE THEM. THE PAPER WAS RIGHT, THE INK WAS CHEMICALLY CORRECT AND AGED JUST THE RIGHT AMOUNT, AND THE STYLE OF WRITING WAS TOTALLY CONVINCING. AND I WAS CONVINCED. CONVINCED THAT SOMEWHERE THERE MUST BE AN ARCHIVE OF GOVERNMENT DOCUMENTS FROM THE PERIOD THAT RECORDED ALL OF THESE MISSING STORIES IN FULL.
+
+THEN I RECEIVED THE MESSAGE ABOUT THE SHADOW ARCHIVE. SOMEONE ELSE KNEW ABOUT IT, AND HAD WORKED OUT THAT I WAS HUNTING FOR IT TOO. THE POSTCARD DIDN'T HELP MUCH, BUT THE EMAILS DID. THE FIRST ONE HAD THE SUBJECT LINE JEKYLL AND HYDE AND WAS ENCRYPTED USING A SIMPLE CAESAR SHIFT TO DISCOURAGE CASUAL INTEREST. IT DIDN'T TAKE ME LONG TO CRACK IT, AND THE NAMES AND DETAILS IT CONTAINED MATCHED THE GROWING LIST OF MYSTERIOUS REFERENCES FROM MY OWN RESEARCH. DOUGLAS BLACK WAS CLEARLY AN IMPORTANT FIGURE, AND I HAD A FEELING THAT HE HAD SOMETHING TO DO WITH THE ARCHIVE. THAT FEELING WAS CONFIRMED BY THE SECOND EMAIL, BLACK HEART, THAT I RECEIVED LATER THAT WEEK. AGAIN IT WAS ENCRYPTED BUT THIS TIME USING AN AFFINE SHIFT CIPHER. IT WAS CLEARLY FROM THE SAME INDIVIDUAL - AT THE VERY LEAST WHOEVER WAS SENDING ME THE EMAILS HAD A HABIT OF MISSING THE LETTER R FROM THE WORD "YOUR".
+
+SOMEONE WAS PLAYING GAMES WITH ME, AND I WAS MORE THAN HAPPY TO JOIN IN.
\ No newline at end of file
diff --git a/2018/2b.ciphertext b/2018/2b.ciphertext
new file mode 100644 (file)
index 0000000..a870d7b
--- /dev/null
@@ -0,0 +1,7 @@
+GYN OFCNDAG,
+
+YZ YG EYZF NAMNAZ ZFCZ Y TYPH WQGADT YP HYGCMNAAWAPZ EYZF QIS RSHMAWAPZ. YZ YG ODACN ZI WA ZFCZ QIS CNA NYMFZ YP IPA NAMCNH, YZ YG ZYWA ZI AGZCVDYGF ZFA ITTYOA IT GAONAZ GAONAZCNQ, CPH ZI ZCKA ZFA GAONAZ ECN ZI ISN APAWYAG. IP IPA GYMPYTYOCPZ BIYPZ FIEALAN, Y HI PIZ CMNAA. ZFYG NIDA YG PIZ GSYZAH ZI MIIH WAP EYZF C NABSZCZYIP TIN FIPISN. QISN GSMMAGZYIPG EISDH VA OCBYZCD YT Y EANA DIIKYPM ZI CBBIYPZ C OFYAT IT GZCTT IN C PAE TINAYMP GAONAZCNQ, FIEALAN ZFA ZCGKG ZFCZ EA VIZF KPIE CNA PAOAGGCNQ YT EA CNA ZI BNIZAOZ CPH AXBCPH ZFA AWBYNA EYDD NAUSYNA C WCP IT CDZIMAZFAN HYTTANAPZ OFCNCOZAN. C NAH VDIIHAH WCP EYZF C VDCOK FACNZ.
+
+ZFANA YG IPA WCP EA VIZF KPIE EFI YG APZYNADQ GSYZAH ZI ZFA DAGG OIPMAPYCD CGBAOZG IT WIHANP GZCZAONCTZ, CPH Y CW GSNBNYGAH ZFCZ QIS HYH PIZ CHH FYG PCWA ZI ZFA DYGZ - QIS CWANYOCP OISGYP HISMDCG VDCOK. VDCOK YG C WCP IT GYPMSDCN ZCDAPZG CPH Y EISDH GSMMAGZ ZFCZ QIS COZ EYZF SZWIGZ GBAAH ZI VNYPM FYW ZI DIPHIP. Y VADYALA ZFCZ FA YG OSZ TNIW ZFA GCWA ODIZF CG QIS, CPH Y CW OIPTYHAPZ ZFCZ QIS EYDD VA CVDA ZI BANGSCHA FYW ZI ZCKA SB ZFA BIGZ IT GAONAZ GAONAZCNQ. Y CW NCZFAN DIIKYPM TINECNH ZI WQ TYNGZ WAAZYPM EYZF WN. VDCOK CPH Y ZNSGZ QIS EYDD PIZ HYGCBBIYPZ WA YP ZFYG, VSZ YT QIS TYPH ZFCZ FA YG PIZ CWAPCVDA ZI NACGIP ZFAP Y EYDD TYPH CPIZFAN ECQ ZI BANGSCHA FYW. C WCP DYKA VDCOK CDECQG FCG C GKADAZIP IN ZEI YP FYG ODIGAZ!
+
+L.
\ No newline at end of file
diff --git a/2018/2b.plaintext b/2018/2b.plaintext
new file mode 100644 (file)
index 0000000..50e5f33
--- /dev/null
@@ -0,0 +1,7 @@
+SIR CHARLES,
+
+IT IS WITH REGRET THAT I FIND MYSELF IN DISAGREEMENT WITH YOU JUDGEMENT. IT IS CLEAR TO ME THAT YOU ARE RIGHT IN ONE REGARD, IT IS TIME TO ESTABLISH THE OFFICE OF SECRET SECRETARY, AND TO TAKE THE SECRET WAR TO OUR ENEMIES. ON ONE SIGNIFICANT POINT HOWEVER, I DO NOT AGREE. THIS ROLE IS NOT SUITED TO GOOD MEN WITH A REPUTATION FOR HONOUR. YOUR SUGGESTIONS WOULD BE CAPITAL IF I WERE LOOKING TO APPOINT A CHIEF OF STAFF OR A NEW FOREIGN SECRETARY, HOWEVER THE TASKS THAT WE BOTH KNOW ARE NECESSARY IF WE ARE TO PROTECT AND EXPAND THE EMPIRE WILL REQUIRE A MAN OF ALTOGETHER DIFFERENT CHARACTER. A RED BLOODED MAN WITH A BLACK HEART.
+
+THERE IS ONE MAN WE BOTH KNOW WHO IS ENTIRELY SUITED TO THE LESS CONGENIAL ASPECTS OF MODERN STATECRAFT, AND I AM SURPRISED THAT YOU DID NOT ADD HIS NAME TO THE LIST - YOU AMERICAN COUSIN DOUGLAS BLACK. BLACK IS A MAN OF SINGULAR TALENTS AND I WOULD SUGGEST THAT YOU ACT WITH UTMOST SPEED TO BRING HIM TO LONDON. I BELIEVE THAT HE IS CUT FROM THE SAME CLOTH AS YOU, AND I AM CONFIDENT THAT YOU WILL BE ABLE TO PERSUADE HIM TO TAKE UP THE POST OF SECRET SECRETARY. I AM RATHER LOOKING FORWARD TO MY FIRST MEETING WITH MR. BLACK AND I TRUST YOU WILL NOT DISAPPOINT ME IN THIS, BUT IF YOU FIND THAT HE IS NOT AMENABLE TO REASON THEN I WILL FIND ANOTHER WAY TO PERSUADE HIM. A MAN LIKE BLACK ALWAYS HAS A SKELETON OR TWO IN HIS CLOSET!
+
+V.
\ No newline at end of file
diff --git a/2018/3a.ciphertext b/2018/3a.ciphertext
new file mode 100644 (file)
index 0000000..b36aef0
--- /dev/null
@@ -0,0 +1 @@
+FTNPTQP RDF TGOBTLFKX HPPQ IYDI B FYTLKM HQTR DGTLI MTLVKDF GKDJH GLI B RDF KPSI RTQMPCBQV RYDI YP YDM IT MT RBIY IYP FYDMTR DCJYBOP. B STLQM FTNP ICDJPF TS YBN BQ GTFITQ QPRFWDWPC JKBWWBQVF SCTN IYP WPCBTM. IYP FITCBPF FITWWPM BQ 1873, DCTLQM IYP MDIP TS IYP KPIIPCF GPIRPPQ OBJITCBD DQM FBC JYDCKPF, FT B DFFLNP YP CPILCQPM IT PQVKDQM IYPQ, GLI B JTLKMQ’I SBQM DQX CPJTCM TS YBN BQ IYP BNNBVCDIBTQ SBKPF DQM IYPCP RDF QTIYBQV BQ IYP TSSBJBDK CPJTCM IT FLVVPFI IYDI YP NPI RBIY FBC JYDCKPF, KPI DKTQP RBIY YPC NDEPFIX. IYP ICDBK YDM VTQP JTKM DQM B NBVYI YDOP NTOPM TQ DI IYDI WTBQI, GLI IYPQ B VTI IYP IYBCM PNDBK. IYBF IBNP BI RDF D HPXRTCM JBWYPC DQM BI ITTH D KBIIKP KTQVPC IT GCPDH, IYTLVY IYP RTCM FICLJILCP YPKWPM D KTI. BI JTQSBCNPM POPCXIYBQV B YDM VLPFFPM FT SDC DGTLI GKDJH, DQM CDBFPM D RYTKP KTDM TS QPR ZLPFIBTQF! BI DKFT FLVVPFIPM IYDI B NBVYI SBQM DQFRPCF BQ IYP FYDMTR DCJYBOP, GLI SBCFI B YDM IT SBVLCP TLI RYPCP BI RDF, DQM YTR B JTLKM VPI BQ. B FIBKK JDQ’I GPKBPOP BI, GLI IYP DQFRPC JDNP SCTN D VTTVKP FPDCJY. B RDF KTTHBQV STC D KTJDIBTQ IYDI RTLKM YDOP WCTOBMPM GKDJH RBIY JTOPC STC D FICPDN TS OBFBITCF, WCPSPCDGKX BQ D JPQICDK KTQMTQ KTJDIBTQ, DQM RBIY SDJBKBIBPF STC FPJLCP FITCDVP TS TSSBJBDK CPJTCMF, DQM BI FYTLKM YDOP GPPQ TWPQPM BQ 1873 TC 1874. B FPDCJYPM STC “GKDJH, KTQMTQ, 1874” DQM B KBHPM RYDI B STLQM. DQM IYDI BF RYX B STLQM NXFPKS KXBQV TQ IYP CTTS TS IYP QTCNDQ FYDR GLBKMBQVF BQ IYP NBMMKP TS IYP QBVYI DQM BQ WTLCBQV CDBQ! B YDM IT SBVLCP TLI D RDX TS VPIIBQV BQFBMP TQP TS IYP NTFI FPJLCP KTJDIBTQF BQ PQVKDQM!
diff --git a/2018/3a.plaintext b/2018/3a.plaintext
new file mode 100644 (file)
index 0000000..bb32477
--- /dev/null
@@ -0,0 +1 @@
+SOMEONE WAS OBVIOUSLY KEEN THAT I SHOULD KNOW ABOUT DOUGLAS BLACK BUT I WAS LEFT WONDERING WHAT HE HAD TO DO WITH THE SHADOW ARCHIVE. I FOUND SOME TRACES OF HIM IN BOSTON NEWSPAPER CLIPPINGS FROM THE PERIOD. THE STORIES STOPPED IN 1873, AROUND THE DATE OF THE LETTERS BETWEEN VICTORIA AND SIR CHARLES, SO I ASSUME HE RETURNED TO ENGLAND THEN, BUT I COULDN’T FIND ANY RECORD OF HIM IN THE IMMIGRATION FILES AND THERE WAS NOTHING IN THE OFFICIAL RECORD TO SUGGEST THAT HE MET WITH SIR CHARLES, LET ALONE WITH HER MAJESTY. THE TRAIL HAD GONE COLD AND I MIGHT HAVE MOVED ON AT THAT POINT, BUT THEN I GOT THE THIRD EMAIL. THIS TIME IT WAS A KEYWORD CIPHER AND IT TOOK A LITTLE LONGER TO BREAK, THOUGH THE WORD STRUCTURE HELPED A LOT. IT CONFIRMED EVERYTHING I HAD GUESSED SO FAR ABOUT BLACK, AND RAISED A WHOLE LOAD OF NEW QUESTIONS! IT ALSO SUGGESTED THAT I MIGHT FIND ANSWERS IN THE SHADOW ARCHIVE, BUT FIRST I HAD TO FIGURE OUT WHERE IT WAS, AND HOW I COULD GET IN. I STILL CAN’T BELIEVE IT, BUT THE ANSWER CAME FROM A GOOGLE SEARCH. I WAS LOOKING FOR A LOCATION THAT WOULD HAVE PROVIDED BLACK WITH COVER FOR A STREAM OF VISITORS, PREFERABLY IN A CENTRAL LONDON LOCATION, AND WITH FACILITIES FOR SECURE STORAGE OF OFFICIAL RECORDS, AND IT SHOULD HAVE BEEN OPENED IN 1873 OR 1874. I SEARCHED FOR “BLACK, LONDON, 1874” AND I LIKED WHAT I FOUND. AND THAT IS WHY I FOUND MYSELF LYING ON THE ROOF OF THE NORMAN SHAW BUILDINGS IN THE MIDDLE OF THE NIGHT AND IN POURING RAIN! I HAD TO FIGURE OUT A WAY OF GETTING INSIDE ONE OF THE MOST SECURE LOCATIONS IN ENGLAND!
diff --git a/2018/3b.ciphertext b/2018/3b.ciphertext
new file mode 100644 (file)
index 0000000..a52eba3
--- /dev/null
@@ -0,0 +1,7 @@
+CTN HLETPQW DP NDBCQ, GDZT DI OJPQJI DP ARGG, ORQ IJQ ARGG TIJRBC QJ KTNPRLAT HT QCLQ UJNFDIB ZJN CTN UJRGA OT UJNQC QCT NDPF. ORQ JZ YJRNPT PCT CLA LI LIPUTN ZJN QCLQ. PCT KJDIQTA JRQ QCLQ NTQRNIDIB QJ QCT RIDQTA PQLQTP YLNNDTA DQP JUI NDPFP.
+
+D CLA FTKQ HWPTGZ LHRPTA ZJN QCT GLPQ ZTU WTLNP PTKLNLQDIB QCT BNTTAW LIA STILG ZNJH QCTDN HJITW OW L SLNDTQW JZ HTLIP, IJQ LGG JZ QCTH TIQDNTGW LKKNJSTA OW QCT GLU. D ULP GTZQ UJIATNDIB CJU QCT MRTTI FITU LOJRQ QCLQ, LIA UCTQCTN HW YJRPDI CLA OTTI DIPQNRYQTA QJ QTGG QCT ZTATNLG HLNPCLGGP LOJRQ HW LYQDSDQDTP. ADPYNTQDJI PTTHTA QCT UDPT YJRNPT, LIA LIWULW, CJU JZQTI AJ WJR BTQ L EJO JZZTN ZNJH L MRTTI?
+
+YCLNGTP CLP AJIT L PQTNGDIB EJO ATSTGJKDIB L ITQUJNF JZ LBTIQP LIA CDP DIQTGGDBTIYT JKTNLQDJIP CLST OTYJHT L FTW KLNQ JZ ONDQDPC ADKGJHLYW. QCT BNJUDIB DIPQLODGDQW LYNJPP TRNJKT QCNTLQTIP QCT THKDNT, LIA DQ DP CTN HLETPQW’P OTGDTZ QCLQ UT UDGG ITTA QJ NTPKJIA DI FDIA QJ ATPQLODGDPT JRN TITHDTP OTZJNT QCTW BNJU QJJ PQNJIB. QCDP DP L ITU LIA ALIBTNJRP FDIA JZ ULNZLNT, ORQ YJRGA, D PRKKJPT, PLST GDSTP, LIA UT UDGG, DI LIW YLPT, ITTA QJ HLQYC JRN TITHDTP DZ UT LNT QJ PQLW LCTLA.
+
+QCDP TIQDNT JKTNLQDJI HRPQ OT FTKQ PTYNTQ. ZDNPQ ZNJH JRN TITHDTP, ORQ PTYJIA, LIA ERPQ LP DHKJNQLIQ, ZNJH QCT JZZDYDLG HLYCDITNW JZ PQLQT. CTN HLETPQW YLIIJQ LZZJNA QCT NDPF QCLQ CTN BJSTNIHTIQ YJRGA OT DHKGDYLQTA DI QCTPT JKTNLQDJIP, LIA PDN YCLNGTP CLP NTLPJI QJ OTGDTST QCLQ QCT ZJNTDBI JZZDYT HLW CLST OTTI YJHKNJHDPTA. ZJN QCDP NTLPJI UT ITTA QJ HJST PDN YCLNGTP’ DIQTGGDBTIYT JKTNLQDJI QJ L HJNT PTYRNT GJYLQDJI. LIA D QCDIF D CLST LI DATL UCTNT QCLQ YJRGA OT!
\ No newline at end of file
diff --git a/2018/3b.plaintext b/2018/3b.plaintext
new file mode 100644 (file)
index 0000000..27b9736
--- /dev/null
@@ -0,0 +1,7 @@
+her majesty is right, life in boston is dull, but not dull enough to persuade me that working for her would be worth the risk. but of course she had an answer for that. she pointed out that returning to the united states carried its own risks.
+
+i had kept myself amused for the last few years separating the greedy and venal from their money by a variety of means, not all of them entirely approved by the law. i was left wondering how the queen knew about that, and whether my cousin had been instructed to tell the federal marshalls about my activities. discretion seemed the wise course, and anyway, how often do you get a job offer from a queen?
+
+charles has done a sterling job developing a network of agents and his intelligence operations have become a key part of british diplomacy. the growing instability across europe threatens the empire, and it is her majesty’s belief that we will need to respond in kind to destabilise our enemies before they grow too strong. this is a new and dangerous kind of warfare, but could, i suppose, save lives, and we will, in any case, need to match our enemies if we are to stay ahead.
+
+this entire operation must be kept secret. first from our enemies, but second, and just as important, from the official machinery of state. her majesty cannot afford the risk that her government could be implicated in these operations, and sir charles has reason to believe that the foreign office may have been compromised. for this reason we need to move sir charles’ intelligence operation to a more secure location. and i think i have an idea where that could be!
\ No newline at end of file
diff --git a/2018/4a.ciphertext b/2018/4a.ciphertext
new file mode 100644 (file)
index 0000000..9b3db5a
--- /dev/null
@@ -0,0 +1,3 @@
+JUR DYKR NLH VB JUR BLZR. JUR IYLDX ZKHRKZ VH NCGYA SLZCKH LH JUR VB-UCKHR ZKHRKZ CS DGVZR LJ BRN HDCJYLBA PLGA. JUR UVHJCGP ICCXH (CG LJ YRLHJ, NVXVERAVL) JCYA ZR JULJ VJ ULA IRRB HRJ KE IP VBHERDJCG BRLZR LBA ED GLBALYY HCZR JVZR LSJRG LEGVY 1875 LH L NLP JC KHR JUR EGVHCBRGH’ EGCERGJP HJCGR JC VBHJGKDJ BRN GRDGKVJH VB JUR LGJ CS ARJRDJVCB. JUR BLZR SVGHJ LEERLGH VB EKIYVD VB LB LGJVDYR VB JUR CIHRGMRG BRNHELERG VB 1877, LBA JUR UVHJCGVLBH HLP VJ NLH DCVBRA LH L TGVHYP URLAYVBR IP L WCKGBLYVHJ NUC NLH HBKIIRA IP BRLZR, IKJ V LZ BCJ HC HKGR. VJ AVAB’J HRRZ LB LDDVARBJ JULJ ACKTYLH IYLDX NLH YCCXVBT JC HRJ KE L JCE HRDGRJ LGDUVMR VB YCBACB LJ JULJ JVZR, LBA HDCJYLBA PLGA TLMR UVZ JUR ERGSRDJ YCDLJVCB. VJ NLH DRBJGLY LBA RLHP JC LDDRHH. VJ ULA HRMRGLY RBJGLBDRH, NVJU L HJRLAP SYCN CS MVHVJCGH, BCJ LYY CS JURZ RBJVGRYP GREKJLIYR, JULJ NCKYA AVHTKVHR JUR DCZVBTH LBA TCVBTH CS JUR LTRBJH LBA CSSVDRGH CS IYLDX’H BRJNCGX. IRHJ CS LYY VJ ULA JUR RBJVGR ZRJGCECYVJLB ECYVDR SCGDR HJLBAVBT TKLGA, NUVDU NLH TGRLJ SCG IYLDX, LBA JCKTU CB ZR. VJ NCKYA IR JUR VARLY YCDLJVCB SCG JUR HULACN LGDUVMR.
+HDCJYLBA PLGA ULA ZCMRA JC BRN EGRZVHRH HRMRGLY JVZRH HVBDR VJ NLH SVGHJ HRJ KE, IKJ V NLH IRJJVBT JULJ JUR HULACN LGDUVMR ULA ZCMRA NVJU VJ, LBA V HERBJ JUR IRHJ ELGJ CS JUGRR NRRXH HDCKJVBT JUR BCGZLB HULN IKVYAVBTH LBA JUR BRN “BRN HDCJYLBA PLGA” BROJ ACCG LJ JUR DKGJVH TGRRB IKVYAVBT. VJ VH BCJ RLHP JC AC JULJ NVJUCKJ IRVBT HECJJRA, URBDR JUR BVTUJ JVZR GRDCBBLVHHLBDR VB JUR GLVB. JUR NLJRG LBA JUR DCYA EYLPRA ULMCD NVJU ZP ZCCA, IKJ LYHC NVJU ZLBP ARJRDJCG HPHJRZH HC VJ NLH NCGJU JUR AVHDCZSCGJ.
+BC-CBR NLH YVXRYP JC TVMR ZR JUR GRLY EYLBH CS JUR EYLDR, JUCKTU ULGGP NLH ULEEP JC EGCMVAR ZR NVJU L DCEP CS JUR CSSVDVLY YLPCKJ, LBA V KHRA L YVALG HPHJRZ JC ZLE LH ZKDU CS JUR CKJHVAR LH V DCKYA. DCZELGVBT JUR JNC HUCKYA ULMR GRMRLYRA KBZLGXRA HJCGLTR LGRLH LBA TVMRB ZR HCZR VARL UCN V ZVTUJ TRJ VB, IKJ BCJUVBT HUCNRA KE KBJVY V ULA L YKDXP IGRLX. YVJRGLYYP. V ULA YCNRGRA JUR YVALG ARJRDJCG ACNB L HULSJ CB JUR DKGJVH TGRRB GCCS, UCEVBT JC TRJ L TYVZEHR VBJC HCZR CS JUR BRLGIP GCCZH. VJ ULA WKHJ LICKJ GRLDURA TGCKBA YRMRY NURB JUR BPYCB YVBR HBLEERA. VJ ZLAR L URYY CS L GCN LH VJ DYLJJRGRA ACNB, LBA V EGRELGRA JC GKB, IKJ BC LYLGZH NRBJ CSS LBA, ZCGR VZECGJLBJYP, V BCJVDRA HCZRJUVBT HVTBVSVDLBJ. VJ ULA JLXRB LGCKBA SVMR HRDCBAH SCG JUR YVALG JC DGLHU ACNB, NUVDU, LJ L GCKTU RHJVZLJR, ZRLBJ VJ ULA SLYYRB SGRR SCG LGCKBA CBR UKBAGRA LBA JNRBJP ZRJGRH. JULJ NCKYA ULMR JLXRB VJ L YCBT NLP KBARGTGCKBA, LBA JURGR NRGR BC ILHRZRBJ GCCZH ZLGXRA CB JUR EYLBH VB JULJ YCDLJVCB. V NLH EGRJJP HKGR V ULA SCKBA JUR HULACN LGDUVMR: BCN V WKHJ ULA JC SVBA L NLP VB.
diff --git a/2018/4a.plaintext b/2018/4a.plaintext
new file mode 100644 (file)
index 0000000..c4b80e0
--- /dev/null
@@ -0,0 +1,3 @@
+the clue was in the name. the black museum is world famous as the in-house museum of crime at new scotland yard. the history books (or at least, wikipedia) told me that it had been set up by inspector neame and pc randall some time after april 1875 as a way to use the prisoners’ property store to instruct new recruits in the art of detection. the name first appears in public in an article in the observer newspaper in 1877, and the historians say it was coined as a grisly headline by a journalist who was snubbed by neame, but i am not so sure. it didn’t seem an accident that douglas black was looking to set up a top secret archive in london at that time, and scotland yard gave him the perfect location. it was central and easy to access. it had several entrances, with a steady flow of visitors, not all of them entirely reputable, that would disguise the comings and goings of the agents and officers of black’s network. best of all it had the entire metropolitan police force standing guard, which was great for black, and tough on me. it would be the ideal location for the shadow archive.
+scotland yard had moved to new premises several times since it was first set up, but i was betting that the shadow archive had moved with it, and i spent the best part of three weeks scouting the norman shaw buildings and the new “new scotland yard” next door at the curtis green building. it is not easy to do that without being spotted, hence the night time reconnaissance in the rain. the water and the cold played havoc with my mood, but also with many detector systems so it was worth the discomfort.
+no-one was likely to give me the real plans of the place, though harry was happy to provide me with a copy of the official layout, and i used a lidar system to map as much of the outside as i could. comparing the two should have revealed unmarked storage areas and given me some idea how i might get in, but nothing showed up until i had a lucky break. literally. i had lowered the lidar detector down a shaft on the curtis green roof, hoping to get a glimpse into some of the nearby rooms. it had just about reached ground level when the nylon line snapped. it made a hell of a row as it clattered down, and i prepared to run, but no alarms went off and, more importantly, i noticed something significant. it had taken around five seconds for the lidar to crash down, which, at a rough estimate, meant it had fallen free for around one hundred and twenty metres. that would have taken it a long way underground, and there were no basement rooms marked on the plans in that location. i was pretty sure i had found the shadow archive: now i just had to find a way in.
diff --git a/2018/4b.ciphertext b/2018/4b.ciphertext
new file mode 100644 (file)
index 0000000..2f76280
--- /dev/null
@@ -0,0 +1 @@
+ATRDW PFKFD KITGG TPGTD PRGFG ZGTPP RFGRD PIDZM KYIEQ GTPLR QKYGT PFZHG TPDYD PIKZY GTPZG GZXRY FRDPD PFGWP FFRYL KYGTP YZDGT GTPGT DPPPX BPDZD FRDPR IDZMK YIGTD PRGGZ ZHDKY OWHPY APGTP OZDPK IYZOO KAPFP PXBRD RWQFP LOZAH FFPLP YGKDP WQZYO ZDXKY IRWWK RYAPF RYLHY REWPG ZLPGP DXKYP GTPKD EPFGF GDRGP IQKGT KYVGT PQRDP XKFGR VPYKY GTPKD ZHGWZ ZVGTP QOZAH FGZZX HATZY GDPRG KPFRY LYZGP YZHIT ZYDPR WBZWK GKVRF JZYDZ ATRHM DZGPG TPWRM ZOBZM PDIZJ PDYFG TPMZD WLZOF GRGPF UHFGR FGTPW RMZOI DRJKG QIZJP DYFGT PBTQF KARWM ZDWLR YLMPR DPBPD TRBFG ZZXHA TKYAW KYPLG ZZJPD WZZVG TPDPR WXKIT GZOGT PXZDP BZMPD OHWRY LGTPK YPJKG REKWK GQZOK GFBZW KGKAR WKYOW HPYAP ZHDGR FVYZM KFYZG GZATZ ZFPRO RJZHD PLBRD GYPDG ZAZYG DZWGT PZGTP DFGTR GMRQD KFVFM RDRYR WWKRY APMKW WPYAZ HDRIP RAZHY GPDRW WKRYA PRYLR LRYIP DZHFP FARWR GKZYK YFGPR LZHDF GDRGP IQFTZ HWLEP GZXRK YGRKY RYRLX KGGPL WQHYP RFQBP RAPEP GMPPY GTPPX BPDZD FGZIP GTPDG TPQRD PGTPE KIIPF GBZWK GKARW GTDPR GGZZH DPXBK DPEHG RFPYP XKPFZ OZYPR YZGTP DGTPQ RWFZG TDPRG PYZHD GDRLK YIDZH GPFMP YPPLG ZKYLH APGTP XGZMZ DVGZI PGTPD MTKWP BDPJP YGKYI GTPXO DZXOZ DXKYI RBZMP DEWZA RIRKY FGZHD KYGPD PFGZH DXZFG KXBZD GRYGM PRBZY KYGTK FKFAZ YOHFK ZYRYL XKWLL KFGDH FGGTP EPFGZ HGAZX PMZHW LEPGZ PYAZH DRIPR LQFOH YAGKZ YRWRW WKRYA PEPGM PPYRW WGTDP PGTRG XRVPF KGTRD LOZDG TPPXB PDZDF GZOKI TGZYP RYZGT PDZDH FRYLK YGTPZ GGZXR YADKF KFKGT KYVKF PYFPR YZBBZ DGHYK GQGZL ZUHFG GTRG
diff --git a/2018/4b.plaintext b/2018/4b.plaintext
new file mode 100644 (file)
index 0000000..99e1c4a
--- /dev/null
@@ -0,0 +1,15 @@
+charles is right the threats to the east are growing by the day in the southern region the ottomans
+are restless and in the north the three emperors area growing threat to our influence the foreign
+office seem paralysed focussed entirely on forming alliances and unable to determine their best
+strategy i think they are mistaken in their outlook they focus too much on treaties and not enough
+on realpolitik as von rocha u wrote the law of power governs the world of states just as the law of
+gravity governs the physical world and we are perhaps too much inclined to overlook the real might
+of the more powerful and the inevitability of its political influence our task now is not to choose
+a favoured partner to control the others that way risks war an alliance will encourage a counter
+alliance and a dangerous escalation instead our strategy should be to maintain an admittedly uneasy
+peace between the emperors together they are the biggest political threat to our empire but as
+enemies of one another they also threaten our trading routes we need to induce them to work together
+while preventing them from forming a power bloc against our interest our most important weapon in
+this is confusion and mild distrust the best outcome would be to encourage a dysfunctional alliance
+between all three that makes it hard for the emperors to fight one another or us and in the ottoman
+crisis i think i sense an opportunity to do just that
\ No newline at end of file
diff --git a/2018/5a.ciphertext b/2018/5a.ciphertext
new file mode 100644 (file)
index 0000000..a8bb657
--- /dev/null
@@ -0,0 +1 @@
+UAYHJ UXXZB JHKGN MTUIT BEJTN JMBIA YNKCM UJTJT NUDNA BEJTN KZDNG SGBKZ DAGIT ULNUJ MUXXT ALNAC CNAXN DJBRX AIWAH AMAPJ BCGBL UDNHN IKGUJ PJBTU HBCNG AJUBZ RKJAI ULUXN ZSUZN NGUZS CGBVN IJBEJ TUHHI AXNDB NHZJH NNYXU WNTUH HBGJB EJTUZ SHBUJ TUZWU JYKHJ TALNR NNZIB ZINUL NDRPI TAGXN HSGNP JTNEU GHJJK RNXUZ NTADR NNZBC NZNDU ZAZDX BZDBZ MAHEK XXBEX ARBKG NGHAZ DNZSU ZNNGH MUJTJ TNHWU XXHZN NDNDJ BRKUX DJTNH TADBM AGITU LNDNN CRNZN AJTZN MHIBJ XAZDP AGDSN JJUZS AIINH HMAHZ BJSBU ZSJBR NNAHP MUJTB KJTAG GPHTN XCRKJ UHJUX XDUDZ JTALN NZBKS TJBSU LNTUY JTNNO IKHNT NMBKX DZNND JBSNJ BCNZX PUZLB XLNDY PGNIB ZZAUH HAZIN TADTN XCNDY NJBEU ZDJTN AGITU LNRKJ UJDUD ZJSUL NYNAZ PBRLU BKHMA PUZJT NDKIJ JTAJT ADIBH JYNJT NXUDA GMAHE AGJBB ZAGGB MEBGY NJBHI AXNAZ DAIIN HHJTG BKSTJ TNEGB ZJDBB GMAHJ BBGUH WPHBU JBBWA SAYRX NAZDH CNZJA ZBJTN GYUHN GARXN EBGJZ USTJN OCXBG UZSJT NXARP GUZJT BEHNM NGHAZ DJKZZ NXHPH JNYHA GBKZD JTNZN USTRB KGTBB DSCHM AHKHN XNHHD BMZJT NGNAZ DUIBK XDNAH UXPTA LNSBJ XBHJR KJUYA GWNDJ TNJKZ ZNXHA ZDBZB IIAHU BZHKH NDJTN HNKHJ GUIWB EARAX XBEJM UZNJB TNXCY NZALU SAJNR AIWUY BLNDF KUNJX PAZDW NCJAZ NPNBK JEBGH NZHBG HUTAD ZBUDN AMTNJ TNGJT NHTAD BMAGI TULNM AHHJU XXBCN GAJUB ZAXBG ZBJRK JUEUJ MAHJT NZHNI KGUJP MBKXD RNJUS TJAZD UIBKX DZJRN HKGNU EJTNP MNGNK HUZSU ZEGAG NDBGH NUHYB YNJNG HEBGU ZJGKH UBZDN JNIJU BZHBU XAPNG NDKCM UJTUZ HKXAJ UBZAZ DYBLN DHXBM XPUJM AHTBG GURXN UMAHT BJDAY CAZDJ TNAUG HYNXX NDBEH NMASN AZDYB KXDUM AHVKH JARBK JJBSU LNKCM TNZUE BKZDA HJNNX DBBGY AGWND MUJTJ TNUZU JUAXH LGULU IJBGU AGNSU ZAUYC NGAJG UOUJM AHUZI BZSGK BKHUZ JTAJD AGWAZ DDAZW JKZZN XRKJY BGNHU SZUEU IAZJX PUJIA GGUND JTNJG ADNYA GWJAZ ZBZJT NXBIW VBTZJ AZZMA HBZNB EJTNJ BCHAE NYAWN GHUZL UIJBG UAZXB ZDBZA ZDUTA DIGAI WNDBZ NBGJM BBETU HHAEN HUZYP BJTNG XUENA HAIAJ RKGSX AGJTU HMAHR USAZD TNALP AZDLN GPGKH JPJTA JJBXD YNJMB JTUZS HZBBZ NTADK HNDUJ UZALN GPXBZ SJUYN AZDZB BZNTA DKCSG ADNDU JUZVK HJAHX BZSUE JTNGB BYRNT UZDUJ MAHHJ UXXUZ KHNJT NZHBY NBZNM BKXDT ALNRN NZYAU ZJAUZ UZSJT NXBIW HBAXX YPCGN IAKJU BZHMN GNCGB RARXP KZZNI NHHAG PRKJZ BBZNT ADCAU DEBGA JAZZH AENMU JTBKJ HBYNJ TUZSU YCBGJ AZJJB TUDNH BUDNI UDNDJ BJAIW XNJTN XBIWA ZDAEJ NGAZB JTNGN USTJN NZTBK GHBES GUYMB GWUMA HUZUT ADEBK ZDJTN HTADB MAGIT ULN
diff --git a/2018/5a.plaintext b/2018/5a.plaintext
new file mode 100644 (file)
index 0000000..86bfbfa
--- /dev/null
@@ -0,0 +1,24 @@
+i am still not sure which of the two came up with the idea of the underground archive it will have
+appealed to black as away to provide security to his operation but a civil engineering project of
+this scale doesnt seem like his sort of things oi think it must have been conceived by charles grey
+the first tube line had been opened in and london was full of labourers and engineers with the
+skills needed to build the shadow archive deep beneath new scotland yard getting access was not
+going to be easy without harrys help but i still didnt have enough to give him the excuse he would
+need to get openly involved my reconnaissance had helped me to find the archive but it didnt give me
+any obvious way in the duct that had cost me the lidar was far too narrow for me to scale and access
+through the frontdoor was too risky so i took a gamble and spent another miserable fortnight
+exploring the labyrinth of sewers and tunnel systems around the neighbourhood gps was useless down
+there and i could easily have got lost but i marked the tunnels and on occasions used these us trick
+of a ball of twine to help me navigate back i moved quietly and kept an eye out for sensors i had no
+idea whether the shadow archive was still operational or not but if it was then security would be
+tight and i couldnt be sure if they were using infrared or seismometers for intrusion detection so i
+layered up with insulation and moved slowly it was horrible i was hot damp and the air smelled of
+sewage and mould i was just about to give up when i found a steel door marked with the initial svr i
+victoria regina imper atrix it was incongruous in that dark and dank tunnel but more significantly
+it carried the trademark tan non the lock john tann was one of the top safe makers in victorian
+london and i had cracked one or two of his safes in my other life as a cat burglar this was big and
+heavy and very rusty that told me two things no one had used it in a very longtime and no one had
+upgraded it in just as long if the room behind it was still in use then someone would have been
+maintaining the lock so all my precautions were probably unnecessary but no one had paid for at ann
+safe without something important to hide so i decided to tackle the lock and after another eighteen
+hours of grim work i was in i had found the shadow archive
\ No newline at end of file
diff --git a/2018/5b.ciphertext b/2018/5b.ciphertext
new file mode 100644 (file)
index 0000000..d3ffb27
--- /dev/null
@@ -0,0 +1 @@
+JKYRMGHJ WDMDI YNZ GLZ HE KJLX KD RCYHTR YR WZGKYZI ZK NZA JNZYV HYZPYR SD CYR HIDMGHJ WDMDI HAK ZKYD PGDLFYH SZ YZDJJDXXZI JDA CHCLWIYZI PWKYHIHG JRA HA GDRSPRWB YZGRE XZGS HIDMCR GZS VJR ZK YRWB D JDAK YZ CYR YZDJLSYZI NZJ ZK HE KJLX PTHKRGKJ GLZ JPRNWR JR HXZIKLZ HAK HIYHLWSYD ZK YRWB R CHHY D CYR JDJDGI HAK ZK HJYZBJHG HAK HYDXGHKHC ZK YZZJ KCRKJAIDHG YD TYDKHHX HE WWDN JPZMYH JGZGHBXH HAKPWWLSHGRI CRHGK KJLX HN CYR HBZGLH YGHAKGZY YD HIYHLWSYD JKD SZ AKCRHGE HAK YHMDT HGDBXH HAK ZK KRHGAK XGHK GHTYZW R KYHJHGB PRX SWHJKD HLTRHW HAK CYRA GHAKZ HAK YZYZDJDM PGRYZDJYRBOH JRDJJLG YD YDHG ZK XDA YZ PWHG YRI HN VYDAK D ZJ HTRKYRMCR JDA ZK KZY JD RDJJLG CHWCDGEYL YR KRAK CHIYDMYZI HE ZK CHHY KZY WWDN HA CYR GRN GHAKGLS CDZMR ZK CYR YZDTHG HAK YD GHNZB SZ HIYRWRE R YDRKYDRX ZK YHHV PWGRWLIDKGRB JD VIGRXJDEHJLRI GLZ ZK JGZGHBXH HHGAK HAK SZ HLTRHW HAK HTRTYH ZK HWEDJJZB HE PRX KD JKATDWKZZS HAK SZ HGRWT HAK XZGS PRNR PRWB HAK KIHGDC ZK CYR JGZKIR HAK HIYHLWSYD ZK PGK ZK YZDKHGIJDC AKDN CHHIZGB ZK JL NZWWR PRX JDAK KYHCLGB KHP CYR CHTRTYH PWWRGZX HXDK HXRJ HAK KR HGDBXH HAK SZ JHIRS ZNK HAK CWGZN HAK ZK JHKRGKJYZXHC JJHGB HAK CYR KYHXRDWGRB YD CHKILCYZI HKLBJDC GDHAK PKDYLKGZBBZ YR JKYHJHGB DWHRGJDC CYR HYZKJCRWT YHHNKHE KYHXHHGTRJDC IDWELB HAK KRAK VYDAK D YZDKIHWSHG YZ KLE JXDR GLZ KLZER YZDJLSYZI ZK CRHW CWLZI JDAK KRAK HLGK JD KD CYR JIDKIRK GZ PTHKRGKJ PIDWZB YZ HHGTR ZK HWERYL HGR JGHCRHW WRIDKDWZB GLZ KRAK HKRYLKGZSYL GRHBBR PRX KD CRZGER CYR HXZA KR JLZWWRI CYR VRHN TYDGRHBBR VJDG HA YHAK YZDKIRYD JWHJYLZI HA SD HIYHGHSGHKYD YRDJJLG YXHCYZI ZK KWLIDSSDC HE WWDN KD YHAK YZDKIR JKGZBBLJ HA SD VGZS JYZKGZX AKDN CHIRS JD HA GHKJDYDX HXDGB HAK GZS KWLIDSSDC JTYDAK HVRX CYR YZDKYHMGHKYD GZS KGZBBLJ ZK CRHW CWLZI AIDAN YZDKIR GZS HKDKHBBR IDWELB R CHGGDKJ JRA KJRH HAK SZ YZDKJHLF HAK CYR JGZGGZA YRDGRTWLE KHWABXRB JHYZKJCRWT HXZA KRKRHGAK GHCYL HE WWDN RDCYD ZK JHKLZG TYDCRGK GLZ YHAK HWBZYDKYRKJYZI HVRK CYR KIR PHAK SD CYR JYRXZKKZ HAK HTRTYH ZK JVHHJ KD HJLIOH HAK JR JDAK HVRK WWDN RDJJLG KRAK VJDG R JD HGHAK HBZGLH SZ JHDGHWWHIYRAI HAK YD HTRGKLZ CHJLRI JRA JVGLK HAK PE YZDJJHGBBLJ WRKLGE JKD CYR RDGRTWLE YD TYDJDGBL WDGBR HAK
diff --git a/2018/5b.plaintext b/2018/5b.plaintext
new file mode 100644 (file)
index 0000000..8838f59
--- /dev/null
@@ -0,0 +1,23 @@
+the april uprising in bulgaria and its brutal suppression by the turks has caused outrage in the
+chancelleries of europe there is a risk that russia will take this as the excuse it seeks to engage
+the ottomans and if they act and take constantinople then our trading routes to india will be under
+threatat home gladstones pamphlet bulgarian horrors and the question of the east has stirred a
+public appetite for action which could lead to support for intervention and make things difficult
+for the prime minister he is faced with mortons fork if he supports action then it will be difficult
+to condemn russian interference if he counsels inaction then he risk appearing weak and callous at
+home and abroad it may appear unfortunate that our political leaders are unable to agree on policy
+strategy or tactics and it is true that this could lead to confusion about our aims but on
+reflection i think that the public disagreement between gladstone and disraeli presents an
+opportunity their dispute conducted in parliament and the press demonstrates to the world the two
+faces of the empire at the same time morally engaged and yet prudent this may allow us to proceed
+with discretion to try to influence the actors and to direct the play away from the glare of the
+footlights it may be possible to engage the league of the three emperors to our causebismarck is
+particularly keen to maintain a balance of power in the region and to avoid further war and he will
+not need to be convinced that an unbridled russia is not to his advantage so i think we can rely on
+him to rein in russias expansionary visionon the other hand the league itself may present a longer
+term threat to the empire given the breadth of its influence in northern europe and we must tread
+carefullythe emperors envoys will be meeting in reichstadt soon to determine the response to the
+crisis and i need a plan to influence the outcome as always our strategy must be to sow confusion
+and on this i plan to ask for advice from baron playfair he has recently concluded his commission of
+enquiry into the civil service and if anyone knows how to control an agenda it must be our own civil
+servants
\ No newline at end of file
diff --git a/2018/6a.ciphertext b/2018/6a.ciphertext
new file mode 100644 (file)
index 0000000..8b6eaaf
--- /dev/null
@@ -0,0 +1 @@
+WJONH TNGYN CTTKH JQWCJ VIHVN TDONG UVWMI AKJNJ ZINHJ WVNTL DKCTW JJVIH VIZMI HBNGU VITDL LWCJD JVISZ DDBNC TBDHJ DLJVI BOIGI IBEJQ JVDKS VJVIG IONHJ VIDUU NHWDC NZADP DLENE IGHBN GYITH NOVWU VVNTU ZINGZ QAIIC LDGSD JJICW CJVIB DMIJV IQODK ZTAIW CJIGI HJWCS JDGIN TZNJI GAKJC DJVWC SWCJV IBZDD YITWB EDGJN CJICD KSVJD VNMII PUWJI TBQUD UDCHE WGNJD GOVDI MIGJV NJBWS VJAIW JODKZ TVNMI AIICI NHQJD SIJTW HUDKG NSITA KJWCI ITITJ DGIUD MIGJV IZWTN GHDWU NGGWI TDCHI NGUVW CSLDG JVIUV WBCIQ WIMIC JKNZZ QLDKC TWJNJ JVIAN UYDLJ VIHJN UYHAK JJVIG IONHC DHWSC DLJVI ZWTNG DGDLN CQTWH JKGAN CUIJD HKSSI HJWJV NTLNZ ZICJV NJLNG HDWSK IHHIT WJBWS VJVNM ISDJU NKSVJ DCNZI TSIVW SVIGK ELDGJ KCNJI ZQJVI UVWBC IQONH LNWGZ QOWTI AKJCD JHDOW TIJVN JWUDK ZTCJA GWTSI WJNCT NZZJV DHIVD KGHDC JVIUZ WBAWC SONZZ ENWTD LLNHW UZWBA ITKEZ DDYWC SLDGJ VIZDH JBNUV WCINH WHKHE IUJIT WJVNT UNKSV JDCDC IDLJV IZITS IHTIH WSCIT JDUNJ UVGNW CHDWB NTIGI NTQJD ZDOIG WJANU YTDOC AKJNH WBDMI TZDDH IAGWU YHJDH JINTQ BQHIZ LENGJ DLJVI WCCIG ONZZU DZZNE HITNC TJDBQ NBNRI BICJW LDKCT BQHIZ LHJNG WCSWC JDNUD CJGDZ GDDBW JONHM IGQXK ZIHMI GCINC TODKZ TCJVN MIZDD YITDK JDLEZ NUIDC JVIAG WTSID LJVIC NKJWZ KHWJB KHJVN MIAII CUKJJ WCSIT SIJIU VCDZD SQDCU INZZA GNHHN CTEDZ WHVIT WCHJG KBICJ HJVIG IONHN BNEDC JVION ZZUDM IGITW CHBNZ ZAKZA HJVNJ WNHHK BITOD KZTVN MIZWJ KEJDH WSCWL QNUJW MWJQN CTNAN CYDLL WCICW CIJII CJVUI CJKGQ JIZIS GNEVB NUVWC IHWCE DZWHV ITONZ CKJKC ZIHHW ONHBW HJNYI CWVNT LDKCT TDKSZ NHAZN UYHUD BBNCT UICJG IKCTI GNZNG SIUWG UKZNG DNYJN AZIWC JVIUI CJGID LJVIG DDBJV IGION HNLWZ WCSHQ HJIBO WJVTG NOIGH UDCJN WCWCS BNEHD LIMIG QCNJW DCNCT JVIJN AZIUD KZTAI JKGCI TZWYI NGIHJ NKGNC JZNRQ HKHNC JVION ZZHOI GIZWC ITOWJ VAGNH HADKC TZITS IGHNC TLDZT IGHBN GYITO WJVOV NJZDD YITZW YIBWH HWDCU DTICN BIHWC NBDCS HJJVI BONHJ VIBDH JNBNR WCSLW CTAZN UYHUD TIADD YWJUD CJNWC ITNCK BAIGD LYIQH NCTAI HJDLN ZZNZW HJDLU WEVIG HNCTO VICNC TVDOJ VIQHV DKZTA IKHIT WJODK ZTAIO DGJVN LDGJK CIDCJ VIAWA ZWDEV WZIAZ NUYBN GYIJA KJWTW TCJLI IZZWY IHIZZ WCSWJ VNGGQ BWSVJ AIWCJ IGIHJ ITWLD CZQLD GVWHJ DGWUN ZGINH DCHAK JWLCD JJVIC JVWHO DKZTL WCTNV DBIWC BQDOC EGWMN JIUDZ ZIUJW DCWJD DYNHI NJAQJ VIJIZ ISGNE VNCTE KJBQL IIJKE DEICW CSJVI UDTIA DDYNJ GNCTD BJDGI NTNHO WJVJV IJVGI IIBEI GDGHD EIGNJ WDCWJ BNQAI CIUIH HNGQJ DICVN CUIDE IGNJW DCNZH IUKGW JQTKG WCSJV IDEIG NJWDC WJHIZ LWCJV NJUNH IOIBD MITLG DBEKG IZQZI JJIGH KAHJW JKJWD CUGQE JDSGN BHJDJ GNCHE DHWJW DCUWE VIGHN CTNJJ VIKGS WCSDL ANGDC EZNQL NWGDJ VIGBD GIUDB EZWUN JITUW EVIGH ZWYIJ VIMWS ICIGI NCTEZ NQLNW GUWEV IGHNC TMNGW NCJHK EDCJV IBWON HUDBE ZIJIZ QWBBI GHITW COVNJ WONHG INTWC SNCTJ VICWJ VWJBI
diff --git a/2018/6a.plaintext b/2018/6a.plaintext
new file mode 100644 (file)
index 0000000..5e0e7dd
--- /dev/null
@@ -0,0 +1,28 @@
+it was dark and dusty in the shadow archive but atleast i had found it the shelves marched off into
+the gloom and most of them were empty though there was the occasional box of papers marked sa which
+had clearly been forgotten in the move they would be interesting to read later but nothing in them
+looked important enough to have excited my co conspirator whoever that might be it would have been
+easy to get discouraged but i needed to recover the lidar so i carried on searching for the chimney
+i eventually found it at the back of the stacks but there was no sign of the lidar or of any
+disturbance to suggest it had fallen that far so i guessed it might have got caught on a ledge
+higher up fortunately the chimney was fairly wide but not so wide that i couldnt bridge it and all
+those hours on the climbing wall paid off as i climbed up looking for the lost machine as i
+suspected it had caught on one of the ledges designed to catch rain so i made ready to lower it back
+down but as i moved loose bricks to steady myself part of the inner wall collapsed and to my
+amazement i found myself staring into a control room it was very jules verne and wouldnt have looked
+out of place on the bridge of the nautilus it must have been cutting edge technology once all brass
+and polished instruments there was a map on the wall covered in small bulbs that i assumed would
+have lit up to signify activity and a bank of fine nineteenth century telegraph machines in polished
+walnut unless i was mistaken i had found douglas blacks command centre under a large circular oak
+table in the centre of the room there was a filing system with drawers containing maps of every
+nation and the table could be turned like a restaurant lazy susan the walls were lined with
+brassbound ledgers and folders marked with what looked like mission code names in amongst them was
+the most amazing find blacks codebook it contained a number of keys and best of all a list of
+ciphers and when and how they should be used it would be worth a fortune on the bibliophile black
+market but i didnt feel like selling it harry might be interested if only for historical reasons but
+if not then this would find a home in my own private collection i took a seat by the telegraph and
+put my feet up opening the codebook at random to read as with the three emperors operation it maybe
+necessary to enhance operational security during the operation itself in that case we moved from
+purely letter substitution cryptograms to transposition ciphers and at the urging of baron playfair
+other more complicated ciphers like the vi genere and playfair ciphers and variants upon them i was
+completely immersed in what i was reading and then it hit me
\ No newline at end of file
diff --git a/2018/6b.ciphertext b/2018/6b.ciphertext
new file mode 100644 (file)
index 0000000..9386a02
--- /dev/null
@@ -0,0 +1 @@
+NILIF RTITA GNEHT EDBIL REITA NOFOS UONER MESEI SIRPA NIPIC LAAOG BLFTU LOWOL NIYMG IDUCS SSNOI WSHTI LPFYA IAHIR VAOCE EMSOT EEAHT TTCEH ALISS ACTSL ARGET OYRTF IYTGN TONRU SAINE ROMEM EBFOR HTEDE ELTAG OIISN BSHTO IRYKS NANUD ENSEC ASAYR YNPPA ORHCA OTCUS AHNIN IDDIV AUIRL KSISS NGLLA NIUOG IRETN TNNOI ASUDN DNMRE NIOSE RUIBA ILTYT AOPAD OTPRU ALSSN CECER IYVES REHTY NISAG LPFYA IAOPR NIOST TUOHT ESDNI VIUDI LAFOS ETAHN EVTIL LTNIE LFNEU ECYNA AWHTY YEERA HTERE OTERP ESATN OPTNI FOEIV AWTDN EHSEB OTHTF MELTA AETTS LOTSI NETUB HTHYE VAILE TTAEL TUROH TIHTY JEINU ROFFO CILAI OSHTN OEEHT HRDNA AHAEV MLTSO OTLAT OCRTN LOEFO EVSTN HTSYE TEEHT GADNE IAIDN CSSSU OIIWN HTENO NAHTO REDNA HTRIE ESOIN SRDNA OMIER PMTRO NAYLT HTTYE KAHTE REOCE DRTFO EHEEM ITAGN TFTRE EHLED GEETA HSEVA ERRUT ENOTD HTRIE OHSEM TITSI AHERT OCTDR AHEBT OCSEM HTERE LAYTI EWNOD TOEEN TDEBO HTERE ROEVE TNNKO WOAHW WTSSA IAEWD ENODE LNOTY NKWWO AHAHT BSNEE ERROC EDSAD HTRTE TUNAH WDREH PESSO BITEL SOPAH TETAH RTHTU NIRUO EBITS TNERE TSHTS SIEBI ILEVE OTAEB ENITN ERNYL WERTS TAYGE NIEHT OWDLR FOPID OLCAM AYIDN MAELP SATDE BOBAE ELDOT VEOLE IPIWT HTEHT EHOPL SFHCU DATSI NIIUG HSFDE IRDNE LPFYA IASIR MAONA CFNNU NINAG IDJNE YOROW IKWGN TIIHH NMHWO REAHE TSSIH UCINN GNEEB MNERO FECEF ITTEV AHNIN IHTSS ARGET FYTRO EHNAM GAEME TNTFO EHIER HCATS TDEEM ITAGN ELNAX EDRFR NAOJZ ESOGF CRKAH VODNA NAARD SSEMY TTGAO ERETE MRNOS URISS SAVNI LOMEV NENIT HTABE KLSNA NAHTD REAWE ASAER RLKSI HTTTA EHOWY LUNUD TINAE FDHGI TTOCO TNLOR UORTR DAORE TUWSE TIUSH HCGIH LHEVE ILOVN VLEME TNTNI EHSID UCISS NOTIS AWLCS AEHTR TAWEW UOHDL VAILE TTTEL NOOHO EPIFO FNEUL CNGNI HTRPE NIPIC LANAS SDEWO EDDIC DEFOT LOWOL HTLPE YAIAF SRART ETAYG PPIYL GNRAC FEPLU ERUSS ERTOT EHNUJ OIEMR BMSRE FOEHT ERNIT EUUOS ARNEG STDNA FOCIF REEPS SRDAU DEEHT TMERO OPOTR TNPEH OREEC IDSGN RPIVO IDUGN WSHTI HTNIE ETILL EGECN EWEEN EDOTD RPAPE ERROF HTOFE TROCH IMWGN RATEB EWRNE SUAIS NAHTD OEOTT AMMEN IPBER TUFFO RAERG TASRE GIFIN CICNA TEYEH EWAER LBOTE NERUS MEIXA UMOCM FNISU NOOMA GNRUO NEIME SETYB EHSOM MTVRA LEUOL SSART ATMEG HWHCI WILLI ERREF OTTSA EHALP FYRIA AGIBM TTOEH FFICI LAEWS ERLBA TEEPO SRDAU TEIEH LRDAE REHTS TAWTI UOBDL BETTE RETON OTKAT OEIFF ICMLA NIETU OSHTF METEE NIHWG LIEWE ERIEC EVFAD LUNAL ADUCC ARAET CCNUO OTLAF TLDEH SISUC ISSNO HTURE SSNAI NAUAD TSHOR NURAG AIFON IFAIC SLREW LETFE NOWYL TINIH OFAMR PLSRE NONLA TOOSE TFDEH SISUC ISSNO NAOND GAEER RDOCE DRTFO EHEEM ITOGN IRAST RGDEE UOOCT EMEWS UFYLL NINET TDXEO LPTIO HTUSI CNTRE IAYTN TAEHT OFHTR OCNIM CGFNO RECNE IEOCN SNNAT ITPON EL
diff --git a/2018/6b.plaintext b/2018/6b.plaintext
new file mode 100644 (file)
index 0000000..6e48a75
--- /dev/null
@@ -0,0 +1,27 @@
+infiltrating the deliberations of our enemies is a principal goal but following my discussions with
+playfair i have come to see that the classical strategy of trying to turn a senior member of the
+delegations is both risky and unnecessary any approach to such an individual risks signalling our
+intentions and undermines our ability to adapt our plans secrecy is everything as playfair points
+out those individuals often have little influence anyway they are there to present a point of view
+and the best of them atleast to listen but they have little authority the junior officials on the
+other hand have almost total control of events they set the agenda in discussion with one another
+and their seniors and more importantly they take the record of the meeting after the delegates have
+returned to their homes it is that record that becomes the reality we do not need to be there or
+even to know what was said we need only to know what has been recorded as the truth and where
+possible to shape that truth in our best interests this i believe to bean entirely new strategy in
+the world of diplomacy and i am pleased to be able to develop it with the help of such a
+distinguished friend playfair is a man of cunning and i enjoy working with him nowhere has this
+cunning been more effective than in his strategy for the management of the reich stadt meeting
+alexander franz josef g or chak ov and andrassy met to agree terms on russias involvement in the
+balkans and there was a real risk that they would unite and fight to control our trade routes with
+such high level involvement in the discussions it was clear that we would have little to no hope of
+influencing the principals and so we decided to follow the playfair strategy applying careful
+pressure to the junior members of there tinues our agents and officers persuaded them to report on
+the proceedings providing us with the intelligence we needed to prepare for the forthcoming war
+between russia and the ottoman empire but of far greater significance they were able to ensure
+maximum confusion among our enemies by the most marvellous stratagem which i will refer to as the
+playfair gambit the officials were able to persuade their leaders that it would be better not to
+take official minutes of the meeting while we received a full and accurate account of all the
+discussions the russian and austro hungarian officials were left only with informal personal notes
+of the discussions and no agreed record of the meeting or its agreed outcomes we fully intend to
+exploit this uncertainty at the forthcoming conference in constantinople    
\ No newline at end of file
diff --git a/2018/7a.ciphertext b/2018/7a.ciphertext
new file mode 100644 (file)
index 0000000..c6045b7
--- /dev/null
@@ -0,0 +1 @@
+EODNJ XPMTD JBHMT BTDGT UJYEU MDIZJ IKHEA KJAPJ TEJUY EUNDY EDHBK ZGJTE PTDGX BZSSB ZEURP BKMUX XEONK IEJTE CKZUJ MDIDC HBREI IUBZD XTUJV KIJJT EHUST JDYBK ZJBRR BHNEJ BWZBN WYEBK JCHBA DAXPZ BCEHY DZEZJ GDYDS EJTEH BBYTD GAEEZ EOCEH JXPGU IDIIE YAXEG JTEIT EXLEI MEHEE YCJUE GBRAX DNWIY UIIUB ZRUXE IDZGY KNTBR JTEIJ EDYCK ZWJEN TZBXB SPTDG AEEZJ DWEZD CDHJC HEIKY DAXPJ BYDWE IKHEU JGUGZ JNBZJ DUZDZ PRKHJ TEHIE NHEJI JTEAU SAEDK JURKX HBKZG JDAXE TDGAE EZNXE DHEGD ZGUXE DZJBZ UJJBI JEDGP YPIEX RDIYP TEDGI MDYUS KEIIE GJTDJ MTBEL EHTDG RBXXB MEGYE UZJBJ TEJKZ ZEXID ZGBZU ZJBJT ETEDG FKDHJ EHIYK IJTDL EWZBM ZMTDJ UMDIX BBWUZ SRBHU JMDIJ BBYKN TBRDN BUZNU GEZNE JTDJJ TEPTD GRBKZ GYETE HECHB ADAXP JTEPM EHENB ZZENJ EGMUJ TJTEE YDUXI JTDJR UHIJS BJYEU ZJEHE IJEGU ZAXDN WAKJU ZDNBZ RKIEG IJDJE DRJEH YPAXD NWBKJ UMDIC KQQXE GMTPT DGJTE PUZLB XLEGY ECEHT DCIJT EPVKI JGUGZ JWZBM TBMJB RUZGJ TEITD GBMDH NTULE DZGTB CEGUM BKXGA EDAXE JBTEX CCEHT DCIJT EPMDZ JEGJB UYCXU NDJEY EUZJT EJTER JBRJT EITDG BMDHN TULEC DCEHI UZJTD JNDIE JTEPI TBKXG TDLET UJYET DHGEH UMDIZ JSBUZ SJBTD ZSDHB KZGXB ZSEZB KSTJB SEJND KSTJI BYEJT UZSMD IZDSS UZSDJ YEZBZ EBRJT ECDCE HIUTD GIEEZ XBBWE GUZJE HEIJU ZSEZB KSTJB VKIJU RPDXX JTUIE RRBHJ UJKHZ EGYPT EDGND KJUBK IXPJH PUZSJ BUSZB HEJTE JTHBA AUZSA ETUZG YPEDH DZGXB BWEGD HBKZG JTEHB BYBZE YBHEJ UYEJB IEEMT DJMEM EHEYU IIUZS DIUGU GIBYP RBBJN DKSTJ BZIBY EJTUZ SDZGU AEZJG BMZJB CUNWU JKCMT EZJTE PTUJY EUTDG AEEZI UJJUZ SHEDG UZSAX DNWIN BGEAB BWUJM DIRKX XBRYD HLEXX BKIUR GDJEG UGEDI BZNHP CJBSH DCTPD ZGUZR BHYDJ UBZIE NKHUJ PDZGU TDGVK IJAEE ZHEDG UZSJT EIENJ UBZBZ JHDZI CBIUJ UBZNU CTEHI UJIEE YEGTE MDICD HJUNK XDHXP WEEZB ZNBXK YZDHJ HDZIC BIUJU BZIDZ GMDID HSKUZ SJTDJ UJMBK XGAEA EIJJB HEDGB RRJTE NUCTE HJEOJ NBXKY ZAPNB XKYZJ BNBZR KIEEZ EYPNH PCJDZ DXPIJ IUMDI YKIUZ SBZVK IJTBM IENKH EJTDJ MBKXG AEMTE ZJTEM BHXGM EZJGD HWXKN WUXPD IUTDG RDXXE ZUTDG GHBCC EGJTE ABBWD ZGUJT DGIXU CCEGK ZGEHJ TEJDA XEIBY ETBMJ TEPTD GYUII EGUJG KHUZS JTEIE DHNTD ZGJTE HEUJM DITUG GEZUZ JTEIT DGBMI UJBBW DGEEC AHEDJ TJBIX BMJTE ICUZZ UZSAE TUZGY PEPEI DZGCU NWEGJ TEABB WKCAK JDIUC KXXEG YPIEX RKCHU STJDS DUZJT EJDAX EJBCI TURJE GIXUS TJXPJ BBZEI UGEUI JHKSS XEGJB HESDU ZYPAD XDZNE DZGJT EJDAX EYBLE GDSDU ZDZGJ TUIJU YEUTE DHGDG UIJUZ NJNXU NWDIU ITURJ EGYPM EUSTJ JTEJD AXEHB JDJEG ADNWD ZGJTE HEUJM DIBZN EYBHE DIBRJ YEJDX XUNNX UZWDI DHDJN TEJJB BJTEZ SDSEG UIJBB GKCSH DAAEG DJJTE JDAXE DZGCK XXEGI UGEMD PIUJJ KHZEG DSDUZ NXUNW UZSIE LEHDX JUYEI DIUJG UGIBU JMDID ZBUIE UWZEM LEHPM EXXJT EJKYA XEHIB ZDIDR EYDGE JTEID YEIBK ZGJTB KSTYK NTYKN TFKUE JEH
\ No newline at end of file
diff --git a/2018/7a.plaintext b/2018/7a.plaintext
new file mode 100644 (file)
index 0000000..d663066
--- /dev/null
@@ -0,0 +1,28 @@
+exactly what or who had hit me i wasnt sure but by the time i came around they had long gone if you
+will excuse the p unit was a professional hit just the right amount of force to knock me out
+probably no permanent damage the room had been expertly disassembled the shelves were emptied of
+blacks mission files and much of the steampunk technology had been taken apart presumably to make
+sure it didnt contain any further secrets the big beautiful roundtable had been cleared and ile
+anton it to steady myself as my head swami guessed that whoever had followed me into the tunnels and
+on into the headquarters must have known what i was looking for it was too much of a coincidence
+that they had found me here probably they were connected with the emails that first got me
+interested in black but in a confused state after my blackout i was puzzled why had they involved me
+perhaps they just didnt know how to find the shadow archive and hoped i would be able to help
+perhaps they wanted to implicate me in the theft of the shadow archive papers in that case they
+should have hit me harder i wasnt going to hang around long enough to get caught something was
+nagging at men one of the papers i had seen looked interesting enough to justify all this effort i
+turned my head cautiously trying to ignore the throbbing behind m year and looked around the room
+one more time to see what we were missing as i did so my foot caught on something and i bent down
+topic kit up when they hit me i had been sitting reading blacks codebook it was full of marvellous
+if dated ideas on cryptography and information security and i had just been reading the section on
+transposition ciphers it seemed he was particularly keen on columnar transpositions and was arguing
+that it would be best to read off the ciphertext column by column to confuse enemy crypt analysts i
+was musing on just how secure that would be when the world went dark luckily as i had fallen i had
+dropped the book and it had slipped under the table somehow they had missed it during the search and
+there it was hidden in the shadows i took a deep breath to slow the spinning behind my eyes and
+picked the book up but as i pulled myself upright again the tabletop shifted slightly to one side i
+struggled to regain my balance and the table moved again and this time i heard a distinct click as i
+shifted my weight the table rotated back and there it was once more a soft metallic c link as a
+ratchet tooth engaged i stood up grabbed at the table and pulled sideways it turned again clicking
+several times as it did so it was a noise i knew very well the tumblers on a safe made the same
+sound though much much quieter
\ No newline at end of file
diff --git a/2018/7b.ciphertext b/2018/7b.ciphertext
new file mode 100644 (file)
index 0000000..008bdb4
--- /dev/null
@@ -0,0 +1 @@
+HCOOT HEAOT DHEYM AAUHA MARRA RWBEH WNDNE ESEER ETNTI RWHAT NRTRY FMRSO VEHSB RNAUT SELTE GOUEG SDENH HEYDE SEERI OEUAI SHVLS RDAEO MACDN IFDNE IAEAS EANFO AHEEA ELNFM SREHI KHABT ICLIT CTFPV ETEII AHSIS PODIS GLLSI TOIIA DHLVA OTTGE OIIHT OGEES NGURF ISRRT TUUNB ANECS DAETS SGICE LTERV MHCIE ITCAO HIOTC ESTMO TWLPT AWRAN EINWC ELUON INISS SNHFH LSTDN CSTAJ AODHE AAOTE FEADT TSEWS PESAA HHMDO OEOET EETSF HORAI OLNYO EITUI EESSA UACET NAEER EVECT IEYNO HEOEH ECHEI SEEEI NAHAU EOUAF EORSO NNNEC UMFRS IRNSI UEOIE RTUCI REIAZ IOINP FRTTE FEPHI OENCS TLTET TCHWE RCLIF DTTTT ATLUB WTLLH ESRUE MNWAN ISOFM RSOFC CIARL SSTSR DCIIR NTWEE ONETP FIEEE ISNRE GNELI IECNN ENGUE RGNIN CTNEN EDEVL CEGTS CIIAN TAIOW OTMFO EHNTA SOEOR ITURA ILTDI HURMR ACUAE ALLSE GRSGU ENAEE ITTAO TTUMT OLLRA EGDTI TSRET RASCL NOEEC DIFDC MWCEA GPAAS TSTGO ATAHA FDRTE EYEBH DMWID NAAGU STRRI EAABO NEAGO OTEIE IEOSA NANRA ROLII NRETT ELEHE TNADI CANTO DOIUO NMGIO SYEIS ANIRF MSMEH CEOSH CRHRH AERRG GWTEA TTLEO NETDE NSEFH SHMRH LIHOE TESIN DEUHG TNLHT SFOGT SRNRC TWTTV RMHSO NTEOG DUARA AOORI IPUNN NHESD ARCHL SHPIE TANTR INLST LHSIV ISORO STOYM OASAT LEINT EFCOD ITAIA ATSST NANIU NNSAI FOSMR SPRDS ECNOO OLODO TUEET TENIY TIRSV RONTL ETTMP ANTHA IODCD EUDHE AIAED SWIVE TEFTE LEFTH GGTSE TTDDT HRNAY COSDP ETORC EOFOO EEOSA OEITU TRTRH SMWED CSNTN NIRNC HAISE SIRNH ITAOH GEEFA IREYI TOVOA EEOER EFASS ISTNA BFTBN POROI EMARI NOREI TRTSN LAWII IEOEN MMUER EHHCO CSOLF MVVTI OEHEA HNLWU EOORU LRHFN OLIXA AOIHE WABAH ANUNG RLONI VCTRA IIRBC RACAT MEPTD PUSML NNPTF PGONU RCGTI UAROA SAORD RCMMS IEHNE OOSNI LERHF NEROI EHFIO IDPIF RHTEN STEIT GETHI OLGAS GSERI SGHEO AGDIE LGNTR EGTNE ERROT NAUMW TPYWG TRDKT EPSDD HDEWG MEONP LTAHA INDID ETTHU EHESN GAABN GWFTA ORTCA DSRLS AEOFN NEDTT KERSR OTUTT HOENE ODMME ILHTE DANTI THOFE TEETL NTLHC MSDIN VRNNR ALTHI NEEYA OIENN ERSNU NTUCI UVEER BLOEF MIERE ODEAI TSUEG AUTIE SMSEI IRSOB IAEGF TNGEH EOOGR AHUOR PNMAL DSOAV GRIAS ADDTM FKEAE HAARI ITMLS TIERI EOAEH EANWT GLOEA HRROL EATEN TUTOH AONLH SESMH ATTFB NNCET RNOYD VHEEE STITT ROERE POOTN AIETS UEEAT OISSR SNETL SGGTH NDCIV RTRCN PMCSA ENTTR ESVES NRSNO NEELE IDTNN ELOTC NFNTI CKOTP GRBFF DICMT RKEUE OERIW EAIEA NEIOO TEROI RYPNF TETSE EUIOP WODTB HFSAT IOUET TTHCN NNLEI LONDI CTRNT OAYGH ITSSU NTOII ETEHI TEFEN HADEE ERONR AIESL ECURA NPOUU IEEEI KNANI OEEIE OORNS NFOMT IAEAO EUNBI KTENO NRIUD NCIHR RANWA HTTOA LNNTT EOPNN NMNFO TAHAU AWEDN REIRH PRWTN SLFSU NCLWH ANVRE REROH NNIDN EUFNI POESC ELTIS DNASR ESNNT EMEIR VNADO BPWSD OEEIR SOTNR SHSON IXNAE ANSSL OAOHA UPAIR NFOAE HLEAA HEEAT DCYST FHIHP NILRR ITEUE RAORS TTOJD MTTAI SCTEO USCAE TIIOG AEGNI CHAEF MFIAL ORIOR NCSNF OCROS LFROO GDALH ETSMG URENW SSWEI ONRWS ETTMS RRNNI WESTV TFEON TBTUE OOLAN ECREN ESEIM NHSNI LWDTT RGTAR SOLID NHENK FRTTW TLOSN FOPHC HGTAH ECBOA ORMT
\ No newline at end of file
diff --git a/2018/7b.plaintext b/2018/7b.plaintext
new file mode 100644 (file)
index 0000000..741ed7b
--- /dev/null
@@ -0,0 +1,30 @@
+the chaos and confusion that followed the reich stadt meeting was more complete than i had any right
+to hope the playfair gambit was an outstanding success the delegates from russia and austro hungary
+each had a clearview of what had been agreed and these views were entirely divergent even better the
+records of the meeting were entirely independent of one another at the urging of our agents within
+the separate courts the minutes were dictated separately by the two foreign ministers andrassy and g
+or chak ov so as to ensure the deepest possible understanding of the agreed outcomes there was no
+signed formal convention nor even an agreed protocol our subtle campaign of whispers and
+misdirection ensured that neither side entirely trusted the other so these minutes were never shared
+the discussions concerning austrian annexation in bosnia and herzeg oven i a will confuse historians
+and diplomats for generations to come it has already confused the principals in this affair and no
+one in the foreign office can make sense of them at all despite the great care taken by the officers
+of the shadow archive to record them accurately there is talk of the need for further meetings of
+the great powers and this time i will make sure that britain will beat the table to influence the
+deliberations and to protect our interests from the point of view of her majesty and the prime
+minister if not that of all her ministers this is close to the perfect outcome discussion is
+displacing war and low level distrust is inhibiting the sort of organised alliance that might
+diminish our influence over the gateway to the east the forthcoming conference in constantinople
+will for the first time involve our government in the discussions concerning the future governance
+of the region lord salisbury will argue for the creation of autonomous regions under bulgarian rule
+in the hope of reducing tensions and eliminating the excuse that russia needs to engage in war if he
+succeeds then we will have established a comprehensive agreement with russia concerning its
+territorial ambitions in central asia resolving the conflict with our own strategic aims even if
+this proves to be too much for our negotiators we can atleast hope to buy time to make our own
+preparations and to manipulate our allies and enemies i will concentrate on developing further
+confusion spreading misinformation and as much distrust as i can manage if the talks fail we should
+atleast ensure that no grand bargain is struck against our interests and no major alliance is formed
+to diminish us the mediterranean is a choke point for the trade routes from the east we can not and
+will not allow others to strangle the flow of goods and people that enrich us no threat is greater
+to the health of the empire and no action is beyond contemplation in our efforts to remove the
+threat
\ No newline at end of file
diff --git a/2018/8a.ciphertext b/2018/8a.ciphertext
new file mode 100644 (file)
index 0000000..81659f4
--- /dev/null
@@ -0,0 +1 @@
+kdIgb oimce idkot seeii huotn pteho mmswi heeoa taoue taebw niInc fnkll flnho unwtd mamtg maera ieanw ronko tsstn kemta rahdn heIpo nsiac oiaeh lntai lbhsh oesoh lhtka rttts aehhI vldTh tunau ehshe noceI aireh rvsrw thett tuaea eseid eeeem topeh eohfB eoodn pafto enect dvasi bpsti xtrrp hfost wiekh Idnpb chrls fidoa atwit urgsd nedao hhgsh iaoeo ricot sgnrg ktedr hanoh tsmao Tehtf morsi ngkhe phtat bmrtt ooeap ctdJt marcs eedad bnier nrhhm rkshg eodBf emahf oeocr ctdfc tvMsy rlneu ooklu nobks nnhhe snosd naenu ueknh noydd Isiwl hseei uibby hatdo ybaeo pAntT sftek atpwa neuoo plttt abtte etioh mrhuh cfsto aeaip otiVc olsgI asstt atyla oodsu ebple rlecs acles hsham ierth ocoen etatn eluhn ehtnw auaih eerje hsaea kshtw cslrh eohin euteI ldelo trele aiutm mesrr oleet setwi naerw aouhe aiawy dycsu tltgu eecni atdte whiks ldlre uoaeg iivsn noleI atorn uscen heuaa tcplr dwato Imath eengb rafal bhade phdgh tgees eniat chdsa dmept oiiku ceuii ereyd ttsun cetTs oieeg naetn sligi tepod legtI oiors rhaaf hgpuc doite tdplh nlell irhpo Scrie eerTo wahto roesi efedu eoanb ahwae Vnnkt oueaS cober seeht rseha rtsda ntmia ahute ebhmI lbnot eyatt ndnht uHoht leade osytl ylwut uoIoa cwmll eints eIoeu retlu ekycb Iuime fnhmi orehv piafe ostto rnhoi lsnne alacn fndof eIhhi cttrh hhltf teipd rTnes ethtp bwenr rpksr mmein tiioa loamr achti deeuw lanse pohhi lidtk achce ynaoh oswum tlond eelaa dmiLd hhrii rhhue tettv eycet aceeo syIhr tcdan orcuo iwvlt wtror Ibdbt ebgal iulrt bduns nswva talsn gfois dytvd tadlk lniwh etcsi kasle yrtda inmen eeacd nluIa hotga ityet erbyt crebc hsead nuIop nolwy daoek iceuw iauan otdaa efood ddhnh octle itehd rfbls adfeo cemla kMkeh Aaiai tmhet udren tiate tuacy adsso eHlai inald oahhA tluwe errre iysta aihko lhymh lelos strmi rnadt asbde dpwdn ennet ttuol wlhni vtoew tidtn ceoeo cfhno rtorh errdt oepmc ceacl heeil eeagn wydnm heaew dnece hngpe tietw wumnp oanee ihitt gsalt hgrhc evett anaaa rtrnl sdenc uagcc dktdo uloyt aucth otnse eaard tdvdr siafn smuey hceha asnke oeett acitn ktnfd nidto dvdee eaone fifim elahr ohnao iweii aatgd sldeI iweuo sncle etrea eaaea oarrt csdal nweet lehwr xeaue eefno ggatt idctt kinet htuss hnctt netot eoanc wrhts rutee ooanh oeehe dlnny tdwed feapw cpdet hnmab ngtyr atnbc anmpl feiet hhdtn obeio asmmn uotio rapre yider rmtbh anlhf timtl klhHa rnobs motfc eefna actfb feerc ysetr ktiAt bwtsf fawod ewyed nyvmm teela idnhn eunae Utnot vtnic hlwpa laato Ilrot stsdk aurrh ianre oroef sepho loyko ltkei rytoi mtoth hIgei rtboi tttre oehde n
\ No newline at end of file
diff --git a/2018/8a.plaintext b/2018/8a.plaintext
new file mode 100644 (file)
index 0000000..09563f8
--- /dev/null
@@ -0,0 +1,27 @@
+I checked around to see if I was being watched but the room was definitely empty and I couldnt hear
+anything outside so I ducked down to inspect the underside of the table The top was highly polished
+with a graceful slope to the edge thickening as it approached the centre column There was no visible
+mechanism to suggest that it was anything more than it appeared to be a grand work table at the
+centre of a grand control room I pushed poked and listened for another mechanism but there was
+nothing mechanical that I could find The thickening of the top and the bulk of the column did allow
+room for a fairly substantial mechanism though and tucked up in the fold where the top joined the
+column there was a small metal plate bearing a makers mark My heart skipped the door to the Shadow
+Archive carried a similar plate inscribed with the trademark of John Tann the locksmith who
+manufactured the security system on the entrance It looked like he had also made this table He was
+not a furniture maker and there could only be one reason he had made this one It must be part of a
+lock mechanism He was the leading safe maker in Victorian London and if Black had felt the need for
+him to build a safe in the heart of the Shadow Archive it could only be because there were secrets
+that were too dark even for the security of the Archive itself Maybe this is what my attacker was
+really after and if so they had struck way too soon I should thank them really without my aching
+head I would have been unlikely to discover Tan ns mechanism but that thought reminded me I was
+still vulnerable down in the shadows I didnt think there was anyone else around but I couldnt be
+sure and I needed backup Until now there hadnt been enough to get Harry involved in this adventure I
+still wasnt certain that he would be allowed to help out as I wasnt really sure that national
+security was involved but I was absolutely certain he would want to see this I needed to get out
+safely and comeback with a team so we could properly explore the Archive and find out what the Tann
+safe stored Before I left I took one more look around gathering the few papers that were left and
+putting the codebook securely into a pocket of my backpack I still couldnt believe that my attackers
+had left it behind but perhaps they missed it in the gloom in their excitement to gather the
+government papers which they had found If nothing else came out of this I was certain that the
+codebook was worth reading I hadnt had time to inspect it properly but the section on the Vi genere
+cipher looked absolutely fascinating
\ No newline at end of file
diff --git a/2018/8b.ciphertext b/2018/8b.ciphertext
new file mode 100644 (file)
index 0000000..13d8226
--- /dev/null
@@ -0,0 +1 @@
+WSLLC PZHSG CJWOI PGADM NRTWN VUUGE FHRJI EFNTK SLJHG POPAJ LLBAS ATKSY GUSWO JLPNR DHWJO QTAJL NFSZA ZRDSH AJAXU DLAHH AKGKW LHDZP SSOIH OLHHW FKTKS LWVPO SZGUO WGAWT TROCJ LEWVW LIUOU WJPAQ ZENLS FCQFA FRFHW ZSLBP ZLCDZ YMSUV CBAUT HFJSA IRBWD HFIOE JZIWV EFRSD ZEKIU UMLDH NVHKE VVHVE EVNSS NZHPV PWURT RJEWU NDVAO HSVIY ULSVT QDAHH FAAAI VAKKA UQIOM HLWCD SCEDB JGFEG PKLOS DZEKI UUMWF KGOOZ KAOQS XMAIK ORWZO PSOQT PDHDQ DIWVD AZVLS SKAHH HAJYI EZAWC EQHOL OAWVW NLPUS YAWIW OPWKT KWOUY IVWOU HNQCP TLUQR KFLAQ RPZLR HONWV TKSNU VNVWZ WYAWW KFZRX GOAHN DUCJL SVWKF TUVHO LPLOP AATPH RAVPF ZSWJL TRFAL HIQCQ JPNIZ QWUCH WJLOE USCAV NPMWY LNWGP WSLPS PZHTW VAJBS VWWFL MSSNG YMHHS AAHWV ASBSW FESUS DHXMK ASSOL HTWVA KAAUH KXAHH MASYT RREKJ UVGPZ LIUWJ LLNWW KFZIQ HDWLV HBPGM WDFWF KIWWO JBMRI NWKTK OPLOE BDHSU TRFAK ARXQP MYEWV ATHLN OJKPN DBAXM OUHPG JOQHN GSTKS ODHVL QIGCE VTKJH UQWBA LDVHW LLIWW OEFOZ BRALW WVWLA HHGHS CSPOU TLAPC OLBSH TQDHL OMEFI LRQGA UGWVA WEPDB OAVNL GPEVV HAAFA IQFQK ZIDOJ VPHDJ ASKVL GAVAH HUKNL RQAAF ATRWJ NPTHH DWHUV HNAHN VHKBV IQIOA UMDFY ZAOVS AAMWH QWFLF ISYLH DLDHG TAWWY KVLXH EGUTR IJLHN JZALO IVUKJ KIDBG FVTSS NZHPV KAUHN IWJVZ OPSPZ PNJAK JLAWH NSJTL JAXVR WVAEA HDHSA SLZSW CLNWV AAYDH DAFKE QQAGU TVONS SEAOJ VLRLW EXDEI OEDAH HBEXL AUHDS AMRFA VPRHQ PSJTL CJEHY QSAVA OESPS REQWD SCELB IQWOV GAKZI RBYGW IHGKX JEUHW AULHH PWYSW VWLOA YSXWL NFWNU BLDHE FNIQT NSUZM COWMS FCQJA TKOPA AHLBG EPGKH XWZUI TEUPE QHHQL MEONJ HSVWJ YAOFC JULNW FWLLM LBZKV NWVAS KVDBP SNEVC BOVRN WJYDI WVQKP NVHWT PLLHU AUTKS NWNIR BEKJE UHWAU LBGKE LTKWJ YAOES BWHRH RXMAP HFDSW SZSYS UCRBR AUCHH DWHUV HNAHN VHDSA SWOXA SIWMS GBLGP AOVRV SEXPT LGOWJ UUSZT FTKSN MZSLO JKPFZ SYSUN RHPMY NDIOL YIDHK GBRFO QKLIW AEYOT ESJWJ EVGWJ FTRIJ VLRWO GWHCD ALSPG QHKKA IUILL OEOCY SSPRD QDHTL CJKWE UVWHZ RXGOA HWRIH VAHLB GLDIF SXWMO USCWA TLBCA UVRZR WKIIH DWFWH FAFVT DPHWA OVSYM YEDGP SILHG ALALH AAFAB BTKJJ ERTWJ TSDZK FLTKS HWZSR BOGMT KSYJP MHODS CEQCP TLEQT KJNOW HAFIY DBUGM IWGYG TBDHW FASPC ZWYNZ ONXHR HWOYY OZWJY PNGIO LYIDZ EFPTV GYSSE DBZLO EFCOL ZOIQK FMLLQ PSYES FKZPB LHENL IDAYW YTDWJ LOAWH DWZTR FEWZT RZZTF NLUDL PNJOH WVFWV AZVRU WBAJW RIJVZ SXTBW YEGHD WYEKO RWZOI HAFLD WVASW PHHEL LOIGK ELFRF KHLNF CJXSI FHWFK PHFDS WSWVW LPSUS OHVNV WXDLF RFDWY MDXAK AYVGQ HWOUH KXAHH GDSKO ZONUO IYSWF KAOZE LZWRF GKPMX GPFVT OSPZL RGCSF UOUHD WLMSW NW
\ No newline at end of file
diff --git a/2018/8b.plaintext b/2018/8b.plaintext
new file mode 100644 (file)
index 0000000..45f74b0
--- /dev/null
@@ -0,0 +1,25 @@
+elliot has done himself no favours in arguing the pragmatic line at the constantinople conference
+disraeli caught the mood with his pamphlet and the people do not seem to agree that bulgarian lives
+count for less in the calculus of international affairs i think salisbury plans to move him on
+perhaps back to vienna he was successful there it is most unusual to have annoyed both salisbury and
+gladstone but i have some sympathy with his views the terrible events that have precipitated this
+crisis can not be undone and there are other considerations russian aggression must still be impeded
+if we are to retain our influence in the region my agents tell me that the russian emperor met with
+the austrians at budapest at the start of the year to discuss their intentions in the event of war
+and it is rumoured that they plan to restructure the balkans in an effort to control the slavic
+moves for a unified state it is my own view that the slavs maybe a most useful ally in blocking the
+expansionist movement in russia and i have advised the government to invite the austrians to join us
+in march to see if we can effect a diplomatic solution to untangle this gordian knot perhaps we can
+find something more attractive for them that will weaken their dependence on tsar alexander ii if we
+fail then i fear that more direct action may need to be taken i have in my possession copies of
+certain letters that have been circulating in franz josef s court that i think might be sufficiently
+embarrassing to concentrate minds on the advantages of working with us instability in the region is
+certainly something to be feared but perhaps we can convince the austrians that stability would be
+worse if it is secured by the russians if we can not turn austria to our cause it might be necessary
+to undertake a campaign to stir up the local populations perhaps russia would think twice before
+getting involved if they were notable to secure as table settlement by force of arms alone the
+lessons of the crime a have not been forgotten by any of its combatants modern warfare is growing
+industrial in its scale and the costs of conflict are prohibitive i am certain that the stories told
+by nightingale of the horrific wounds suffered there have softened the appetite of some for open
+conflict and perhaps that is responsible for her majestys support of the shadow archive and all its
+works i must not let her down nor the empire
\ No newline at end of file
diff --git a/2018/9a.ciphertext b/2018/9a.ciphertext
new file mode 100644 (file)
index 0000000..7f94794
--- /dev/null
@@ -0,0 +1 @@
+WFREZOBRHCESTIKVBZEOGOAXZGGHTQFADLGEPBHXDIRSMELEQBGODKAIVRBTTMMEEJRSMNXFXRAEUBAIUMSUEEXVHIREZQVSXJQSQMMLDRVTIWNPGZRWAZMLDJBTFWVSOJRCFWKWDLQPDWUEEJLBQTHRJCQIZIFYVCHMTIKVBQNIPPXEJPREPJNXLFNDMNXIOGAGTMPEQRRDUBBRVRNLXMWFDAXIZPXEGOHADBXVVRUEDMPEVQBMQBAMQECRAXKMHRBRUIEMQRUEIIRLHJBOWMWEWGGIFBHSNRUEFEHSISFEUOAXHCAHACKWWMPRMKDMWZHTIQMLDQDUMLKSQMSSBMVMDJSODKXWIPBMTMKIIMEDSCTVGGAGGAMLHPRWMAGSUGFKFPTXPWNTFIVOHPFWACEHUCGUDVBEVIRDTIKVBFBWTMZSWYHTTWKMVYGIAVMSEPVNSBAIPGAARBXVDJYWQAMMOJJEDMGXVSEEFPTXWFRRQEXVHYAYZIMMRLNLEMVYUGGYUUIPLANTUWGWESGHQRNWWJNUSPXHDLQPAQGXHBBUFBAEWURWQZXGXPEEZBECVMZEIPXVHSADQZGIZQPOFTTRGWNRPIGHLRUAPVMXDIRNYCVLWMPOZDBRFCGHQPHQHQRCDMMEUWGHMBPIQCRDQLTTUMCEDAXGXPVTKBXEPRBGGIKHWFRSTIWSZYECTQOIDLBTTMKXHYZORIGEOWFTEPTHFYZPQLHRRLRSULXSIRUEOWFQDLQCQVMVHYADIMKIFMZBUVZXKPBUSPUPDAXSOWWIEMBKMVWXKCSEIXTTHPFTTIMSXPNNFIZSQGFTEPTHOCSTNMAMQBSRAUMMPCGOFQFIRLRORBAIWPBOBMKWZMHLPIKVLTRWUBAEQMGHQZUSAMSDAKNQHLGSDMMVLCIEPNKSPYFIPMKSRKBRMUHVHBVSFIGXSYETANMLHYECTQOIOYOYDQGXKKBSFKHYOBOEPMVVBNGEPYNMFIYYGABRJRUEEBTRGYEDFWHPVZYAOSAEGSFEPIKEQERORKBTKCESUVVPXBVNSANFVRVTGBBSQYADFZTRVNBSUBBSQYADMTFSVRAOZMHJLRJAEPTVGCETTIGEYGTEZMKILRJAEAESZQVNOMMLHNNPQZLLDBGONMAEQBYEPEBXKANRQIGHWFRSOIGRHPGHQGAEGZEOGOAXZGGHFPXQZYFNFZXEOJLDQABKQCQFAZMLLQFODBHJZMEKMKHYSJRORBBQHQGHQGVEOJRDTIKVBMIEDBHWKMJHUULSPCGHUVZEQBUEDMTHLRAOPLXHWFRNOIFIEYPKFWPSUIBNFPXWDDRAEEXARPXEPEXXDJXEPIUSXRJHMBBLDBYEMZGIGABNOMKRLLTTTMLLDBBWMZVLLTRAZLUPDAXSEMVVHRJODSYSURUESWOIULZEZBAEUPLDULGXJGIEYCVLDUNYNCMMKYQARMXPLLTHQPTHKCNRPAHQHMSTTQLWWMEYNMYSUCNNPIYXHPGHQAXGRLQTUUXLHUNSOIEPHBNWMGAIVCRMQLIEURVCGTTVOWGHACZLWDHLUILOHBUIYEAEWUNSNWMLHPVNSPBQESGHQETWHLWOKQGKECVNSKKCSRVCTMLELBFOYMMLLLTANWNXWFRBMTDEQNEONTXQWFRNYCMXHPRDEBXZHRHRZMKWSMRMTQLXRPLLQALSQFVSFWKCUCCEMBLMWQRLRPTWWMAOAVXPLQGEZABGRSYDZBZIWYAYFPBRJKBRQWNXRDUIYMQGHNGSAUXGRKZEZBTFRSGWAZDMQEOAOSPEUBFTTZHYJFGHQXTTHPFSAQMYULRDYGTXWCATUWGFDAXTABAIVYSEFPXQHAUAZQLQZYFBUOZIUYADTMTZLCETTIGAHURRQCLIGRBAZLAEGZREZMQUXGFIFMECPYQEFPXGRKCOZMGXVQYIPIEQRQGNAQLIOCFSXGHZHPBNQIGSWFRRMVWXKCYOGLVPLAXSUPTHKCNRPEAIQKBVUVZXKCGANTXWHCZEPBHFHRUEDMLYORBFMJKSNCACAOMSRRUCMBVLLLTOZBAIEYERQTLXKYGMMLXMWCIEZPTVGCETAWIIQUUAFTBXWJRNAQLIWFRLAKDXXKOLQZLQDBRWMAAIDTVLKLBWJSVSQLTRGURHMLMSUCFODBMSGPVLXQGKDQZAXTTGFCFSTWEIWMCAEATRHLQOEKHTHGATABAILLGEDQHVLRJAEILAHJYWQPTHWYXEZBAIHDSODBLMWRVNSQGXKCZIPLEIRDNPUTXSILBTQJHSNQNNPXTTHPFWMATWPYYLBQEIRDJHMBESRIRDXQDIHVCLAABZHQGHQATJHUNSDQZKHBGONTHALDJEYIWIDKVSFIDI
diff --git a/2018/9a.plaintext b/2018/9a.plaintext
new file mode 100644 (file)
index 0000000..8edaee2
--- /dev/null
@@ -0,0 +1,30 @@
+the engineers harry brought with him wanted to take saws and torches to the table safe but neither
+of us were keen i could see that it would be worth alot to collectors and probably belonged in a
+museum harry said he agreed but i had a feeling he wanted it installed back in headquarters there
+was something proprietor i al in the way he looked at it it took the two of us eighteen hours to
+crack it but with a squadron of special forces from hereford guarding us there was no risk that my
+attackers would return i asked harry how he got authorisation to bring them in after all we still
+werent sure that there were any national security implications but he just laughed and pointed out
+that we were currently somewhere under new scotland yard and it hadnt taken much to convince the
+home secretary that we needed a proper security team to guard the shadow archive another team of
+analysts had camped on one side of the command centre and were combing through blacks codebook and
+the few papers that our antagonists had left behind from time to time one of the troopers would
+arrive with another box of documents retrieved from aside room or a more distant part of the archive
+labyrinth most could be decrypted quickly using the standard tools black had used a range of ciphers
+including substitution and transposition and almost none of it was harder than avi genere it was
+slow since the papers had to be handled with care and the scanner they had brought with them wasnt
+really designed for this sort of work a couple of times they called harry over to show him something
+and he read it nodded then came back to work on the safe as we worked we talked about what i had
+learned concerning the shadow archive and blacks secret work for the government harry didnt give
+much away but i had a feeling he had heard some of this story before and after the second time he
+was called away he seemed particularly thoughtful i asked him what was bothering him but he was
+enjoying being cryptic he said something about the balkan problem then muttered steve turners poem
+history lesson history repeats itself has to no one listens i couldnt get anything more out of him
+except some comment about working backwards through the papers so i turned my attention back to the
+safe the mechanism was bigger and heavier than we were used to and had been exquisitely made the
+components slid almost noiselessly over one another and the loud clicks i had heard when moving the
+table seemed to be the result of a broken cog tooth catching on the barrels that made it even harder
+to open what little noise the lock tumblers made was heavily disguised and we had to resort to
+drilling a small access hole to pass an endoscope into the interior it was as well we had taken the
+effort sitting in the middle of a pile of notebooks and papers was a small pile of what looked like
+explosives the safe was rigged to blow if we made a mistake
\ No newline at end of file
diff --git a/2018/9b.ciphertext b/2018/9b.ciphertext
new file mode 100644 (file)
index 0000000..2ccb370
--- /dev/null
@@ -0,0 +1 @@
+XLLDY DXLLM IQXLF WHLTQ VXEEG CKKIP VZFOT MAYYD RGFYY DLRBQ PVIQH FTUVM PIKOY LBNEY GJECN SRMBA VBXYA NESHJ HBKYS DTMLO ZGZFC SAYBH JYFLB EIYAR XHKXI ETLLY SQYCP VXLXH RWVCI HFSXQ XOHXE IEUSO LRXFK DIQHN JZEFK YGNRY LHZKK JTCIY XGKLV DRYBM JEVCG CDBIB GOFDI NHBVG IRTNJ XEKHN KYIFM IKUGY UUZXS BXWRW KLBXR BXWUY DSXCF UJOLR MUJOX SHLVN EPMHR ORYKL VDMBX GVRXD HFFBX LHWIE SEGCK XIKXW JEVNR WESEE RUDOA RTBKC VSHGL BHPTY YOZYA CUXEQ XCKSR SMLFZ TMZHZ NEPMH ZRGGK YSVPG PSEKQ PXAES VYTTR LGGMU DYPNB XVRXD HYIOL NLIDD EBXCQ XIPYY YDIQK OFMJM LLVGS NKIAK QCANE YQCAN YQYMK BKBEC UIKOV SLMVB TEGCI LRYVY NDEFM YGYLC ANESC RBFZL ERLHZ NIPNN IERCO UYCRY DFRLI FMMJY VATMK XIETS DCIGM LRZHL TMVDE RLLVV PYFMV RXLHM ZCYAH ZPWXS UQVSZ YXPRR IPNMD KMJEC NCVCP IGBSH TGVRX DHFCK WQXLX XSAXB KPSLK YTXSA XFGSG LBLGO LRLCU OZCBB TKIZM BXSQL HCKKG GYCEE WGANI OLRXB NNRYP IYPSL HCKCI SJYYD IJUCK KTKHW ESIPT YJOLR WHRCA CBPCK ZGKSE KQWKY MOVYX LVRXR TBKBI FMUID YZTYU SVYXF TKOAT FPOLR MUYDX MGMZD MEGCU KIJLC DCMRT BKCTY ALVZR MBNRM MDBHL OLRWU VVHJN IYCCR KUGRG GAQWY ECWCI KIJVI ENRYG QFBMC ANWYW LHCKS FKTFR MMRBF FZHLT FRBYR EOTNI GKUMR XGPXV NMTBX ESEKX LJOZJ XMDOL RLYKK XQGUB VEZXB KXSGM OCYWL TECKF YDYVC SFPYJ YLRWH RKMQL OIXMF MCNOM JWFLY LQKYN YTQMC WYWSV ICOLR MUYDI TXCCO FMAQV CSFMH VOARX VKSPN LSCZI CWMZD YZWYZ PMLNH VOFCO UYIPY MCUXE WGUDB IEMUY DCYPY DKWCA NESWC MUKCG GOUCC IFMYK SRSHN JWMYM HVWIT HGTSZ YEMEK TCANJ SWGKW VRXDH NLYCY PUVOW WTGVG ITXCC OFGGY YDRGE LVLXY TXEOK YXBKV SPMHF MRYVY NPMRV CCPRM VLVRX PNZDY VDXMF VSRXL FWKLB BKOQM LYMKL WXBKD EFMXV CMJTY IOZYA FCKHL TNEOR GMHFM IFMMJ YVATN GEVCR UDBEU MUYDX YXLYD KLBLV RXYZY YDICL IKXYE XVVFE FLLVG SNKIA KQCAN WYPJT MVFMJ GCKCS AKYNY PFVOD KXYWY VMGSL NYQMK RWRWS JICUP SQWIY DIKPY EBYMM UYDWG XJFRC KMMFM XYXLX DELXN WYHLT NYQYM UYIKK LBHES AFMLF GWCBL FDGGO FCKXY ANNOM TRGJS XGMOS DLENI ILRYX GPVIP NMKCY KBNRR XBBUJ NRYXG UOXAX LIYGC ALZKJ WTFGY XQBBK NMYLC EOLUG IZDYJ HMVBE PHZVZ SFHNE SKCUH RMMLB FIOFL BMJOV EGITQ RGWHV ZQGXB KDERA ALYFC UNYQM KXWRO TRTBK DGCIM FBTCA NYDMU RFCKR GYQFX RGANZ GWCBG VXIEG CKRKG YSXBI LXYCL EPXXZ CRMVX VNRCI RVOZY ACUXE JEUYO XGAQE SVYEO GYTWE FRCVC OCEER CXVKY RCOUY CHMAN VWCKL MVVIF MYEYR KXFSY VNAMZ UVSMY YDSRG IZDYJ HMEGS PNIKX IQXLG YXQKY NYTEG CUKIJ KYYDS FMCNO XYBNF QILHN ESKCU IKOPZ TYIOA CPXEY GCLXE KWCBG VXIPN IWYWC VCMBI QVCKK QMEJZ NIFMH ZRXGP EIYAR XHKXI ETLLY TMEYM OHMMY CLECK YNOAR LLZPW EGCYD SUMXV FIGAW RIEJX XJSLR MUYDJ JXMPW XPHZD YGGWH ROPZT NZFIL BYYDC YEYUY XBXEI YAQXC CVECA NXXSK THFSW SYHFM KLBQF CJMRA VDEPM MIESL HCKEP MLFRX SGMUE BIRGC EKSRX FSKRC FUVLS RZHZB ECIJR OPGAQ EYMRB MFZLQ BNZBF CANXX MQBFR XMEKU DIPCO CKMID YYUXE YBLKC YYWHR IRYFL VQRGL YZVPY KYYRX GPHFS XATLF PXPHJ GEWEG CUVMS USCDG CYLVZ HLTBI OLBXS RVTQT BRSWQ NLUOV YXZVG XYANC VELXY SCEFK UNRWG DLLDS QLOIO LR
diff --git a/2018/9b.plaintext b/2018/9b.plaintext
new file mode 100644 (file)
index 0000000..a18f15d
--- /dev/null
@@ -0,0 +1,30 @@
+the russo turkish war has been all that we feared russia has played her hand perfectly building
+support for action with her allies in germany and austria and effectively marginalising the british
+position while appearing to be amenable to an international solution our strategy of sowing
+confusion among the allies worked to delay the inevitable and i comfort myself that this delay
+achieved two things first we were able to develop our agent network within the diplomatic services
+of our enemies and second we were able to begin to negotiate with other leading powers to present
+our own solution to the turkish problem nonetheless my methods have not been universally popular in
+whitehall and i have expended considerable energy fighting enemies within now finally with the
+prospect that peace might be bought at the impending congress in berlin i can begin to hope for a
+resolution when i said this to playfair he corrected me and said that i must surely mean brought but
+it is my view that all victories worth winning are bought and often at great cost my hope is that
+our new methods of diplomacy might succeed at a much lower cost in lives all of the major powers
+have begun to see the gathering threat that war may erupt across the continent and all have realised
+that they have something more to lose from further conflict if we can control the agenda at berlin
+then i believe we may see away out of the crisis the pan slavic movement aims to unite the slavic
+states in the same way that germany and italy have been unified but is deeply split between those
+who believe that the locus of its power should lie within russia and those who seek a balkan
+solution the balkan states themselves remain divided with varied cultural and political ambitions of
+their own and no clear idea of which party should lead the unification perhaps that is misleading it
+is not that they lack a clear idea but rather that there are very many rival views and these are
+incompatible the question of how and whether this unification might be achieved is the principle
+concern of the congress all of the major powers william sure have a view but my focus is on the
+smaller states and parties my agents across the balkans have nurtured instability in the hope that
+we can bring pressure to bear through the mon the major powers of course the frenzied atmosphere of
+the diplomatic bazaar in germany will be rich in trading opportunities and i have heard rumours that
+we may gain cyprus cementing our control of the mediterranean trade routes at the same time by
+trading macedonia back to the ottoman state we hope to undermine russian territorial gains and
+perhaps to settle the balkan question permanently if so our agent network in bosnia will give usa
+foothold in that region i will continue to work closely with them in the hope of creating a new and
+more secure future
\ No newline at end of file
diff --git a/2018/aa.ciphertext b/2018/aa.ciphertext
new file mode 100644 (file)
index 0000000..f1bf626
--- /dev/null
@@ -0,0 +1 @@
+010000100000100100010111100101000010101110101011010100100110100110000110001000110110100010100001001101101000101010110001010000110010100011100001000010101110111110001100011010100110101000010000001101000001000001011100000101110001000100100010001011010111000000000101000010100101000001001000000100101101100100110000110100110111110000101011100110001011010010110100101000111101101100111100000010100001001101101011010010000010001000000100001000100001011000010011010000110001111010110001000010100111000001001011001100100100111110101100100010100011001101000001111001000100101100010000110000101101001011100100001010000000110001001010010100001011100110001011000010110011001010000110100001000001111000010110110000100100100010011000011010110000010010111000110001001010100000000000111010001111010011001111000100111100000010100100110010101100110110111000100111000100111100100101011000100110010010001010110001000101001010101110101000110101000101001010101110001011000010101001010010000110101011100010000000010000100000100001101010110100000010000011000010000010001000001010101100110011101000110100001010100100001001010001100010000110111101101011011100100000000011001110000001000101001100011100100000110011100100010000000011010110000000000001001010011110000000110000000010010110011110000110100001000100000001010011100110001000100101000110011111010101001011100101101001001000111101101101011010100001010010000000110101000100011001001010101101101100110001000010000010000000110011100010000010011110110100110001111010101010101000111110001011001000100000010001000000000001000100010110101110100000101011100001000001000011010110000100111100000010100110100000010011111010101111100110010010001100011010101011101000111101101011110011010110101111011000100010101100101011001110010010101100111100000110101000100100111100110001100010000110111101101011011100100000000011001111001001001001100101000011010110101100100001110000000110100000000000011010100010000010000010101001000100010001011110010000001100010000110100010010000110100100111100011000011100110011000001001001110001100101011000000010001001110000000010000001011011100101100000000011010100101001001010100101011110010010001101011010101111110010000110100010000010000100010010000001111011100010001011001010101000110001001010011000010100001010000010001001100110011110001000101000110010110000001011011010010100100101101101001011100110011010110101100010001101000001010001001010001010011110000000110011101011010001010000110011001001001001100101000011010110101100100001110000010011010100010010111000100000001011000100111100100101001001001010100001000010000010000100101010000001001010000101000101101000111110001011110100001100000101001110001011000010100011101110111101101100110101001100001001011001001010000101000101000010111110001000000011001100001101011011000000111000101011001000001000000100100101011000000101001110001001000111001101011001011000101010000110000010100111010100001100010001111000011001001101011101101010110100011110001011000000111100011000101100110000010010111000100000001010101100001011011010101100100100000101001011100010100011011110001000100011100110101011001000110000110011100010011000101001011000100100101000101011001001011101101000100000100010001001011000111100110101000101001011011111000000001001100010101111000000110001110100111000011100101101110000001011110000000011010110000000010100000010001010011110001000010001001100000111001000101100110010100000011111010100110000001100101011101000111110001001000111001101011001011000101010000010101011000011010110000010000101000101010011010110111001000110000010011100111101101100010100010110011011000010011001110101000101000010001110001000011010100010011100101000001011010110000110011100101010001000110101000101000010000100110001111000110001010010000001001001111000110001101110110000101001110010110010011000101110000011101100101011101000111110101100101001111000100110110001110101000101010010011100110100001100010101010010011100100000110001000001010110101000111110001001000111001101011001011000101010000110000010100110010010001100011010101011011110000100110001111010101100011101001101011100111100000110011100111001001001001001101100101011001110000100101010100010010011010100101010001010000010101000111110001100101000100011001010000010101100110101000110011100111000111011011010000010100100000110100001000001110100000010000001101100100001000110011010100111000000001001101000000101011000001010100110100010000111011000111010111010001011101000000010001001001000101011110010101110001100111000100110011000000001110101000101000101000010001110101011011011100100011110000100110001111100110000001100100000100010000101010000001010110011001001001010000000100100100001100110000101001100001000110000101100110100001100110011000000110000000010010110101000111110101011011011110001010001000000101101101010101001011001011100100011100101000010000110000110001000110001110010100110000110100000000110000010000100110010001011011100101010100001011000100100111000101011101000100000110100100010101010001010000110101011001010111000011100101101001001000010000010001010101110001000110101001100010111010100001101100110100101000010000100110001111100110000011011000010011001110101011000011001001110100000000110000010000100110010001011011000111001011110001000110000001011010001001011100101101100000101100110000111001001111000000001001001000100100001111010100101001100010000110001101000110011110010000011100100110001000100010000010000100000100100010111100100011110000101101011110011001111011110001101101010110101001100000111011000000100111100101011101010110000110100010111100110011100111000110011101001101111000010101010111100111100000010100110100010010001001100000010010111010110001101100001100010101001011000001101101010101001011000000100001000000100101000011010110000110011100001000010000010001110001000010101110001101000111110001000110010100000101011010010001011010101010000101000110001101011000100000010101001100110001000000101000010001000000100001000000100111000001100110010000010000100110001000011010101111001001010001100101111010100110001111010100000011111100100100010001010001100100100010010101100111100001010011110000000110011101011010001010000110010011101001000101111001000000011000001001000110011010011010110011000000100101010000011001111000100111010111000011010000100001101101000110001000110111100001101011010101111101010000001101100100110100010101111011000100010101010100001011111010110001011101011010001010000110011001001111000100001010101011010101011011010100001101000111110001100101000110000001101100100001011000101000101001010000001101011110011000010100100000001101011011010010100000010000001101011011010110101100000110000100010001010101011000110110010000000010010101010000100101110101100100011001100100110100011000001000111001101001011100100110100100010100101001010010000001100010000100010001000010010101100111100010010100110010001101100111001100101010011010110011100111100000010001010010100010010110010110000010010001110001100101011001100100100100000000110001001100101000011010110011001000100101010011111010110101100110010101111010011010110011101011100111001100100100000110010000010101011000011010110000100111010101010100000110000100000000101010010100100110001101011011010000100001011010110001100011000101001011000011010111001001010101101010011010110011101000100100000000011001111001010000101010001000011001010001100101000110000100000110001111010001000101001101000110011001011111010101111000011010010001011010101010001011110101100001100111100011000101000010000001100010000100011101011001111000100111100101010001010100000000000110110100010101110110000100001001011101001000010101100001001010101000101001010101000001011000011011000011100011001101011011010010001010000110010001101110011000010100100000110101100101010111000001100000110001100010100100010101100110000000100111010100010011100111100001101000100010000101110110001001001000100000010001110110000110100111100101011001110000110101100011010100001000011010110000000000100100010010010111010100100111010100010011100100000010011110100001100000010101010100001001010000110000100110010011000000010010001011110010000001011011010000010100101000010010101101010110100011110001011000000110001111000011100100010011001000101001100100110100001000001000101000101001011011101101011111010101111100110100100111100111010110011001011010100110101001000101001011000011000110001111010100011010011010101101010111001101100001110000100111100010010000010001000100000000000110101000101001011001101101100100101010001101011010001110010111010101111001100110011000010111100101011101001011000010010111000100000001010010010001001111000100001011010100000000000001011100010001000000100001001100001010010001010000110100001001001001111011111001010001011011001101100001110100101101000100000110001011110111010001100111100000010100100100000000000110110100110101000111101101011001100101001001001011100100011100101000010100110000100110001111010110001011111011100110101000100001011001010101100100000001100110000010011010110011000000011001001000010000110010011100100001010101011011100110001110100001100101010111010100100111100000010000110110000000100110100011000011001011110101010110001011000100100000100001011110100000010100110110000000100110101110000101111000000110001110101000101001010100100001011100000110100001010111101101000110100100010001011010101110110000101000101001011001110101001101100010001011110110100110001111010100010011100101100001100101001101100100000110010101100110110111000100110100101101001101011100010001000100000000000110100100010000110001000100001001010011000011100101110100000000100001111110010000100001011100000100110101000010010101100111100000101010011010000110001111010110000100000110001111010001000101001001101011000100000101010110000100110110001111101000100000010001000000110100001001010101011101001100101101011011001100010100110000100001100111100000010100110111101101000110010110100000011100101111001111100110011001010100000000000111100101001001010110100110100110010100100001010000100101011100001100010100111001110001001000011010100001011010010001100110101000101001011010110001101110101000001000010011000110011101011101100101000111100100011100101100100010000000110100001000011011000100000110000100100101100011000100101100101011001111000100001100110000101101100010101000010001001011000000100111100000010001000110001111100010111101101101000101100001010000010000100000011001111000100111100000010101010000000111000000001000000010000110001111010100100100011100100110000011101001010101011000110011001101011011000101001110010000010101100101100101011001000110001010011101011000000011111000000000000101100100001001011010101111001001000101011001000000000001011100010010001010000110010000010000100110001100101000001110101000101000110011111010100101101101010101111001011100110001010111000110001010010001110001010110111100011011000100000110100100010100110101000010001101100101001101001001010100000100010110111101011011110000101101100101100101010100001001110001000101000100001001011010100111100100010101111100110001001110100100101000110101000001000110010000010101011000111000000010001111010101111000011010110000101101010110000101000100000100100111010100001101001100101011010000010000100100111011011001001000010100011101000111110001010001010000010000010000001001001001100011000001000110100001101000010000001010011010101110010111000100000010110000001111011101010000010000101011000001010101100110001101001011000001010100101110000011001011000000001101010101111101000111101101011010110100010010000100010000001000111001101001010101000110001001010011001101010000101101001010101000010100100100010010001000110100001000010011000101101101010100101000010101100110001111010100010011100000110101100011010110000001010000110000001001001100110100000111110001100011010100001000011010110000001111000100001000100110010011101000010010001010000110001101011011000101001110010000010101100101100011000100101100101011001111000100001100111001110101001101100010001011000011010000010001011000011001011100110001011010101000110011100000110001100011010110000101000000010010100010010101010011010110010101101101000110000001100100000101000101100101011000010000110001000111001010110101000111110001010000010010000010010111010100100110100100110011100000100001000000010001100011000101110001100010110101100100101001110000101101100000110011000110010100000000100001111110010010001101100101011001100000110001000101100101010100001011111010101001001110111110001010000110000101001001010001100000110001011001001000010010001100111010010101001101100010001010000100001000001001000101011110010101000001011010101000010011011011100001100011000101111110010000010101001100010000110001101000001111000000010000000001010100100001100111100010001101011100100000001001010001100101010000100110011101001000010010011010000010011100100010001000011010100110001111100110000101001011000100110000001111000101000000110001100010100111000011100101101101100100001111000100100010100101000001100100001010010000100110001000010000001100110000100001100011010101101001010100000110010000101010000001011001110010011111010101111100111011000000000000001001001110011000001001011100101101001001000100110001100111100000010101110100000101011010101010001010000110010010010000100010000101001011110001100010100101100011100000100001100101000110110010010000101101011011010000101001010010000001011010101011001001010000110100001000001011000100110000101110101000101000011011111100100111100100101000101001011011100001010000010010001101110100000101100111100011000101000100000101101101010101111001010100010000011000010101111001010010010001000011010100100000011010100110011100100100010001010000110100001000011011000100100100011000010111010101001100110100110001100110110100010001011010101110010111000100000010110000001001011100100001001001000100000000000110010110010100101011001001011011000101011001001000000110101101000110000011101011000110000100010101010001101011000100100111000111001011000110000100001001000100001010011010110011101101100000010011100010010001001100010110001101001011000110001111010111001000010101010111011101011010001010000110001110011100010101000000011001111000000011010100000000011010010001000100001000010000011100100110001111010111001011111011010111101101000110000000010101000110101001000101001011000011001101000101100110011010011001100101001000100010011010010101010001100011010101101011111100100110011100010010001010000110000101001111000100001011110010001101100011001100101010010001110001000100001001100100111000000000001101100110001001001011001001011011000101011001000111010101101011100101011001111100110001000000100101100011100000001001001110111111001011000100001111010101100011000001000100110001001000010010001011111011000101101001001100000001010000000101001010101101001000011010110000001111100110000000010101000110010000110000110101001000010001100101100011000001000100101101000110001010110001000110000101100111000111001010011001110101100101010100001101000111110001000011000101001010110100000000100100101000101001011100110001011110010101111101000000100100000001001100010001000100010000010000100000010000110000111000010000010000010001101100100001011000101000101001010100100111010111011111000100101000001101011011001101111010010000010101100100101001100011000100000110001000100010001100100100010011001001010000110001010000010011010000110000010011100111110101100101010111000100101001101011001000010010001010000001000101010001000110000011010110100001100011100000110100111010110001101100001100010101000111100001000110100101100001100000010100000001010001100101110101110101011110001001100011010100001111110001100100101011111010110001100100101001001110010100110001010111100100010101100110010100001000010000010101100110000100011001010111000011100000100110011101001101100100110000100101011100001111000011100011011000010000110000010100110100100111100111100110001100110110010001011001010100001000111001110001000000100000011100101011011001100111100000010100100110000010011100100010001101000111101101100111001001001000010101010111100101100101011101000110000100001011010101111001011010101111001001100101011001101011000100001001100100100011100101100001011001010110000101001000001111011110010101001010010000110101000100100100101000010101110100000001010000001010011100110001000100010101011100110110000011101001010101011000110110000101010000101001001011111011010111001001010011000011001001100110011100010100011000011010010101010111100111000100100100000000000111100100011011110001000100001000010000010011011000010001100100110111000011100000110001000110101001100001001000000101000100100000010001001000000110101000100110100010000110000000101101010100000011111010000010010111000100110011100110010000000001001001100101010000100110001111010100110100101000000000100111010101111001100110000100001000010000000001011000000000000110010101010001010000000110010001001101101011111001110101100111100100000100110000110100001000010010001010000110000101001000011011000100000110000100100100110101100101011001110000000011010110001010000110010101000111010111000011001001000001011000011001111011111010001101100110001111000101000110000100010001000101001010010000111000011100010101000001010101111000010000000100010101110110001001001000100000010011100000110110101000100110001101101000001111100111100101010100111011010010100111100000010100110110000110000001001110001010010101000101101101010100101000010101110101011010110000010011100000110001000110100101100011010110000001001010101000101001011010010001100111100001100001000000000001101000100010000001011001101000001000100111001000010101010111010000010010001010000110000000010000010000010101000110010001011010101000101000110110000000100110101101111110010111101101100010100010110100000001000110011100101110001000011100110001100000101100010100110000110010011100100011000011100100011000110000100110001100110000100001101100010101111010111011000000100011010100000001011010100110100101100100100011100100011000100100101001111000010110110010010001001110001011110000010001001001100100011101000111110001100011010110100000010000001101011010111110001010001000000000001100101001100100110001010011001101010110000101000010010100011100110111000100111100110001100100011001100011100000010101000010001000010001101011000100100101010101011001001000000000001100001100010011111010100110001111010100101101011010100110001010010101111101000111110001010100010101010100001100100001011001000110001001101000011000001000100110001010000110000100001000110111000100111010100110011000101100000010000100000000000111001100010100100000101101010000010001001110011010100001100111100000110011100111000110011100001000110011101001010101100110101001100001101011000100001001100100100011100111000001101011010101111011101010010001011010101011000000110000110101011100010000110101000010001101100100011110010010010000110001011110010110000100111000001110010111010110001010000100000110100111100000110100110010001101100100101000101001010010000001100010000101100001101011000000001000010100011101000111110001000100100000110011011000000000000000001001011001010000101001011100100001000100110000110100000000101000101000010101110011100010010110100011100001000010000001011010001001011100100110001111010100011000011001111000011101011010001010000110000101011100110000110001010000100101011001000101111010110110000110011001000101011010011011100111010111000110001010011011000000010000100111000011000001001111100011000110001010010001110001000010101110000010011010110001100100100111000011100101101101100110101011000000111001000101011100010000100011110001110001100010010001010001011010100110000100100000010001001000001110010000001000110101000011001101100011010111000101100110000100110001010100011001100110001111100111100110011001010010001101110000101001100011011011001000001000110100101011111001110001011001000101111010110110000110100100101000101001010101100001000100101101010001011010100110100100100110001011111001110001011011011001111011111010000110001111010111000100100101010100010000110000010101110110000100001000100110001010011001111000011100101110001101000111110001100011010110000011111010010001101101100000010100100110001101011011010000110101000010001101100100011001100100110000010101000010001000010101000111101101100110101000101001010011001111011100010010001000011000000000001001010000010011101011000111001101100010001011110110011001000011000101111100100100000101100100101110000000100001000110100111100011000101000000010001001000001100010001000001000000010111100101000001011001101011101101100001100001010001110001100010110101111011110000110001100111100000010000111001100001100100101101111001011100110001011110010101111101000111101101000111001000010001011010100110001110010101111011110001010011001111000101011001001000000110000111100100001011100000100101001001010101010011001000010111001000001010110101000111110001110001100011000001001001110001001010101011000011100011000110001111100101011001111000011001011110010101111101000100000000100110010101011101000111110001100101100000010011000001110001100101001010010101000000110101011001010110100011110001011000000110101000010011001001110100000000100001111110010000010001100111000110100000010000101111001111100101011000110100000101001001000101011110010000110100010000010000100100110001000100001011000100000001010101101101011011010011000100111001010001000110001100010101001011010111001001010101101000011010110001110001010101100011100000110100001001001001001000010101010111011001000101111010110110000110100100101001100011110100000101010000100110010100111011110001000100101000010001000000110100001000100100101000010101100001101101000101111000110111110101101011010110001000010100111000001001000101101100000110001101100011010100001000011001110101100110101001001001011001101101100111010101111010011010110100010000100100101001010100010000100000101111000100100000110001100010100100011101011001111000110000100000010100110000100001100011010100001000011010110000010001000110000100110001011001001001010000000011111010000010010111010110001001011001101011000111100110000000011100111001001001010000110100100110000110101000100001011001010101100110011100101000101001011001110101000010100011000100100011000110011101011000110011101000000101001110101000101001011000100001000011100100101000010101100101100111000101111101000110010000000010101110001101110111110001011010101000101001010011000001001011011000010100100110010000011001010111000011100110001001000100010101011101001100101101000100101000110100100110010010101000100100010001001000010100000001010011000000100110000110100111010101111011110110110010001000100010001010000110000110000001001001001001010010001101100101100101011000011010100001001011011000110000110110000000001000111010001101001011010100000000100001111110010000001001010000101000101011010011000000000000001100010011111010100110001111010100001011111011000100
diff --git a/2018/aa.plaintext b/2018/aa.plaintext
new file mode 100644 (file)
index 0000000..3c14f42
--- /dev/null
@@ -0,0 +1,57 @@
+harry had insisted we place the hole where it wouldnt be seen later i was pretty sure now that he
+planned to claim the table for his office so he suggested we remove the makers nameplate and drill
+there it was just as well he did the demolition charge was linked to a web of mechanical detonators
+and almost any other direction would have disturbed atleast one of them the machinery was old and
+the sappers werent happy working with it but mechanical mechanisms can be easier to work with than
+electronics as you can see how everything is connected a judicious dose of superglue fixed most of
+the mechanisms in place just leaving us with the problem of what to do with a heap of old and
+unstable explosives normally we would have placed one or two of our own detonators and packed out
+the place with sandbags and breeze blocks to contain the explosion and i think even harry might have
+been convinced that that is what we should do in this case but unfortunately the explosives were not
+the only thing we could see inside the safe sitting under them was a slim black book we couldnt see
+any details but having got this far it seemed crazy to destroy it anything this well protected must
+have been important at sometime and we needed to know what this might all have been about after a
+quick callback to headquarters harry got approval to continue trying to crack the safe he knew me
+too well to ask me to leave but the documents team retreated to a safe distance down the corridor
+with most of the guards leaving a small team to watch over us as we worked one of them had joined
+the sas from the sappers and was an experienced bomb disposal expert so he worked with us watching
+the explosives for any changes monitoring vibration and temperature and generally keeping us calm it
+takes a special temperament to do that work full time and we were glad of the company and the
+expertise after seventeen hours we were getting tired and as eighteen approached i began to wonder
+if we would manage to save the papers but eventually the final cog turned and the last tumbler fell
+into place we had managed to glue the broken cog back together and with a mild protest the top
+turned raising a platform up through the central pillar to present us with the book we had seen by
+the light of the endoscope it was bagged and secured and harry took it with him the special forces
+secured the entrances to the shadow archive and i left to get some sleep we met the next day to go
+through the papers harry had started on the decrypt doing all the usual checks frequency analysis
+index of coincidence and soon the distributions were relatively flat so it was clearly not a simple
+caden us or substitution cipher and we started trying some of the ideas we had found in blacks
+codebook it took us longer than we had expected but after a few days we had the entire set
+deciphered and had begun the analysis harry had slightly different interests from me i was
+fascinated by the insights into an older world while harry was focussed on why these documents might
+have any contemporary significance both turned out to be important history matters and as marx said
+it tends to repeat itself personally i would be the wasnt the first person to say it and he wont be
+the last but for us the point was that as we read more we began to see the parallels between blacks
+world and our own and it was not comfortable reading when we got to the back of the book all became
+clear the book was actually a civil service report on the shadow archive closing it down and giving
+reasons why black had been too successful and his activities had badly destabilised the balkans the
+report traced a direct line from the bulgarian crisis to later tragedies given his early enthusiasm
+for his new methods of shadow diplomacy i honestly believe he never meant to cost so many lives but
+it seemed clear from the report that blacks interference in foreign domestic politics had had dire
+consequences it looked all too familiar and if our enemies wanted to discredit us when we complained
+about their interference in domestic politics then these papers would be the ideal kom prom at
+material it looked like we werent just victims of these tactics we had invented some of the methods
+ourselves back in the nineteenth century harry put out a request for analysts to work on recent
+signals traffic to see if there was anything to suggest who was responsible for sending me on the
+hunt for the kom prom at files there wasnt much and certainly nothing to link it to foreign
+government action it was quite possible that this was the work of one of the criminal networks that
+had grownup after the fall of the soviets market manipulation is a lucrative business and attacks on
+government credibility area very effective way to move whole markets the documents stolen from the
+archive were still out there somewhere and it was possible that they contained enough to embarrass
+us but that seemed unlikely whoever wrote the closure report had been thorough and it didnt seem
+likely they had left anything important on the shelves but time would tell harry set a watch in case
+anything surfaced and asked me to keep an eye on the black markets too as i suspected the shadow
+archive table appeared a little later in his headquarters fully restored and i assumed completely
+disarmed i returned to the library to finish the job i had started but when they offered me a new
+contract i refused i had a better offer the table was in an office next to harrys with my name on
+the door
\ No newline at end of file
diff --git a/2018/ab.ciphertext b/2018/ab.ciphertext
new file mode 100644 (file)
index 0000000..2419e56
--- /dev/null
@@ -0,0 +1,5 @@
+TSTJAN FP JON PVZDYPRFXTFEX, NQWKEJLOPJKHQ WYJ VZDEBRZB FG JON FXCOVE GADBJLI; KTNB TSGJYIKPUWATSUH. HCH CSST SHNF SUMN.
+XFTV YFFCHD HCH ZCXYCWHDCYPZ IZ JON QSYFDKY FOJTSXGAT ZW IIZKMZ WE XFP VZTKGAOMKH TRI IDZJLLATOW WH XFP LSDQL-RZZKQSRIPJZ JEXNXGNISRMP YMFEGB, DXK HRWIKH CTZORWO, BFIIGQNKT IIPPMYFU XJ IV ZAS WHNXNXS. XFP MKQVVA NSUUTLYF MKEVQXPJEDJLJZV LWI WMDCFPQ GJZDKTELYR NBF TVMGCHF, TD KPGR DQ W EOITDIH JQ GKHQCYF GKDIRNJ WYWC WYIGDHDD JQ CZH TGATQNUDIE. TN CMQC MKJZDDRE I AYJSJ EOITDIH JQ NBF ZYHAOUU TDEPNW WH XFP YYERLOP YUO IIMKITFEBGDCFPQ WE DS ZAS YEP SY ODDZKVCM VJ AGSWF TDEPNW.
+URI EGYEWX WHNXNXS LE IJ NPUIZPJEFEX RZNKMBLQPJJF TKNZDD HSX DS AD URI ZACHDJI EPDYFJWHC NF ASV XIEKHJH SOOKP LLMDSYJT LY DXK MTXN PCMAJINZNB ESRAOMD. JJ EGF OWUTFVTVBFU XJ NSUOKGA FPYXSLVXYUES WYJ NF ETVHC SSU ZCOPMZ ODTVKICUDG GNNNWED IPVNIEII DS LVIXFPM ZAS LYDOYFQXE KW BFI QGUOWUN’D QKQKTEQNZN, GADPN SMFXDBRZB CP SPNYOUU VJ ZXYSHDFVP ZKPDWLTGNUN LY DXK FLIYD NBDJ LAF YJUDZRDCKH XIHP ZNHZCOPMKO. QGGZN EWZYXPJZDJLJZ VZJBP NBCWUQ JHKI ZADD EDYMF VJ AGO KHJWLXCWACIYD SL URI GADBJLI, AGSSIR KRWOU URI IPGNETXN ZYZVII JQ CZH VTNAYZJVRE, TN TDN FN DXCU LIHC WKB QYMG ZFEKQNZNW BSVN PQKT XVRDNKP. JON QOG URWA JS YFCWRZ YYF YH YINSTS THTQCUS GJYISPDGGDCFPQ WYJ KKTQCYIG YFZCHJV.
+NP FWHDCJVBWH DXKTS WZSOCTQ XJ GYHF YINZ Y JWIVNFKFPUIYNO IFJENPJ BFI QGUOWUN WYJ DBDIPNF BYFN GJZDKTELYR NBF EINJ WFT QYMG YU WIKGZCWDJLJZ, NBWKKF KJRZ T JNL SL URCEP GKUJIHF YYF VR PTGK JE XFP KYJLWAP MFZTP MKGRFZXRKJ. NU DD EOMTJQII DXCU VXFPM RFJXNAV JWEGNAJNPA XFP MKEIYRDIKPJ CP MGCEW WE DXK GDVED XKDU CP DXK DIGFTQK NKDA GYHF SSRFNKO, YYA IJ KPJLHP AFY VJ IKDSNSRAF WYWC XFIN VFILJJ CW NDDETJM BDXF ZS NPUIW QCRF JC APGR VQ EFIN NU ZCYDYNPSB. JOM NPLIEDCMDJLJZV NPJC LXYJL QOJL NBDJ ON LYW TSPGDOE UV KHPT, CPU XFIN BF IIAOMUFU JHKI IWQXJZ ICHQWMGPWFJXE DS ZDWI DS MKHDBNZDK JE PJZZFP. RLE TITFULGDO LDCLVC HKTS RJD HKDBXFC, NBWKKF GO BDU FNPJ C TSPGDCHFBH EODJFQDPOG JTDQRZYR JE XFP PUJJII FNCUSD, GZZ JWEXNYKFTTVB AOJWIBE FPMISDA DXCU RI FIZ KHJWLXCWASB RZZKQSRIPJZ NSWYF. JF TSGJAZ FG RLE PIVMVHXPJZ ETR LP WFVEB, FKHKXSV EPQKTTP JQ NBF SSAIJZ OVGDYOUUQ JHKI MTSH’E SOYHVRGX DFMBIMDCFP RLYD NBDJ FVIDQ BTD HPDYVDXNJ YW ASV XIEKHJH’E QCYHJ DNNMKU QIMAOZDIH, EK NBF TFEPJJF VJ GZT EWZYXPJZDJLJZ CW VEDDAKYJQLYR. ARDZN UPKZ D FIHFSUDB MJOMUDB EFTDB EVRAICUFU DJYO NPJIHPVZJEK IPNCJBD, QTQNPA YE FSTF DRETBBU DRAK XNH FIHFSUDBLAC, YUO DX RF DRFTV AGYZ AS XFACHFU CY IZHFEXDAO. SPHCHDPUDJIVC, NBF LCVOIKH IIVINNPA XJ GCW QSVRKZ NP BCYJSU DII GXVF NDDETJM, HV EN NYUPVX HPGD WE XFPI ZW HLVX CU URI XTVWJEK IPNCJBD JQ XNH IIMAPNUCIYD NF URI GADBJLI. YKJKURIVPVW D EYXMOY WH YYKWLJZLGX MKEVVIF ICJEXGTJKO YH XPIIFID JQ NBF HCHPCMP QIMAOZDIH’E JOVDIXXPJZ HKKQPVZ URWA DXK FMLEDOUES CP DXK DIGFTQK, BRLVP SLGDGRIGRZ UIYTOE, BTD UZSGP JC G FICMB RDYAKT VJ XPIIFID JQ NBF DRAPGRJAIYNO JWCQDZCZZ DR VKJEWE. LY SYYUDGDXYY URI NFNCCBLEGIKPJ CP GOCOGYGANKTQ LY FDFUBWYJ TCTU EGF Y YFBWATQKMN CZPJ WFZVND, KYFQYXIARZ YIMIPWF JON SSRJZI AGOTHSPOPV GFII GLYYF JOGD VFNSXFTJM VEYEOYR BTD QKCUI VR, AGSSIR XFP JCNS WYJ YJUDZRDCKH VJ AGO FTAWYTVCUDCY LOYF T GVKVKMN KDIMEFU DNNMKU. JON ZYTF QOGJSG DIGFTQK OVIE ZSZ DFTNIM FP TRB KWLJZLGX ZFEKQNZNW GICX DXK QSVRKZ. CH JON FDCMS CP MGCEW’D JSOYDJLJZV MTSE RZ NBF CLI PCMAJINZ VKXSRATOW, TKQJOMW WH LAF YJUDZRDCKH TPEK BYFX WYJ CZ HSIXF NF ATZN MOKP JORF, YW NKGF IV ZAS RNPZ ZW SDAIARJQO G FOJVII VKDCUDCY QSY ADD QASGJEK MKGRFZXRKJ FG DRAPGRJAIYNO VDFIHF, NBDJ DNPIW UV OGWO RFU FVIDQ UV XFP ZKXSPJSIKPJ CP DXK VEBNABYWKRI XYIZILYDX IFEIGDX ZAS HGAZ. ZAS IWDMCWIBRZYYZ ZCED SL URLE NSSMU RJD AK QICZPMRZ ZCYNOCMSB GZZ ZADD VPZ ZW GYNFNNWED RZ NBF RCDFO GADGF TJ ZVIR, RQ TFV XLVX OAEKDN DXK QKR, IASHF JON IMJADZN QPYURIH OJEFIKHKPUO. JOJFO MWLIHZIKPJ QRZCWUILNF HBJZO FIZ BJJONANF CSIY MOUFHLMTYYJSD JQ NBF DRAPGRJAIYNO EDJW GZZ CPTPBFCW QICIODKO YH LXYJL’Q CZPMCUDZNF JFB ZCXSGKUSPB JCWUTRMPZ ZASQEPGHFQ, WYJ XK HSIXF NF ATZN MOJWCI GZ YRNVDA PJZJIIVC WYFS WQPJZ, HSXATJM ADD JLJ VWBLATDCM TRI JCVMVQGDCJ IVWVF HNUR XFP NCEDX EOKVWIX JQ NBF FWVIDK. OKVRZB ZADD ZPMNWU, FVIDQ BTD PKDSHQII XYYISPB KJ EFQXGMCRJQLYR MSHQLGZ, BKTCWY IJE DKDAACCP DQZPMNDBLED OAQTRETSU JE XFP ACMWWYF MKIDCY, IJE WE XFP JKFU XJ SMFUSGA DXK NSBRDOYTTRNIJ ZTTBN ASSUSD. FP VKFCD AK XCXS BNWORWFII IJ KYJIYFCHF EIALSYL VJ GROUUQ LY DXK TSKRKJ, IVJ QJAO NNFCHDYUUBH AK XCXS BNWORWFII ZOG NSXFKZW WH EJAFNPA. EFTGK EBWEFCJDB BRSGFNTGB GYE DBEGCV YFBLNJ SU FQTRKJCIS, FVIDQ FQXGMGNHRII ZOG EVZNAN TFJOJJV ZW ULEAPVU JON JCVMVQGDCJ DZXRWCZJSD JQ KFUSRATYR WFTJFCZJVR, LC KRDZLYR YMFEXE LCZADR AGONT YYHPYSEIWMTOW. EVRAASRMDRQ DXK DAIYJY FG DQZKMZDEX RZNKTEWATSUDB QNPNNPAD, FP HCH TFVP, YZ MSWED CU QTVA, DS JWEXHKG ZAS CDDDFNS CP ZOMWJLGDCFPQ, WYJ NF CSRNQCZ GICX TJWJUI UZSGMSBQP SL URCEP ZKMDFNAYZJVRE. GO BDU TGANNEKPGA VSEZIEF ZSTDRQ DXK QSVRKZ FG JON MPRITVRIJ CPU FGXFCPQ GHTVKH ULEAPVUDRQ DXK DBPRIJJF YYRXZNPA FNDHKFE XFP NBTSI NYKKTVVE. TW BF RWI AOWUILMDOE ADQEPGL UV IYRYMJEK KTNB URI XIEFT FCKPMW JE XFTV GDN ORF MKEVVI LSSMU OGWO IFSR HPBCTUII IV C HDKYTWNETRA FPJESDE IJE URI EOAZMSXB KW BJQ QNDXFOQ QGC HKMB OGWO GWE ORY WYJSRIF CU ADKF RSHFIRXPJZ. URI EVCRGKP KIT NP XORNX BF CWYTKSMTXNJ CUUSVYINNWEWV NSUXSRATSUH JC JOM IFEIPTN CU LIHC GNUJPN NSWU DR VTQKH FVJYCWFU XJ PVZDYPRFX C PSE KIT FG XCHVCUI YH EOAZFIJDRO NPQXNIZ FG XWH. OJLWIXDZYZFBH FTV HJZXJACKH SRMKPYDAII I IFTS VNNFRFQD GSKYWTGF IJE AS DNPIW UV OGWO KYFPJAOE NVVN PRZTSQN WOYHDCYF SL EVZNAN EJFPJYYJZ. RIHP MKEVVIF YZ URI GADBJLI APGR D CCHP DFNFPNDO WUVVB, DXFVAO PKM YFTDJZV ZATX KTGR CSGJYO JMSWH TJ C NVQNZN, GF RWOP DBWQIY DS YFCCOP YUO ZPGFVNGN, CH TJ WWCI MIVKH UIEDMFZ, JOJFO EWZYXPJZH XORNX UDIVGDO NU. JONAO NH ZPNIM KXDBNZDK URWA MGCEW DND PV VELAF HNURLY DXK DIGFTQK UV YYJOYUTNN LXCU RWOP AKEVQN VJFBE WE MGCEW CZPMCUDCYF. (YW DE WETZK, URI NDTTWBCQC SL URWA ZYTF XWE ZSZ EBIGA PUUDP AGO CTZORWO GDQ YYNSHFIII.) DXKHS DZPDNDBLEPZ NP YPGNFTDDP, LACIFIH GZZ VWBLATDCM TKRDYZJVR. KGCRF JONAO CTS RJ AOJWIBE KW BJAONA DYJCIE MONPA WDDXFTDDNJ AD URI GADBJLI, AGO CEJLOTVZH JONC HFTWII LCZA XIHP JFU TFJWO TVIBNA, YUO DX RF LSJJI ZASIDYPN DXCU JORF XCO YIMKIK DECAGOY UVCV KW ZAS RNDHFTW. XFP GFETP QASSQQ DDSKFTJII MT ZAS WHNXNXS ENAO VDIXRNPRDIPB IDZJLI RZ NBF YWVVYU HJWAPV CU JON PJE WH XFP JNPSXNPJZA ZIYDPYZ, TRI MGCEW JJNPWHSB JZ NYZDRQ DS EJQVDSN YVQDRIJ KYFWYFCFP YH EKHNPA BRFDFTU WXKJM CTPUIJ UDJLJZYRJQXE. MGCEW DNPIW UV OGWO YFJLHPZ LTVQ AGO CTZORWO CTVYYJ NBF JLXP SL XDGAKMND’Q BNINB, AVENWOY ADD EODJFQDJAV JWEXRZPKO RLE LSYL TRI LO BDLI DZDFXSVNJ OHJUIYNO FG T ORRXRZ TGATQK IICDS HFTWLYR PUOSV MKZK PTQN IMJATRQPG NP JON AOMJVR GASSPU RRZOZFSR ALORXS. YYQSYUKRGDORZ, DX EPOTH JOGD NBF QOGJSG DIGFTQK PSXKKMQ BTD LC NBJQ DAIBK HKTZKMZJEK GAIKO DREOMYFZXRKJ NP JON AOMJVR, GZZ GF YIVTOHF JOGD CZH TGATSUH CWB GYHF ZCYDMNCKXNJ, YZ MSWED CUODVNNNRZ, JC AGO KXSRAF GKDULYR NF URI PTMWU XCHXZ GDI.
+XFTV LDZX GXSUF ZCDXZ JDKDN NSUHDBNAYIMS IXMYYTTDEYOUU JC AGO SL ACOPMUNSRA IJE BS JNPG GF RWOP JF WFXRKJ IVJ XJ AOJWCQNZZ ZATX AGO WATBJL YYERLOP YUO TPV TNW PSXKKMQH QOJOGE CS EJOJE VF, LAF ZFEKQNZNW DEWVCVKO, ZPGFVNGDII, IJE, JH RNNOWHTVB, JOWUICBPZ, CPU LAF YWHSXE JCWQVDNJ SL. URLE AOVWIX EGSSMU WVFS YFCWRZ DRDQDRQCKO HCH I KKTDCI KW CU BIGFN WFLIYDT-LJLI BPYYH. XI KKPRO IIMKITFEB G SPIMDGGDCFP UWAP SL UXC AGSSHTRI IJE UXIYDT-LJLI GD OCTBLNFN. NP JON YOCPJLXP, CZ HRCDXZ IF FVNFOYXSB DFCUI JON GCMASDA FOJVILAC YHDDPGMGK; JJ EJOGE GVVX DXK NVDA NSTQICXTVNPA QGDOYJTP RQ CZ HRCDXZ LDBP RZNF FEIXC XCPUD.
diff --git a/2018/ab.plaintext b/2018/ab.plaintext
new file mode 100644 (file)
index 0000000..5c64741
--- /dev/null
@@ -0,0 +1,5 @@
+REPORT ON THE ESTABLISHMENT, EFFECTIVENESS AND STANDING OF THE SHADOW ARCHIVE; WITH RECOMMENDATIONS. FOR YOUR EYES ONLY.
+THIS REPORT WAS COMMISSIONED BY THE FOREIGN SECRETARY TO REPORT ON THE STRUCTURES AND ACTIVITIES OF THE QUASI-INDEPENDENT INTELLIGENCE AGENCY, THE SHADOW ARCHIVE, HEREAFTER REFERRED TO AS THE ARCHIVE. THE REPORT CONTAINS RECOMMENDATIONS FOR ACTIONS CONCERNING THE ARCHIVE, AS WELL AS A SUMMARY OF LESSONS LEARNED FROM ANALYSIS OF ITS ACTIVITIES. IT ALSO CONTAINS A BRIEF SUMMARY OF THE CURRENT ASSETS OF THE ARCHIVE AND RECOMMENDATIONS AS TO THE USE OR DISPOSAL OF THOSE ASSETS.
+THE SHADOW ARCHIVE IS AN INDEPENDENT INTELLIGENCE AGENCY SET UP BY THE PRIVATE SECRETARY TO HER MAZESTY QUEEN VICTORIA IN THE LATE EIGHTEENTH CENTURY. IT WAS ESTABLISHED TO CONDUCT SURVEILLANCE AND TO CARRY OUT COVERT DIPLOMATIC ACTIONS DESIGNED TO FURTHER THE INTERESTS OF HER MAZESTY’S GOVERNMENT, WHILE PROVIDING AN ELEMENT OF PLAUSIBLE DENIABILITY IN THE EVENT THAT ITS ACTIVITIES WERE DISCOVERED. SCANT DOCUMENTATION STILL EXISTS FROM THIS STAGE OF THE ESTABLISHMENT OF THE ARCHIVE, THOUGH GIVEN THE DELICATE NATURE OF ITS OPERATIONS, IT MAY BE THAT VERY FEW SUCH DOCUMENTS WERE EVER WRITTEN. THE FEW THAT DO REMAIN ARE BY NATURE PRIVATE COMMUNICATIONS AND PERSONAL RECORDS.
+IN PARTICULAR THERE APPEARS TO HAVE BEEN A CORRESPONDENCE BETWEEN HER MAZESTY AND CHARLES GREY CONCERNING THE NEED FOR SUCH AN ORGANISATION, THOUGH ONLY A FEW OF THOSE LETTERS ARE ON FILE IN THE PRIVATE ROYAL COLLECTION. IT IS SURMISED THAT OTHER LETTERS CONCERNING THE RECRUITMENT OF BLACK AS THE FIRST HEAD OF THE ARCHIVE MUST HAVE EXISTED, BUT AN ENTIRE BOX OF DOCUMENTS FROM THAT PERIOD IS MISSING WITH NO INDEX FILE TO TELL US WHAT IT CONTAINED. OUR INVESTIGATIONS INTO BLACK SHOW THAT HE WAS RELATED TO GREY, AND THAT HE RETURNED FROM BOSTON MASSACHUSETTS TO TAKE UP RESIDENCE IN LONDON. HIS IMMEDIATE FAMILY WERE NOT WEALTHY, THOUGH HE HAD BEEN A RELATIVELY SUCCESSFUL CRIMINAL IN THE UNITED STATES, AND CONTEMPORARY RECORDS SUGGEST THAT HE HAD ESTABLISHED INDEPENDENT MEANS. NO RECORD OF HIS EMPLOYMENT CAN BE FOUND, HOWEVER SEVERAL OF THE EXTANT DOCUMENTS FROM GREY’S PERSONAL COLLECTION HINT THAT BLACK WAS RECRUITED AS HER MAZESTY’S FIRST SECRET SECRETARY, SO THE ABSENCE OF ANY DOCUMENTATION IS UNSURPRISING. BLACK KEPT A PERSONAL JOURNAL WHICH CONTAINED SOME INTERESTING DETAILS, GIVING US SOME INSIGHT INTO HIS PERSONALITY, AND IT IS CLEAR THAT HE THRIVED ON ADVENTURE. UNFORTUNATELY, THE VOLUMES RELATING TO HIS PERIOD IN LONDON ARE ALSO MISSING, SO WE CANNOT RELY ON THEM TO FILL IN THE MISSING DETAILS OF HIS RECRUITMENT TO THE ARCHIVE. NONETHELESS A NUMBER OF UNOFFICIAL RECORDS MAINTAINED BY MEMBERS OF THE FOREIGN SECRETARY’S DEPARTMENT SUGGEST THAT THE EXISTENCE OF THE ARCHIVE, WHILE OFFICIALLY DENIED, WAS KNOWN TO A SMALL NUMBER OF MEMBERS OF THE INTELLIGENCE COMMUNITY IN LONDON. IN PARTICULAR THE ESTABLISHMENT OF HEADQUARTERS IN SCOTLAND YARD WAS A RELATIVELY OPEN SECRET, PRESUMABLY BECAUSE THE POLICE THEMSELVES WERE AWARE THAT SOMETHING UNUSUAL WAS GOING ON, THOUGH THE NAME AND ACTIVITIES OF THE ORGANISATION WERE A CLOSELY GUARDED SECRET. THE NAME SHADOW ARCHIVE DOES NOT APPEAR ON ANY OFFICIAL DOCUMENTS FROM THE PERIOD. AS THE SCALE OF BLACK’S OPERATIONS GREW IN THE MID EIGHTEEN SEVENTIES, RUMOURS OF ITS ACTIVITIES ALSO GREW AND IT SEEMS TO HAVE BEEN THIS, AS MUCH AS THE NEED TO ESTABLISH A SECURE LOCATION FOR HIS GROWING COLLECTION OF INTELLIGENCE PAPERS, THAT SEEMS TO HAVE LED BLACK TO THE DEVELOPMENT OF THE UNDERGROUND LABYRINTH BENEATH THE YARD. THE EXTRAORDINARY COST OF THIS COULD NOT BE PROPERLY CONCEALED AND THIS LED TO QUESTIONS IN THE HOUSE WHICH IN TURN, IF YOU WILL EXCUSE THE PUN, DROVE THE ARCHIVE FURTHER UNDERGROUND. THOSE GOVERNMENT MINISTRIES WHICH HAD HITHERTO BEEN BENEFICIARIES OF THE INTELLIGENCE DATA AND ANALYSIS PRODUCED BY BLACK’S OPERATIVES NOW COMPLETELY DISTANCED THEMSELVES, AND HE SEEMS TO HAVE BECOME AN ALMOST ENTIRELY FREE AGENT, SETTING HIS OWN POLITICAL AND DIPLOMATIC GOALS WITH THE TACIT SUPPORT OF THE PALACE. DURING THIS PERIOD, BLACK WAS FOCUSSED LARGELY ON DESTABILISING RUSSIAN, GERMAN AND AUSTRIAN IMPERIALIST EXPANSION IN THE BALKANS REGION, AND ON THE NEED TO PROTECT THE MEDITERRANEAN TRADE ROUTES. HE SEEMS TO HAVE DEVELOPED AN EXTENSIVE NETWORK OF AGENTS IN THE REGION, BUT MORE IMPORTANTLY TO HAVE DEVELOPED NEW METHODS OF WORKING. WHILE CLASSICAL DIPLOMACY HAD ALWAYS RELIED ON ESPIONAGE, BLACK ESTABLISHED NEW COVERT METHODS TO DISRUPT THE DIPLOMATIC ACTIVITIES OF POTENTIAL OPPOSITION, BY PLACING AGENTS WITHIN THEIR BUREAUCRACIES. CONTROLLING THE AGENDA OF IMPORTANT INTERNATIONAL MEETINGS, HE WAS ABLE, AT LEAST IN PART, TO CONTROL THE OUTCOME OF NEGOTIATIONS, AND TO BENEFIT FROM INSIDE KNOWLEDGE OF THOSE DELIBERATIONS. HE HAD PARTICULAR SUCCESS DURING THE PERIOD OF THE BULGARIAN AND BALKANS CRISES DISRUPTING THE ALLIANCE BUILDING BETWEEN THE THREE EMPERORS. IF HE HAD RESTRICTED HIMSELF TO ENGAGING WITH THE MAZOR POWERS IN THIS WAY HIS RECORD WOULD HAVE BEEN REGARDED AS A SIGNIFICANT SUCCESS AND THE SUBTLETY OF HIS METHODS MAY WELL HAVE WON HIM FRIENDS IN HIGH GOVERNMENT. THE SKILFUL WAY IN WHICH HE MANIPULATED INTERNATIONAL CONVENTIONS TO OUR BENEFIT AT VERY LITTLE COST IN LIVES PROMISED TO ESTABLISH A NEW WAY OF WORKING BY SUBTERFUGE INSTEAD OF WAR. UNFORTUNATELY HIS VICTORIES ENCOURAGED A MORE RECKLESS APPROACH AND HE SEEMS TO HAVE EXPLORED MORE EXTREME VERSIONS OF COVERT DIPLOMACY. HERE RECORDS AT THE ARCHIVE TELL A MORE COMPLETE STORY, THOUGH FOR REASONS THAT WILL BECOME CLEAR IN A MOMENT, WE HAVE CHOSEN TO REMOVE AND CLASSIFY, OR IN SOME CASES DESTROY, THOSE DOCUMENTS WHICH NARRATE IT. THERE IS CLEAR EVIDENCE THAT BLACK SET UP UNITS WITHIN THE ARCHIVE TO UNDERTAKE WHAT HAVE BECOME KNOWN AS BLACK OPERATIONS. (AS AN ASIDE, THE ETYMOLOGY OF THAT NAME WAS NOT CLEAR UNTIL THE ARCHIVE WAS UNCOVERED.) THESE SPECIALISED IN BLACKMAIL, BRIBERY AND POLITICAL AGITATION. WHILE THERE ARE NO RECORDS OF HIGHER CRIMES BEING AUTHORISED BY THE ARCHIVE, THE ACTIVISTS THEY WORKED WITH WERE NOT ABOVE MURDER, AND IT IS QUITE PROBABLE THAT THIS HAD BECOME ANOTHER TOOL OF THE NETWORK. THE LOCAL GROUPS SUPPORTED BY THE ARCHIVE WERE PARTICULARLY ACTIVE IN THE BALKAN STATES AT THE END OF THE NINETEENTH CENTURY, AND BLACK FOCUSSED ON TRYING TO DISRUPT RUSSIAN EXPANSION BY SOWING DISCORD AMONG BALKAN NATIONALISTS. BLACK SEEMS TO HAVE RETIRED FROM THE ARCHIVE AROUND THE TIME OF VICTORIA’S DEATH, HOWEVER HIS SUCCESSORS CONTINUED HIS WORK AND WE HAVE UNCOVERED EVIDENCE OF A HIGHLY ACTIVE GROUP WORKING UNDER CODE NAME ARCHANGEL IN THE REGION AROUND NINETEEN TWELVE. UNFORTUNATELY, IT SEEMS THAT THE SHADOW ARCHIVE NETWORK WAS BY THIS STAGE SUPPORTING ARMED INSURRECTION IN THE REGION, AND WE BELIEVE THAT ITS ACTIONS MAY HAVE CONTRIBUTED, AT LEAST INDIRECTLY, TO THE EVENTS LEADING TO THE FIRST WORLD WAR.
+THIS FACT ALONE COULD CAUSE CONSIDERABLE EMBARRASSMENT TO THE UK GOVERNMENT AND WE FEEL WE HAVE NO OPTION BUT TO RECOMMEND THAT THE SHADOW ARCHIVE AND ALL ITS NETWORKS SHOULD BE WOUND UP, ITS DOCUMENTS ANALYSED, CLASSIFIED, AND, IF NECESSARY, DESTROYED, AND ITS ASSETS DISPOSED OF. THIS REPORT SHOULD ALSO REMAIN CLASSIFIED FOR A PERIOD OF AT LEAST SEVENTY-FIVE YEARS. WE WOULD RECOMMEND A PUBLICATION DATE OF TWO THOUSAND AND TWENTY-FIVE AT EARLIEST. IN THE MEANTIME, IT SHOULD BE PRESERVED USING THE HIGHEST SECURITY AVAILABLE; IT WOULD FORM THE MOST COMPROMISING MATERIAL IF IT SHOULD FALL INTO ENEMY HANDS.
diff --git a/2018/history-words-raw.txt b/2018/history-words-raw.txt
new file mode 100644 (file)
index 0000000..4c6bea9
--- /dev/null
@@ -0,0 +1,2265 @@
+__NOTOC__<noinclude>{{EuropeanHistoryTOC}}</noinclude>
+
+{| border="0" id="toc" style="margin: 0 auto;" align=center
+| &nbsp; [[#A|A]] &nbsp; [[#B|B]] &nbsp; [[#C|C]] &nbsp; [[#D|D]] &nbsp; [[#E|E]] &nbsp; [[#F|F]] &nbsp; [[#G|G]] &nbsp; [[#H|H]] &nbsp; [[#I|I]] &nbsp; [[#J|J]] &nbsp; [[#K|K]] &nbsp; [[#L|L]] &nbsp; [[#M|M]] &nbsp; [[#N|N]] &nbsp; [[#O|O]] &nbsp; [[#P|P]] &nbsp; [[#Q|Q]] &nbsp; [[#R|R]] &nbsp; [[#S|S]] &nbsp; [[#T|T]] &nbsp; [[#U|U]] &nbsp; [[#V|V]] &nbsp; [[#W|W]] &nbsp; [[#X|X]] &nbsp; [[#Y|Y]] &nbsp; [[#Z|Z]] &nbsp; 
+|}
+
+
+
+==A==
+*'''[[w:Absolutism|Absolutism]]''' - Political theory that one person should hold all power; in some cases justified by "Divine Right of Kings."
+*'''[[w:Act of Supremacy|Act of Supremacy]]''' ''(1534)'' -  Act of Parliament under King Henry VIII of England declaring the king as the head of the Church of England, making official the English Reformation; (1559) reinstatement of the original act by Queen Elizabeth I.
+*'''[[w:Adam Smith|Adam Smith]]''' ''(1723-1790)'' -  Scottish economist and philosopher, author of ''The Wealth of Nations'', thought of as the father of capitalist economics.
+*'''[[w:Age of Enlightenment|Age of Enlightenment]]''' - An intellectual movement in 18th century Europe marked by rational thinking, in contrast with the superstition of the Dark Ages.
+*'''[[w:Albert Einstein|Albert Einstein]]''' ''(1879–1955)'' - Physicist who proposed the theory of relativity and made advances in quantum mechanics, statistical mechanics, and cosmology.
+*'''[[w:Alexander Kerensky|Alexander Kerensky]]''' ''(1881-1970)'' - The second prime minister of the Russian Provisional Government, immediately before the Bolsheviks and Lenin came to power.
+*'''[[w:Algeciras Conference|Algeciras Conference]]''' - Took place in 1906 in Algeciras, Spain. The purpose of the conference was to mediate the Moroccan dispute between France and Germany, and to assure the repayment of a large loan made to the Sultan in 1904. The Entente Cordiale between France and the United Kingdom gave the British a free hand in Egypt in exchange for a French free hand in Morocco. France tried to achieve a protectorate over Morocco, but was opposed by Germany.
+*'''[[w:Allied Powers|Allied Powers]]''' ''(World War I)'' - Russia, France, British Empire, Italy, and United States.
+*'''[[w:Anschluss|Anschluss]]''' ''(1938)'' - The inclusion of Austria in a "Greater Germany"; in contast with the ''Ausschluss'', the exclusion of Austria from Imperial Germany in 1871.
+*'''[[w:Ancien Régime|Ancien Régime]]''' ''("Old Order")'' - the social and political system established in France under the absolute monarchy; removed by the French Revolution.
+*'''[[w:Appeasement|Appeasement]]''' - Neville Chamberlain's policy of accepting conditions imposed by Nazi Germany.
+*'''[[w:April Theses|April Theses]]''' ''(1917)'' - Lenin's writings on how Russia should be governed and the future of the Bolsheviks.
+*'''[[w:Aristotelian (Ptolemaic) Cosmology|Aristotelian (Ptolemaic) Cosmology]]''' - The belief that Earth is at the center of the universe
+*'''[[w:Arms Race|Arms Race]]''' - A competition between two or more countries for military supremacy.  This was perhaps most prominent during the Cold War, pitting the USA against the Soviet Union.
+*'''[[w:Aryans|Aryans]]''' -  In Nazism and neo-Nazism, a non-Jewish Caucasian, especially one of Nordic type, supposed to be part of a master race.
+*'''[[w:Autarky|Autarky]]''' - An economy that does no trade with the outside world.
+*'''[[w:Avant-garde|Avant-garde]]''' - People or actions that are novel or experimental, particularly with respect to the arts and culture.
+*'''[[w:Avignon Papacy|Avignon Papacy]]''' ''(1305-1378)'' - Period during which the Papacy was moved from Rome to Avignon, France.
+
+==B==
+*'''[[w:Babylonian Captivity|Babylonian Captivity]]''' - A term referring to the Avignon Papacy which implies that the Popes were captives under the French kings.
+*'''[[w:Banalities|Banalities]]''' - Fees imposed by a feudal lord on serfs for the use of his facilities.
+*'''[[w:Baroque|Baroque]]''' - A cultural movement in art originating around 1600 in Rome; art designed for the illiterate rather than the well-informed ''(Protestant Reformation)''.
+*'''[[w:Bastille|Bastille]]''' ''("Stronghold")'' - Generally refers to Bastille Saint-Antoine, demolished in the ''Storming of the Bastille'' at the start of the French Revolution.
+*'''[[w:Battle of Gallipoli|Battle of Gallipoli]]''' ''(1915)'' - Failed attempt by the Allies to capture the Ottoman capital of Constantinople. ''(World War I)''
+*'''[[w:Battle of Jutland|Battle of Jutland]]''' ''(1916)'' - Largest naval battle of World War I; fought in the North Sea between British and German fleets.
+*'''[[w:Battle of the Argonne|Battle of the Argonne]]''' ''(1918)'' - Biggest operation and victory of the American Expeditionary Force (AEF) in World War I; in the Verdun Sector.
+*'''[[w:Battle of the Somme|Battle of the Somme]]''' ''(1916)'' - Attempt by British and French forces to break through the German lines, to draw German forces away from Verdun.
+*'''[[w:Battle of Verdun|Battle of Verdun]]''' ''(Feb-Dec 1916)'' - Longest and possibly largest battle in history; resulted in over 1 million deaths and 450,000 wounded or missing.
+*'''[[w:Battle of Lepanto|Battle of Lepanto]]''' ''(1571)'' - The first major victory of any European power over the Ottoman Empire; destruction of most of the Ottoman Empire's ships resulted in its loss of control over the Mediterranean Sea.
+*'''[[w:Beer Hall Putsch|Beer Hall Putsch]]''' ''(1923)'' - An unsuccessful coup by Adolf Hitler and other leaders in Munich, Bavaria, Germany.
+*'''[[w:Belgian Congo|Belgian Congo]]''' - An area of central Africa, which was under formal control of the Belgian parliament from 1908 to 1960. The Belgian administration was one of paternalistic colonialism in which the educational and political system was dominated by the Roman Catholic Church and Protestant churches.
+*'''[[w:Benjamin Disraeli|Benjamin Disraeli]]''' ''(1804-1881)'' - British author and Prime Minister, best known for his defense of the ''Corn Laws''.
+*'''[[w:Berlin Crisis|Berlin Crisis]]''' ''(1948-1949)'' - The Soviet blockade of West Berlin during the Cold War; abated after the Soviet Union did not act to stop American, British and French airlifts of food and other provisions to the Western-held sectors of Berlin
+*'''[[w:Bill of Rights 1689|Bill of Rights 1689]]''' - One of the fundamental documents of English law; agreed to by ''William and Mary'' in return for their being affirmed as co-rulers by the English Parliament after the Glorious Revolution.
+*'''[[w:Black Death|Black Death]]''' - The plague which killed one third of Europe's population in the 14th century.
+*'''[[w:Bloodless Revolution|Bloodless Revolution]]''' - A term used to refer to the ''Glorious Revolution''; the description is largely accurate of William's succession to the English throne, although his struggle to gain the Scottish and Irish thrones was far from bloodless.
+*'''[[w:Boer War|Boer War]]''' - Two wars, one in 1880-81 and the second from October 11, 1899 – 1902 both between the British and the settlers of Dutch origin (called Boere, Afrikaners or Voortrekkers) in South Africa that put an end to the two independent republics that they had founded.
+*'''[[w:Bolsheviks|Bolsheviks]]''' - A faction of the Russian revolutionary movement formed 1903 by followers of Vladimir Lenin, who believed in a small party of revolutionaries with a large fringe group of supporters.
+*'''[[w:Book of Common Prayer|Book of Common Prayer]]''' - The prayer book of the Church of England; was first published in 1544 and has been through many revisions.
+*'''[[w:Boxer-Rebellion|Boxer-Rebellion]]''' - Uprising against Western influence in China.
+*'''[[w:Burschenschaften|Burschenschaften]]''' - Liberal German associations of university students; helped initiate the ''Revolution of 1848 in Germany''.
+
+==C==
+*'''[[w:Cahiers de doléances|Cahier des doléances]]''' ''("Statement of Grievances")'' - documents drawn up by electors of the French States-General, since 1484, listing complaints with the state.
+*'''[[w:Calvinism|Calvinism]]''' - Protestant religion founded by John Calvin, centered upon "the sovereignty of God" ''(Protestant Reformation)''.
+*'''[[w:Carbonari|Carbonari]]''' ''("coal-burners")'' - groups of secret revolutionary societies founded in early 19th century Italy, and instrumental in organizing revolution in Italy in 1820 and 1848.
+*'''[[w:Carlsbad Decrees|Carlsbad Decrees]]''' ''(1819)'' - A set of restrictions placed on Germans, under influence of Metternich of Austria; dissolved the Burschenschaften, provided for university inspectors and press censors.
+*'''[[w:Catholic monarchs|Catholic monarchs]]''' - The Spanish rulers Queen Isabella I of Castile and King Ferdidand II of Aragon whose marriage marked the start of Christian dominance in Spain.
+*'''[[w:Cavaliers|Cavaliers]]''' - Supporters of Charles I of England in the English Civil War; also known as ''Royalists''.
+*'''[[w:Cecil Rhodes|Cecil Rhodes]]''' - (1853–1902) British imperialist and the effective founder of the state of Rhodesia (since 1980 known as Zimbabwe), named after himself. He profited greatly from southern Africa's natural resources, generally at the expense of the natives; severely racist.
+*'''[[w:Central Powers|Central Powers]]''' ''(World War I)'' - Dual Alliance of Germany, Austria-Hungary, the Ottoman Empire, and Bulgaria.
+*'''[[w:Cesare Beccaria|Cesare Beccaria]]''' ''(1735-1794)'' - Italian philosopher and mathematician, author of ''On Crimes and Punishments'' resulting in penal code reforms.
+*'''[[w:Charles Fourier|Charles Fourier]]''' ''(1772-1837)'' - French utopian socialist thinker; supported man's right to a minimum standard of life.
+*'''[[w:Charles I|Charles I]]''' (of England, Scotland) ''(1600-1649)'' - Struggled against Parliament, favoring absolutism, hostile to religious reform efforts; executed at the end of the English Civil War.
+*'''[[w:Chartism|Chartism]]''' - A movement for social and political reform in England, named from the ''People's Charter'' of 1838.
+*'''[[w:Cheka|Cheka]]''' ''(1917-1922)'' - The first of many Soviet secret police organizations.
+*'''[[w:Chivalry|Chivalry]]''' - Church-endorsed warrior code of ethics for knights, valuing bravery, loyalty, and self-sacrifice.
+*'''[[w:Cobden–Chevalier Treaty|Cobden–Chevalier Treaty]]''' ''(1860)'' - Treaty substantially lowering duties between the Britain and France, marking increasing cooperation between the two nations.
+*'''[[w:Classical|Classical]]''' - Pertaining to the culture of ancient Greece and Rome.
+*'''[[w:Classical liberalism|Classical liberalism]]''' - A political and economic philosophy, originally founded on the Enlightenment tradition that tries to circumscribe the limits of political power and to define and support individual rights.
+*'''[[w:Claude Henri de Saint-Simon|Claude Henri de Saint-Simon]]''' ''(1760-1825)'' - The founder of French socialism.
+*'''[[w:Comintern|Comintern]]''' ''(Communist International)'' - International Communist organization founded in March 1919 by Lenin, intended to fight for complete abolition of the State.
+*'''[[w:Committee of Public Safety|Committee of Public Safety]]''' - the executive government of France during the Reign of Terror of the French Revolution, established on April 6, 1793.
+*'''[[w:Common Market|Common Market]]''' - A customs union with common policies on product regulation, and freedom of movement of all the four factors of production (goods, services, capital and labour).  It is established across most modern European nations.
+*'''[[w:Code Napoléon|Code Napoléon]]''' - ''(see Napoleonic code)''.
+*'''[[w:Collectivisation|Collectivisation]]''' - An agriculture system in which peasants are not paid wages, but instead receive a share of the farm's net output.
+*'''[[w:Committee of Public Safety|Committee of Public Safety]]''' - The executive government of France during the Reign of Terror of the French Revolution.
+*'''[[w:Communist Manifesto|Communist Manifesto]]''' - Document laying out the purposes of the Communist League, first published on February 21, 1848, by Karl Marx and Friedrich Engels.
+*'''[[w:Concordat of 1801|Concordat of 1801]]''' - Agreement between Napoléon and Pope Pius VII after Napoléon's coup d'état of France.
+*'''[[w:Congress of Berlin|Congress of Berlin]]''' - Prompted in 1878 by Otto von Bismarck to revise the Treaty of San Stefano. Proposed and ratified the Treaty of Berlin.
+*'''[[w:Congress of Vienna|Congress of Vienna]]''' ''(1814-1815)'' - a conference held in Vienna, Austria, to redraw Europe's political map after the defeat of Napoleonic France.
+*'''[[w:Consubstantiation|Consubstantiation]]''' - Lutheran belief that in the Eucharist sacrament, the spirit of Christ is present in the bread and wine, but they are not actually the body and blood of Christ ''(Protestant Reformation)''.
+*'''[[w:Continental System|Continental System]]''' - Foreign economic warfare policy of Napoléon, consisting of an embargo against Great Britain, which failed.
+*'''[[w:Corn Laws|Corn Laws]]''' ''(1815-1846)'' - British import tariffs designed to protect farmers and landowners against foreign competition.
+*'''[[w:Corporative state|Corporative state]]''' - A political system in which legislative power is given to corporations that represent economic, industrial, and professional groups.
+*'''[[w:Corvée|Corvée]]''' - In feudal societies, an annual tax on a serf that is payable by labor; used to complete royal projects, to maintain roads, and for other purposes.
+*'''[[w:Council of Constance|Council of Constance]]''' ''(1414-1418)'' - Called for the abdication of all three popes of the Western Schism; successfully elected Martin V as the single pope, ending the Schism.
+*'''[[w:Council of Trent|Council of Trent]]''' ''(1545-1563)'' - Council of the Catholic Church to condemn Protestantism and to initiate some internal reform of Church corruption ''(Protestant Reformation)''.
+*'''[[w:Count Cavour|Count Cavour]]''' ''(1810-1861)'' - Leader in the movement for Italian unification; first Prime Minister of Kingdom of Italy.
+*'''[[w:Coup d'état|Coup d'état]]''' - Sudden overthrow of a government, typically done by a small group that only replaces the top power figures.
+*'''[[w:Crédit Mobilier|Crédit Mobilier]]''' ''(1872)'' - Involved the Union Pacific Railroad and the Crédit Mobilier of America construction company. $47 million contracts had given Crédit Mobilier a profit of $21 million and left Union Pacific and other investors near bankruptcy. A Congressional investigation of thirteen members led to the censure of the board members and many political figures had their careers damaged.
+*'''[[w:Cuban Missile Crisis|Cuban Missile Crisis]]''' ''(1962)'' - Started on October 16, 1962, when U.S. reconnaissance was shown to U.S. President John F. Kennedy which revealed evidence for Soviet nuclear missile installations on the island, and lasted for 13 days until October 28, 1962, when Soviet leader Nikita Khrushchev announced that the installations would be dismantled.
+
+==D==
+*'''[[w:Dante Alighieri|Dante Alighieri]]''' ''(1265-1321)'' - Author of ''The Divine Comedy'', a highly sarcastic work criticizing the Church; one of the first authors to write in vernacular.
+*'''[[w:David Hume|David Hume]]''' ''(1711-1776)'' - Philosopher and historian of the Scottish Enlightenment.
+*'''[[w:Decembrists|Decembrists]]''' - Officers of the Russian Army that led 3,000 soldiers in the Decembrist Revolt, an attempted uprising at Senate Square in December, 1825.
+*'''[[w:Declaration of Pillnitz|Declaration of Pillnitz]]''' ''(1791)'' - A statement issued by Emperor Leopold II and Frederick William II of Prussia, warning French revolutionaries to allow restoration to power of Louis XVI.
+*'''[[w:Declaration of the Rights of Man and of the Citizen|Declaration of the Rights of Man and of the Citizen]]''' ''(1789)'' - French Revolution document defining a set of individual rights, adopted by the National Constituent Assembly as a first step toward writing a constitution.
+*'''[[w:Defenestration of Prague|Defenestration of Prague]]''' (Second) ''(1618)'' - Act of revolt of the Bohemian aristocracy against the election of Ferdinand II, a Catholic zealot, as ruler of the Holy Roman Empire.
+*'''[[w:Deism|Deism]]''' - Belief in a God as the creator, based on reason instead of faith ''(Enlightenment)''.
+*'''[[w:Denis Diderot|Denis Diderot]]''' ''(1713-1784)'' - French writer and philosopher dealing with free will, editor-in-chief of the early encyclopedia, Encyclopédie ''(Enlightenment)''.
+*'''[[w:Destalinization|Destalinization]]''' - Actions taken by Khruschev in the Soviet Union to allow greater dissent and to speak out against the actions of former USSR President Stalin.
+*'''[[w:Détente|Détente]]''' - The relaxation of tensions between the Soviets and Americans.
+*'''[[w:Dialectical materialism|Dialectical materialism]]''' - The philosophical basis of Marxism as defined by later Communists; uses the concepts of thesis, antithesis and synthesis to explain the growth and development of human history.
+*'''[[w:Diggers|Diggers]]''' - A group begun by Gerrard Winstanley in 1649 during Oliver Cromwell's England; called for a social revolution toward a communistic and agrarian lifestyle based on Christian Nationalism.
+*'''[[w:Directory|Directory]]''' - A group of five men who held the executive power in France, according to the French Revolution constitution of 1795.
+*'''[[w:Duke of Alva|Duke of Alva]]''' - Commonly refers to ''Fernando Álvarez de Toledo'', the third Duke of Alva (or Alba).
+*'''[[w:Dutch East India Company|Dutch East India Company]]''' ''(1602-1798)'' - The first joint-stock company; granted a trade monopoly with Asia by the government of the Netherlands.
+*'''[[w:Dutch Revolt|Dutch Revolt]]''' - Term referring to the ''Eighty Years' War''.
+
+==E==
+*'''[[w:Edict of Nantes|Edict of Nantes]]''' ''(1598)'' - Declaration by Henry IV of France granting Huguenots substantial rights in a Catholic nation; introduction of religious tolerance ''(Protestant Reformation)''.
+*'''[[w:Edict of Worms|Edict of Worms]]''' ''(1521)'' - Declaration by Holy Roman Emperor Charles V at the end of the Diet of Worms that Martin Luther was an outlaw and a heretic ''(Protestant Reformation)''.
+*'''[[w:Edmund Burke|Edmund Burke]]''' ''(1729-1797)'' - Irish philosopher, Whig politician, and founder of modern conservatism; criticized the French Revolution.
+*'''[[w:Eighty Years' War|Eighty Years' War]]''' ''(1568-1648)'' - A war of secession in which the Netherlands first gained independence as the Dutch Republic.
+*'''[[w:Emigration|Emigration]]''' - The action and the phenomenon of leaving one's native country to settle abroad. In particular, a large amount of emigration took place during the late 1800s in Europe.
+*'''[[w:Ems Telegram|Ems Telegram]]''' ''(1870)'' - Document edited by Otto von Bismarck to provoke the Franco-Prussian War.
+*'''[[w:Enclosure|Enclosure]]''' - The post-feudal process of enclosing open fields into individually owned fields; took off rapidly in 15th and 16th centuries as sheep farming became increasingly profitable.
+*'''[[w:Enlightenment|Enlightenment]]''' - ''(see Age of Enlightenment)''.
+*'''[[w:English Civil War|English Civil War]]''' ''(1642-1649)'' - A civil war fought between supporters of Charles I, (king of England, Scotland, and Ireland) and the Long Parliament led by Oliver Cromwell.
+*'''[[w:Erich Ludendorff|Erich Ludendorff]]''' ''(1865-1937)'' - German general responsible for capturing the forts of Liège, critical to the Schlieffen Plan.
+*'''[[w:Erich Maria Remarque|Erich Maria Remarque]]''' ''(1898-1970)'' - German soldier on the front lines of World War I, wrote ''All Quiet on the Western Front'' (1929).
+*'''[[w:Escorial|Escorial]]''' - Large palace, monastery, museum, and library near Madrid, Spain; commanded by King Philip II, promoting study in aid of the Counter-Reformation.
+*'''[[w:Estates-General|Estates-General]]''' - An assembly of the three classes, or Estates, of France before the French Revolution.
+*'''[[w:Excommunication|Excommunication]]''' - Suspension of one's membership in the religious community; banning from the Church.
+
+==F==
+*'''[[w:Factory Act|Factory Act]]''' ''(1833)'' - An attempt to establish normal working hours for workers in the textile industry.
+*'''[[w:Fall of Eagles|Fall of Eagles]]''' - Refers to the collapse of tsarist Russia.
+*'''[[w:Fascism|Fascism]]''' - Right-wing authoritarian political movement.
+*'''[[w:Fashoda Incident|Fashoda Incident]]''' - The climax of colonial disputes between imperial Britain and France in Eastern Africa; brought Britain and France to the verge of war but ended in a diplomatic victory for Britain.
+*'''[[w:February Revolution|February Revolution]]''' ''(1917)'' - The first stage of the Russian Revolution of 1917, consisting of riots in Petrograd which resulted in the abdication of Tsar Nicholas II.
+*'''[[w:Ferdinand Foch|Ferdinand Foch, General]]''' ''(1851-1929)'' - French soldier critical in stopping German advance during Spring 1918 and the Second Battle of Marne (July 1918); began the counter-attack leading to German defeat.
+*'''[[w:Ferdinand Lassalle|Ferdinand Lassalle]]''' ''(1825-1864)'' - German politician whose actions led to the formation of the Social Democratic Party, which was strongly opposed by Karl Marx.
+*'''[[w:Fernando Álvarez de Toledo|Fernando Álvarez de Toledo]]''' ''(1508-1583)'' - A Spanish general and governor of the Spanish Netherlands, nicknamed "the Iron Duke" for his cruelty; fought against Protestants in the Netherlands ''(Eighty Years' War)''.
+*'''[[w:Feudalism|Feudalism]]''' - Medieval system of holding land as a fief, provided by a lord to a vassal.
+*'''[[w:Fief|Fief]]''' - Revenue-producing property granted by a lord to a vassal ''(feudalism)''.
+*'''[[w:First Five-Year Plan|First Five-Year Plan]]''' - Outline the goals of the Soviet bureaucracy, focusing on heavy industry.
+*'''[[w:Flora Tristan|Flora Tristan]]''' ''(1803-1844)'' - One of the founders of modern feminism, author of several feminism works; grandmother of Paul Gauguin.
+*'''[[w:Fourteen Points|Fourteen Points]]''' - United States President Woodrow Wilson's outline for reconstructing Europe after World War I.
+*'''[[w:Francesco Sforza|Francesco Sforza]]''' ''(1401-1466)'' - Founder of the Sforza dynasty in Milan, Italy; successfully modernized the city, which became a center of Renaissance learning and culture.
+*'''[[w:Francis Bacon|Francis Bacon]]''' ''(1561-1626)'' - English philosopher, advocate of absolute duty to the sovereign, and defender of the Scientific Revolution.
+*'''[[w:Franco-Prussian War|Franco-Prussian War]]''' ''(1870-1871)'' - War fought between France and Prussia over a possible German claim to the Spanish throne.
+*'''[[w:French Academy of Sciences|French Academy of Sciences]]''' ''(1666)'' - Learned society founded by Louis XIV to encourage French scientific research.
+*'''[[w:Friedrich Engels|Friedrich Engels]]''' ''(1820-1895)'' - German Socialist philosopher who co-published The Communist Manifesto with Karl Marx.
+
+==G==
+*'''[[w:Galileo Galilei|Galileo Galilei]]''' ''(1564-1642)'' - First to use the telescope in astronomy; proved Copernicus' heliocentric theory ''(Scientific Revolution)''.
+*'''[[w:Geoffrey Chaucer|Geoffrey Chaucer]]''' ''(1340-1400)'' - Author of ''The Canterbury Tales'', a collection of stories exposing the materialism of a variety of English people.
+*'''[[w:Gestapo|Gestapo]]''' - The official secret police force of Nazi Germany, Geheime Staatspolizei ''(secret state police)''. 
+*'''[[w:Girolamo Savonarola|Girolamo Savonarola]]''' ''(1452-1498)'' - Brief ruler of Florence known for religious anti-Renaissance preaching, book burning, and destruction of art.
+*'''[[w:Giuseppe Garibaldi|Giuseppe Garibaldi]]''' ''(1807-1885)'' - Italy's most famous soldier of the Risorgimento.
+*'''[[w:Giuseppe Mazzini|Giuseppe Mazzini]]''' ''(1805–1872)'' - Italian writer and politician who helped to bring about the modern, unified Italian state.
+*'''[[w:Glorious Revolution|Glorious Revolution]]''' ''(1688-1689)'' - The removal of Stuart king James II from the thrones of England, Scotland, and Ireland; replaced by ''William and Mary''; sometimes referred to as the ''Bloodless Revolution''.
+*'''[[w:Great Fear|Great Fear]]''' ''(1789)'' - Event at the start of the French Revolution; upon rumors that nobles planned to destroy the peasants' harvest, the peasants sacked nobles' castles and burned records of feudal obligations.
+*'''[[w:Great Purges|Great Purges]]''' - Campaigns of repression against social groups, often seen as a desire to consolidate the authority of Joseph Stalin.
+*'''[[w:Great Schism|Great Schism]]''' - Term used to refer to either the Western or Eastern Schism within the Catholic Church.
+*'''[[w:Gulag|Gulag]]''' - The branch of the Soviet police that operated forced labor camps and prisons.
+
+==H==
+*'''[[w:Heinrich Himmler|Heinrich Himmler]]''' ''(1900-1945)'' - The commander of the German Schutzstaffel and one of the most powerful men in Nazi Germany; one of the key figures in the organization of the Holocaust.
+*'''[[w:Lord Palmerston|Henry Palmerston]]''' ''(1784-1865)'' - British Prime Minister and Liberal politician.
+*'''[[w:Philippe Pétain|Henri-Phillippe Petain, General]]''' ''(1856-1951)'' - A French soldier and Head of State of Vichy France. He became a French hero because of his military leadership in World War I.  '''(ed: specifically...?)'''
+*'''[[w:Henry V|Henry V]]''' ''(1387-1422)'' - King of England ''(1413-1422)''; accepted by the English as heir to Charles VI and the French throne, thus adding conflict to the Hundred Years' War.
+*'''[[w:Hermann Goering|Hermann Goering]]''' ''(1893–1946)'' - A prominent and early member of the Nazi party, founder of the Gestapo, and one of the main architects of Nazi Germany.
+*'''[[w:Heresy|Heresy]]''' - Holding of beliefs which are contrary to those of organized religion.
+*'''[[w:Huguenot|Huguenot]]''' - Member of the Protestant Reformed Church of France ''(Protestant Reformation)''.
+*'''[[w:Humanism|Humanism]]''' - A secular ideology centered on human interests, stressing the value of the individual ''(Renaissance)''.
+*'''[[w:Humanitarianism|Humanitarianism]]''' - The belief that the sole moral obligation of humankind is the improvement of human welfare.
+*'''[[w:Hundred Years' War|Hundred Years' War]]''' ''(1337-1453)'' - 116-year conflict between England and France.
+
+==I==
+*'''[[w:Ignatius of Loyola|Ignatius of Loyola]]''' ''(1491-1556)'' - Founder of the Society of Jesus, to strengthen the Church against Protestantism ''(Protestant Reformation)''.
+*'''[[w:Il duce|Il duce]]''' ''(The Leader)'' - Name adopted by Italian prime minister Benito Mussolini in 1923 to position himself as the nation's supreme leader.
+*'''[[w:Impressionism|Impressionism]]''' - Art movement focused on creating an immediate visual impression, using primary colors and small strokes to simulate reflected light. ''(19th century)''
+*'''[[w:Imperialism|Imperialism]]''' - The policy of extending a nation's authority by territorial acquisition or by the establishment of economic and political hegemony over other nations.
+*'''[[w:Individualism|Individualism]]''' - Emphasis of the individual as opposed to a group; humanism ''(Renaissance)''.
+*'''[[w:Innocent III|Innocent III]]''' - Pope who organized the Fifth Crusade (1217); began the Papacy's interference in European affairs.
+*'''[[w:Easter Rising|Irish Easter Rebellion]]'''  ''(Easter Monday, 1916)'' - An unsuccessful rebellion against British rule in Ireland.
+*'''[[w:Iron Curtain|Iron Curtain]]''' - Boundary which separated Western and Eastern Europe during the Cold War.
+*'''[[w:Isaac Newton|Isaac Newton]]''' ''(1643-1727)'' -  English physicist, mathematician, astronomer, and philosopher; credited for universal gravitation, laws of motion, and calculus ''(Scientific Revolution)''.
+
+==J==
+*'''[[w:James Hargreaves|James Hargreaves]]''' ''(1720-1778)'' - English inventor of the spinning jenny in 1764.
+*'''[[w:James Watt|James Watt]]''' ''(1736-1819)'' - Scottish engineer who improved the steam engine, a catalyst of the Industrial Revolution.
+*'''[[w:Jan Hus|Jan Hus]]''' ''(1369-1415)'' - Founder of the Hussites, with reform goals similar to those of John Wyclif; author of ''On the Church'', criticizing the Church; was burned at the stake.
+*'''[[w:Jean-Jacques Rousseau|Jean-Jacques Rousseau]]''' ''(1712-1778)'' - Swiss-French philosopher and political theorist; "noble savage" idea that man is good by nature but corrupted by society.
+*'''[[w:Jesuits|Jesuits]]''' - ''see Society of Jesus''
+*'''[[w:Joan of Arc|Joan of Arc]]''' ''(1412-1431)'' - Peasant girl who defended an English siege on Orléans during the Hundred Years' War; was captured and burned as a heretic.
+*'''[[w:Johann Tetzel|Johann Tetzel]]''' ''(1465-1519)'' - Dominican priest known for selling indulgences ''(Protestant Reformation)''.
+*'''[[w:John Calvin|John Calvin]]''' ''(1509-1564)'' - Founder of Calvinism in Geneva, Switzerland ''(Protestant Reformation)''.
+*'''[[w:John Kay|John Kay]]''' ''(1704-1780)'' - British inventor of the flying shuttle for weaving, a catalyst of the Industrial Revolution.
+*'''[[w:John Knox|John Knox]]''' ''(1505-1572)'' - A Protestant reformer who founded Presbyterianism in Scotland ''(Protestant Reformation)''.
+*'''[[w:John Locke|John Locke]]''' ''(1632-1704)'' - An English philosopher of the Enlightenment who wrote about "government with the consent of the governed" and man's natural rights; provided justification for the ''Glorious Revolution''.
+*'''[[w:John Wyclif|John Wyclif]]''' ''(1328-1384)'' - Initiator of the first English translation of the Bible, an important step toward the Protestant Reformation.
+*'''[[w:Joseph Joffre|Joseph Joffre, General]]''' ''(1852-1931)'' - Catalan French general; helped counter the Schlieffen Plan through retreat and counterattack at the First Battle of the Marne.
+
+==K==
+*'''[[w:Karl Marx|Karl Marx]]''' ''(1818-1883)'' - An influential German political theorist, whose writing on class conflict formed the basis of the communist and socialist movements.
+*'''[[w:Khruschev|Khruschev]]''' - See ''Nikita Khrushchev''
+*'''[[w:Kristallnacht|Kristallnacht]]''' ''(1938)'' - A massive nationwide pogrom in Germany, directed at Jewish citizens throughout the country.
+*'''[[w:Kulturkampf|Kulturkampf]]''' ''(Cultural Fight)'' - Attempt by Chancellor Otto von Bismarck to reduce Catholic influence in the early years of the 1871 German Empire.
+
+==L==
+*'''[[w:Laissez-Faire|Laissez-Faire]]''' - Libertarian philosophy of pure capitalism, without regulation of trade ''(Enlightenment)''.
+*'''[[w:Law of Maximum Général|Law of Maximum Général]]''' - A comprehensive program of wage and price controls in Revolutionary France.
+*'''[[w:Lay|Lay]]''' - in Catholicism, all non-clergy persons.
+*'''[[w:Lay investiture|Lay investiture]]''' - The induction of clerics by a king (a layman).
+*'''[[w:Vladimir Lenin|Lenin, Vladimir]]''' ''(1870-1924)'' - The leader of the Bolshevik party and the first Premier of the Soviet Union; enacted the New Economic Policy.
+*'''[[w:Leonardo da Vinci|Leonardo da Vinci]]''' ''(1452-1519)'' - Italian Renaissance architect, inventor, engineer, sculptor, and painter; most known for ''The Last Supper'' and ''Mona Lisa''; the archetype of the "Renaissance man."
+*'''[[w:Leopold III|Leopold III]]''' ''(1835–1909)'' - King of Belgium; founder of the Congo Free State, a private project to extract rubber and ivory.
+*'''[[w:Levée en masse|Levée en masse]]''' - French term for mass conscription, used to mobilize armies during the French Revolutionary Wars.
+*'''[[w:Lord|Lord]]''' - The owner of land who grants a fief to a vassal ''(feudal system)''.
+*'''[[w:Lorenzo de' Medici|Lorenzo de' Medici]]''' ''(1449-1492)'' - Ruler of the Florentine Republic during the Renaissance; Christian supporter of Platonism and humanism.
+*'''[[w:Louis Napoleon Bonaparte|Louis Napoleon Bonaparte]]''' ''(1808-1873)'' - The nephew of the Emperor Napoleon I of France; member of the Carbonari in his youth; elected President of the Second Republic of France in 1848; reigned as Emperor Napoleon III of the Second French Empire from 1852 to 1870.
+
+==M==
+*'''[[w:Machiavellian|Machiavellian]]''' - Having the qualities seen by Niccolò Machiavelli as ideal for a ruler; using ruthless authoritarian tactics to maintain power.
+*'''[[w:Manchurian Incident|Manchurian Incident]]''' ''(1931)'' - Japan's military accused Chinese dissidents of blowing up a sectin of a Japanese railroad in Manchuria, thus providing an excuse for the Japanese annexation of Manchuria.
+*'''[[w:Mannerism|Mannerism]]''' - Art after the High Renaissance in reaction to it, using exaggeration or distortion instead of balance and proportion.
+*'''[[w:Manor|Manor]]''' - The local jurisdiction of a lord over which he has legal and economic power ''(feudalism)''.
+*'''[[w:Marquis de Condorcet|Marquis de Condorcet]]''' ''(1743-1794)'' - French philosopher and mathematician, inventor of the Condorcet method, a voting system.
+*'''[[w:Marshall Plan|Marshall Plan]]''' - The primary plan of the United States for rebuilding the allied countries of Europe and repelling communism after World War II.
+*'''[[w:Martin Luther|Martin Luther]]''' ''(1483-1546)'' - German theologian and Augustinian monk who began Lutheranism and initiated the Protestant Reformation.
+*'''[[w:Meiji Restoration|Meiji Restoration]]''' ''(1866-1869)'' - Revolution in Japan; replaced the Tokugawa shogunate with imperial rule, and modernized the feudal country; provoked by the opening of Japan's ports to the West.
+*'''[[w:Mein Kampf|Mein Kampf]]''' ''(My Struggle)'' - A book written by Adolf Hitler, combining elements of autobiography with an exposition of Hitler's political ideology of nazism.
+*'''[[w:Mensheviks|Mensheviks]]''' - A faction of the Russian revolutionary movement formed 1903 by followers of Julius Martov, who believed in a large party of activists.
+*'''[[w:Mercantilism|Mercantilism]]''' - The economic theory that a country's economic prosperity depends on its supply of gold and silver, and that a country should export more than it imports.
+*'''[[w:Metternich|Metternich]]''' ''(1773-1858)'' - Austrian foreign minister during and after the Era of Napoleon.
+*'''[[w:Michaelangelo|Michaelangelo]]''' ''(1475-1564)'' - Renaissance painter, sculptor, poet and architect; most known for the fresco ceiling of the Sistine Chapel.
+*'''[[w:Obshchina|Mir]]''' - In Russian, "peace," Connotes "community."  '''(ed: relate this to the subject????)'''
+*'''[[w:Monasticism|Monasticism]]''' - Complete devotion to spiritual work.
+*'''[[w:Munich Agreement|Munich Agreement]]''' ''(1938)'' - An agreement regarding the Munich Crisis; discussed the future of Czechoslovakia and ended up surrendering much of that state to Nazi Germany, standing as a major example of appeasement.
+
+==N==
+*'''[[w:Napoléon Bonaparte|Napoléon Bonaparte]]''' ''(1769-1821)'' - General and politician of France who ruled as First Consul (1779–1804) and then as Emperor (1804–1814).
+*'''[[w:Napoleonic code|Napoleonic code]]''' - French code of civil law, established by Napoléon on March 21, 1804, to reform the French legal system in accordance with the principles of the French Revolution.
+*'''[[w:National Socialist German Workers' Party|National Socialist German Workers' Party]]''' - The Nazi party which was led to power in Germany by Adolf Hitler in 1933.
+*'''[[w:Nationalism|Nationalism]]''' - Ideology which sustains the nation as a concept of common identity among groups of people.
+*'''[[w:NATO|NATO (North Atlantic Treaty Organization)]]''' ''(1769-1821)'' - An international organization for collective security established in 1949, in support of the North Atlantic Treaty signed in Washington, DC, on 4 April 1949.
+*'''[[w:Nazi-Soviet Non-Aggression Pact|Nazi-Soviet Non-Aggression Pact]]''' ''(1939)'' - A non-aggression treaty between foreign ministers Ribbentrop of Germany (Third Reich) and Molotov of Russia (Soviet Union).
+*'''[[w:Neo-platonism|Neo-platonism]]''' - Philosophy based on the teachings of Plato, which resurfaced during the Renaissance.
+*'''[[w:Neville Chamberlain|Neville Chamberlain]]''' ''(1869-1940)'' - British Prime Minister who maintained a policy of appeasement toward Nazi Germany.
+*'''[[w:New Economic Policy|New Economic Policy]]''' ''(NEP)'' ''(1921)'' - Lenin's system of economic reforms which restored private ownership to some parts of the economy.
+*'''[[w:New Model Army|New Model Army]]''' - An army of professional soldiers led by trained generals; formed by Roundheads upon passage of the Self-denying Ordinance in 1645; became famous for their Puritan religious zeal ''(English Civil War)''.
+*'''[[w:New Monarchs|New Monarchies]]''' - The states whose rulers in the 15th century began authoritarian rule using Machiavellian tactics ''(Northern Renaissance).
+*'''[[w:Niccolò Machiavelli|Niccolò Machiavelli]]''' ''(1469-1527)'' - Florentine political philosopher; author of ''The Prince'' ''(Renaissance)''.
+*'''[[w:Nicolaus Copernicus|Nicolaus Copernicus]]''' ''(1473-1543)'' - Astronomer and mathematician who developed the heliocentric theory of the solar system ''(Scientific Revolution)''.
+*'''[[w:Nietzsche's Superman|Nietzsche's Superman]]''' ''(Übermensch)'' -  Concept that the strong and gifted should dominate over the weak.
+*'''[[w:Night of the Long Knives|Night of the Long Knives]]''' ''(1934)'' - A purge ordered by Adolf Hitler of potential political rivals in the Sturmabteilung.
+*'''[[w:Nihilism|Nihilism]]''' - Philosophy viewing the world and human existence as without meaning or purpose.
+*'''[[w:Nikita Khrushchev|Nikita Khrushchev]]''' - Leader of the Soviet Union after Stalin's death, from 1953 until 1964.
+*'''[[w:NKVD|NKVD]]''' - An agency best known for its function as secret police of the Soviet Union; also handled other matters such as transport, fire guards, border troops, etc.
+*'''[[w:No man's land|No man's land]]''' ''(World War I)'' - In trench warfare, land between two opposing trenches which provides no cover.
+
+==O==
+*'''[[w:October Revolution|October Revolution]]''' ''(1917)'' - The second stage of the Russian Revolution of 1917, led by Leon Trotsky; the first officially communist revolution, also known as the ''Bolshevik Revolution''.
+*'''[[w:Ancien Régime|Old Regime]]''' - see ''Ancien Régime''.
+*'''[[w:Oliver Cromwell|Oliver Cromwell]]''' ''(1599-1658)'' - Military leader and politician who led an overthrow of the British monarchy in the English Civil War; established the Commonwealth of England over which he ruled as Lord Protector.
+*'''[[w:Open-Door Policy|Open-Door Policy]]''' - Maintenance of equal commercial and industrial rights for all nations in China after the Opium War.
+*'''[[w:Opium War|Opium War]]''' ''(1834-1860)'' - Two wars between Britain and China over a Chinese attempt to eliminate the opium trade and reduce foreign influence within its borders.
+*'''[[w:Otto von Bismarck|Otto von Bismarck]]''' ''(1815-1898)'' - Prime Minister of Prussia who unified Germany and became the Chancellor of the German Empire.
+
+==P==
+*'''[[w:Pablo Picasso|Pablo Picasso]]''' ''(1881-1973)'' - Founder, along with Georges Braque, of Cubism.
+*'''[[w:Pagan|Pagan]]''' - Of or relating to classical, non-Christian religions.
+*'''[[w:Paris Commune|Paris Commune]]''' ''(1871)'' - Socialist government briefly ruling Paris, formed by a civil uprising of post-Franco-Prussian War revolutionaries.
+*'''[[w:Parlements|Parlements]]''' - Law courts of the ancien régime in France.
+*'''[[w:Parliamentarians|Parliamentarians]]''' - Anything associated with a parliament; sometimes refers to ''Roundheads'' ''(English Civil War)''.
+*'''[[w:Paris Peace Conference|Paris Peace Conference]]''' ''(1919)'' - A six-month international conference between the Allied and Associated Powers and their former enemies; proposed Treaty of Versailles.
+*'''[[w:Paul von Hindenburg|Paul von Hindenburg, General]]''' ''(1847-1934)'' - German war general; Reich President of Germany (1925–1934). 
+*'''[[w:Peace of Westphalia|Peace of Westphalia]]''' ''(1648)'' - A series of treaties ending the Thirty Years' War.
+*'''[[w:Peasants' War|Peasants' War]]''' ''(1524-1526)'' - A mass of economic and religious revolts in Germany ''(Protestant Reformation)''.
+*'''[[w:Peninsular War|Peninsular War]]''' ''(1808-1814)'' - A major conflict during the Napoleonic Wars, fought in the Iberian Peninsula; Spain, Portugal, and Britain vs. France.
+*'''[[w:Perspective|Perspective]]''' - Artistic technique used to give a painting the appearance of having three dimensions by depicting foreground objects larger than those of the background ''(Renaissance)''.
+*'''[[w:Philosophes|Philosophes]]''' - A group of French philosophers of the Enlightenment, including Jean-Jacques Rousseau and Voltaire.
+*'''[[w:Pierre-Joseph Proudhon|Pierre-Joseph Proudhon]]''' ''(1809-1865)'' - French anarchist, most famously asserting "Property is theft."
+*'''[[w:Politburo|Politburo]]''' ''(Political Bureau)'' - The executive organization for Communist Parties.
+*'''[[w:Politique|Politique]]''' - A term used in the 16th century to describe a head of state who put politics and the nation's well being before religion.
+*'''[[w:Popolo|Popolo]]''' - The poor, working class of Italy ''(Renaissance)''.
+*'''[[w:Predestination|Predestination]]''' - The religious idea that God's decisions determine destiny; particularly prevalent in Calvinism ''(Protestant Reformation)''.
+*'''[[w:Presbyterianism|Presbyterianism]]''' - A Protestant church based on the teachings of John Calvin and established in Scotland by John Knox ''(Protestant Reformation)''.
+*'''[[w:Proletariat|Proletariat]]''' - A lower social class; term used by Karl Marx to identify the working class.
+*'''[[w:Protectorate|Protectorate]]''' - A relationship of protection and partial control assumed by a superior power over a dependent country or region; the protected country or region.
+*'''[[w:Protestant Wind|Protestant Wind]]''' - Term used to refer to one of two incidents in which weather favored Protestants in battle: 1) the storm which wrecked the Spanish Armada, preventing an invasion of England (1588); 2) the favorable winds that enabled William III to land in England and depose the Catholic King James II (1688).
+
+==Q==
+*'''[[w:Queen Victoria|Queen Victoria]]''' ''(1819–1901)'' - Queen of the United Kingdom, reigning from 1837 until her death, longer than any other British monarch. As well as being queen of the United Kingdom of Great Britain and Ireland, she was also the first monarch to use the title Empress of India. The reign of Victoria was marked by a great expansion of the British Empire. The Victorian Era was at the height of the Industrial Revolution, a period of great social, economic, and technological change in the United Kingdom.
+
+==R==
+*'''[[w:Raphael|Raphael]]''' ''(1483-1520)'' - Florentine painter and architect of the Italian High Renaissance.
+*'''[[w:Father Grigori Rasputin|Rasputin, Father Grigori]]''' ''(1872-1916)'' - Russian mystic having great influence over the wife of Tsar Nicholas II's wife Alexandra, ultimately leading to the downfall of the Romanov dynasty and the Bolshevik Revolution.
+*'''[[w:Rationalism|Rationalism]]''' - The philosophical idea that truth is derived from reason and analysis, instead of from faith and religious dogma (Renaissance).
+*'''[[w:Realism|Realism]]''' ''(Renaissance)'' - Depiction of images which is realistic instead of idealistic.
+*'''[[w:Realism|Realism]]''' ''(19th century)'' - Artistic movement originating in France as a reaction to ''Romanticism''; depiction of commonplace instead of idealized themes.
+*'''[[w:Realpolitick|Realpolitick]]''' ''(Politics of reality)'' - A term coined by Otto von Bismarck which refers to foreign politics based on practical concerns rather than theory or ethics.
+*'''[[w:Reconquista|Reconquista]]''' - The Spanish "reconquering" resulting in the removal of Jews and Muslims from the state, and a unification of Spain under Catholicism.
+*'''[[w:Red Guards|Red Guards]]''' ''(Russia)'' - The main strike force of the Bolsheviks, created in March 1917.
+*'''[[w:Reichstag|Reichstag]]''' ''(Imperial Diet)'' - Between 1871 and 1945, the German parliament.
+*'''[[w:Rembrandt van Rijn|Rembrandt van Rijn]]''' ''(1606-1669)'' - A baroque painter and engraver of the Netherlands during the Dutch Golden Age.
+*'''[[w:Renaissance|Renaissance]]''' - A cultural movement started in Italy in the 14th century marked by a rebirth of classic art and scientific learning of ancient Greece and Rome.
+*'''[[w:René Descartes|René Descartes]]''' ''(1596-1650)'' - Mathematician (inventor of the Cartesian coordinate system) and rationalist philosopher ("I think, therefore I am").
+*'''[[w:Risorgimento|Risorgimento]]''' ''(resurrection)'' - The gradual unification of Italy, culminating in the declaration of the Kingdom of Italy (1861) and the conquest of Rome (1870).
+*'''[[w:Rite of Spring|Rite of Spring]]''' - A ballet composed by Russian Igor Stravinsky; controversy due to its subject, pagan sacrifice.
+*'''[[w:Robert Owen|Robert Owen]]''' ''(1771-1858)'' - Welsh social reformer, father of the cooperative movement.
+*'''[[w:Robespierre|Robespierre]]''' ''(1758-1794)'' - One of the best known leaders of the French Revolutions; known as "the Incorruptible"; leader of the Committee of Public Safety.
+*'''[[w:Romanticism|Romanticism]]''' ''(18th century)'' - Artistic and intellectual movement, after the Enlightenment period, stressing strong emotion, imagination, freedom from classical correctness in art forms, and rebellion against social conventions.
+*'''[[w:Rotten borough|Rotten borough]]''' - A small British parliamentary constituency which could be 'controlled' by a patron and used to exercise undue and unrepresentative influence within parliament.
+*'''[[w:Roundheads|Roundheads]]''' - Puritans under Oliver Cromwell in the English Civil War; named after the round helmets they wore; also known as ''Parliamentarians''.
+*'''[[w:Royal Society of London|Royal Society of London]]''' ''(1660)'' - An institution of learning committed to open content, the free availability and flow of information.
+*'''[[w:Royalists|Royalists]]''' - An adherent of a monarch or royal family; sometimes refers to ''Cavaliers'' ''(English Civil War)''.
+*'''[[w:Russian Civil War|Russian Civil War]]''' ''(1918-1920)'' - Conflict between communists and monarchists, after the Russian Revolution of 1917.
+
+==S==
+*'''[[w:Saint Bartholomew's Day Massacre|Saint Bartholomew's Day Massacre]]''' ''(1572)'' - A wave of Catholic mob violence against the Huguenots, lasting for several months.
+*'''[[w:Sans-culottes|Sans-culottes]]''' ''(without knee-breeches)'' - Term referring to the ill-clad and ill-equipped volunteers of the French Revolutionary army.
+*'''[[w:Schleswig-Holstein|Schleswig-Holstein]]''' - A region of northern Germany which Denmark surrendered to Otto von Bismarck in 1865.
+*'''[[w:Schutzstaffel|Schutzstaffel (SS)]]''' ''(Protective Squadron)'' - A large paramilitary organization that belonged to the Nazi party.
+*'''[[w:Secularism|Secularism]]''' - Concern with worldly ideas, as science and rationalism, instead of religion and superstition ''(Renaissance)''.
+*'''[[w:Self-denying Ordinance|Self-denying Ordinance]]''' ''(1645)'' - A Bill passed by English Parliament, depriving members of Parliament from holding command in the army or navy, to promote professionalism in the armed forces; aided creation of the New Model Army ''(English Civil War)''.
+*'''[[w:Sepoy mutiny|Sepoy mutiny]]''' ''(1857–1858)'' - Rebellions against British colonial rule in India; caused the end of the British East India Company's rule in India, and led to a century of direct rule of India by Britain.
+*'''[[w:Sigmund Freud|Sigmund Freud]]''' ''(1856-1939)'' - Austrian neurologist credited for psychoanalysis and the theory of unconscious motives.
+*'''[[w:Simony|Simony]]''' - The ecclesiastical crime of paying for offices or positions in the hierarchy of a church ''(Protestant Reformation)''.
+*'''[[w:Sir Richard Arkwright|Sir Richard Arkwright]]''' ''(1732-1792)'' - English inventor of the Water Frame, a water-powered cotton mill.
+*'''[[w:Sir Thomas More|Sir Thomas More]]''' - Author of ''Utopia'', a novel which extols the hypothetical ideal society, by the Northern Renaissance ideals of humanism and Christianity.
+*'''[[w:Social Darwinism|Social Darwinism]]''' - The application of Darwinism to the study of human society, specifically a theory in sociology that individuals or groups achieve advantage over others as the result of genetic or biological superiority.
+*'''[[w:Society of Jesus|Society of Jesus]]''' - A Roman Catholic Order founded in 1534 by Ignatius of Loyola ''(Protestant Reformation)''.
+*'''[[w:Spanish Civil War|Spanish Civil War]]''' ''(1936–1939)'' - The result of the complex political and even cultural rift in Spain.
+*'''[[w:Sphere of Influence|Sphere of Influence]]''' - A territorial area over which political or economic influence is wielded by one nation.
+*'''[[w:Joseph Stalin|Stalin, Joseph]]''' ''(1879-1953)'' - Bolshevik revolutionary who ruled the Soviet Union after the death of Lenin; responsible for the Great Purge and five year plans.
+*'''[[w:States-General|States-General]]''' - ''(see Estates-General)''.
+*'''[[w:Subsistence|Subsistence]]''' - Production of food only in quantities needed for survival, without the creation of surpluses.
+*'''[[w:Sudetenland|Sudetenland]]''' - The region inhabited mostly by Sudeten Germans in various places of Bohemia, Moravia, and Silesia; became part of Czechoslovakia in 1945.
+*'''[[w:Suez Canal|Suez Canal]]''' ''(constructed 1854-1869)'' - A canal in Egypt between the Mediterranean and Red Seas, allowing access between Europe and Asia.
+
+==T==
+*'''[[w:Tabula rasa|Tabula rasa]]''' (Blank slate) - John Locke's idea that humans are born with no innate ideas, and that identity is defined by events after birth.
+*'''[[w:Taille|Taille]]''' - A direct land tax on the French peasantry in ancien régime France.
+*'''[[w:T.E. Lawrence|T.E. Lawrence]]''' ''(1888-1935)'' - also known as Lawrence of Arabia; a British liaison officer during the Arab Revolt of 1916–1918.
+*'''[[w:Tennis Court Oath|Tennis Court Oath]]''' ''(1789)'' - A pledge by France's Third Estate to continue to meet until a constitution had been written; may be considered the birth of the French Revolution.
+*'''[[w:Thirty Years' War|Thirty Years' War]]''' ''(1618-1648)'' - Conflict principally taking place in the Holy Roman Empire involving a religious conflict between Protestants and Catholics, fought for the self-preservation of the Hapsburg dynasty.
+*'''[[w:Thomas Hobbes|Thomas Hobbes]]''' ''(1588-1679)'' - English political philosopher advocating an authoritarian version of the social contract (''absolutism'').
+*'''[[w:Thomas Malthus|Thomas Malthus]]''' ''(1766–1834)'' - English economist who, in ''An Essay on the Principle of Population'', predicted that increasing population growth would cause a massive food shortage.
+*'''[[w:Thomas Newcomen|Thomas Newcomen]]''' ''(1664-1729)'' - English inventor of the Newcomen engine, a steam engine for pumping water out of mines.
+*'''[[w:Tory|Tory]]''' - A member of the British Conservative party.
+*'''[[w:Totalitarianism|Totalitarianism]]''' - A form of government in which the political authority exercises absolute and centralized control over all aspects of life.
+*'''[[w:Treaties of Tilsit|Treaties of Tilsit]]''' ''(1807)'' - Treaties ending war between Russia and France; began a powerful secret alliance between the two countries.
+*'''[[w:Treaty of Brest-Litovsk|Treaty of Brest-Litovsk]]''' ''(1918)'' - Peace treaty which marked Russia's exit from World War I.
+*'''[[w:Treaty of Versailles|Treaty of Versailles]]''' ''(1919)'' - Peace treaty created by the Paris Peace Conference; which officially ended World War I.
+*'''[[w:Trotsky, Leon|Trotsky, Leon]]''' ''(1879-1940)'' - Bolshevik revolutionary, early Soviet Union politician, and founding member of the Politburo; expelled from the Communist Party after a power struggle with Stalin.
+*'''[[w:Truman Doctrine|Truman Doctrine]]''' ''(1947)'' - Harry S. Truman's statement initiating the U.S. policy of containment toward Russia.
+
+==U==
+*'''[[w:Ulrich Zwingli|Ulrich Zwingli]]''' ''(1484-1531)'' - Founder of Zwinglianism in the Zürich, Switzerland; leader of the Swiss Reformation ''(Protestant Reformation)''.
+*'''[[w:Usury|Usury]]''' - Charging a fee generally in the form of interest on loans; forbidden by most religious doctrines ''(Protestant Reformation)''. Usury was forbidden in the Catholic Church, so Jews became wealthy, successful merchants
+*'''[[w:Utopian Socialism|Utopian Socialism]]''' - The socialist ideals of creating a perfect communist society. Writers such as Charles Fourier, Henri de Saint-Simon and Robert Owen were prominent Utopian Socialists.
+
+==V==
+*'''[[w:Vassal|Vassal]]''' - The tenant of land who receives a fief in exchange for knightly service ''(feudalism)''.
+*'''[[w:Vernacular|Vernacular]]''' - The standard, native language of a region (generally as opposed to Latin).
+*'''[[w:Virtu|Virtu]]''' - Humanist value of the Renaissance emphasizing a nobility of spirit and action, stressing an individual's dignity and worth; replaced the chivalrous Medieval value of humility.
+*'''[[w:Voltaire|Voltaire]]''' ''(1694-1778)'' - French deist philosopher, author of ''Candide'', which sarcastically attacks religious and philosophical optimism ''(Enlightenment)''.
+
+==W==
+*'''[[w:War of the Three Henrys|War of the Three Henrys]]''' ''(1584-1598)'' - A series of three civil wars in France, also known as the Huguenot Wars; fought between the Catholic League and the Huguenots.
+*'''[[w:Wars of the Roses|Wars of the Roses]]''' ''(1455-1487)'' - Intermittent civil war fought over the throne of England between the House of Lancaster and the House of York.
+*'''[[w:Warsaw Pact|Warsaw Pact]]''' ''(1455-1487)'' - An organization of Central and Eastern European Communist states. It was established in 1955 to counter the threat from the NATO alliance.
+*'''[[w:Weimar Republic|Weimar Republic]]''' ''(1919-1933)'' - The first attempt at liberal democracy in Germany; named after the city of Weimar, where the new constitution was written.
+*'''[[w:Western Schism|Western Schism]]''' ''(1378)'' - Split within the Catholic Church at the end of the Avignon Papacy.
+*'''[[w:Whig|Whig]]''' - A member of the British Liberal Democrat party.
+*'''[[w:White-collar|White-collar]]''' - Class of labor performing less "laborious" tasks and are more highly paid than blue-collar manual workers. 
+*'''[[w:White Man’s Burden|White Man’s Burden]]''' - The concept of the white race's obligation to govern and impart it beliefs upon nonwhite people; often used to justify European colonialism.
+*'''[[w:William and Mary|William and Mary]]''' - King William III and Queen Mary II; jointly ruled England and Scotland after the Glorious Revolution of 1688; they replaced the absolutist King James II and ruled as constitutional monarchs.
+*'''[[w:William Gladstone|William Gladstone]]''' ''(1809-1898)'' - A British Liberal politician and Prime Minister (1868–1874, 1880–1885, 1886 and 1892–1894), a notable political reformer, known for his populist speeches, and was for many years the main political rival of Benjamin Disraeli.
+
+==X== 
+* X-ray - first systematically studied by Wilhelm Conrad Röntgen in 1895. 
+
+==Y==
+*'''[[w:Yekaterinburg|Yekaterinburg]]''' - The location at which the family of Czar Nicholas II was murdered by Bolsheviks
+
+==Z==
+*'''[[w:Zimmermann Telegram|Zimmermann Telegram]]''' ''(1917)'' - Message sent by German Arthur Zimmermann, proposing that Mexico ally with Germany against the United States; hastened U.S. entry into World War I.
+
+<noinclude>{{EuropeanHistoryTOC|mini}}</noinclude>
+
+[[File:Zakupy1853.jpg|thumb|right|Schloß Reichstadt, Lithograph 1853]]
+'''The [[Zákupy|Reichstadt]] agreement''' was an agreement made between [[Austria-Hungary]] and [[Russia]] in July 1876, who were at that time in an alliance with each other and [[German Empire|Germany]] in the [[League of the Three Emperors]], or ''Dreikaiserbund''. Present were the Russian and Austro-Hungarian emperors together with their foreign ministers, [[Alexander Gorchakov|Prince Gorchakov]] of Russia and [[Count Andrassy]] of Austria-Hungary. The closed meeting took place on July 8 in the Bohemian city of Reichstadt (now [[Zákupy]]). They agreed on a common approach to the solution of the [[Eastern question]], due to the unrest in the [[Ottoman Empire]] and the interests of the two major powers in the Balkans. They discussed the likely [[Russo-Turkish War (1877–1878)|Russo-Turkish War]] of 1877–1878, its possible outcomes and what should happen under each scenario.
+
+The later [[Budapest Convention 1877|Budapest Convention]] of 1877 confirmed the main points, but when the war concluded with the [[Treaty of San Stefano]] in 1878, the terms of the treaty were quite different leading to Austrian insistence on convening a revision at the [[Congress of Berlin]] later that year. These events laid the background for the subsequent [[Bulgarian Crisis (1885–1888)|Bulgarian Crisis]] of 1885-1888, and ultimately [[World War I]].<ref name=ragsdale>{{cite book |url=https://books.google.com/books?id=bwvllKkPQtYC |editor-first=Hugh |editor-last=Ragsdale |title=Imperial Russian Foreign Policy |publisher=Woodrow Wilson Center Press. Cambridge University Press |year=1993 |isbn=9780521442299}}</ref><ref>{{cite book |url=https://books.google.com/books?id=dr7Yz98twWQC |first=Frederick |last=Kellogg |title=The Road to Romanian Independence |publisher=Purdue University Press |year=1995 |isbn=9781557530653}}</ref><ref>[http://isanet.ccit.arizona.edu/noarchive/berlincongress.html Mikulas Fabry. The Idea of National Self-Determination and The Recognition of New States at The Congress Of Berlin (1878)] {{webarchive|url=https://web.archive.org/web/20080621140434/http://isanet.ccit.arizona.edu/noarchive/berlincongress.html |date=2008-06-21 }}. ISA Annual Convention, New Orleans, March 24-27, 2002</ref><ref>{{cite book |url=https://archive.org/stream/secrettreatiesof02pribuoft/secrettreatiesof02pribuoft_djvu.txt |editor-last=Pribram |editor-first=Alfred |year=1921 |title=The Secret Treaties of Austria-Hungary |volume=2 |publisher=Harvard University Press}}</ref>
+
+== Format ==
+The negotiations took place in a private and almost informal setting. It is significant that the results of the meeting were not written down, so that the Austrian and Russian view of what was agreed on differed significantly. There was neither a signed formal convention nor even a signed protocol. The minutes were dictated separately by both Andrassy and by Gorchakov suggesting that neither side really trusted the other side. The extent of agreed Austrian annexation in Bosnia and Herzegovina has remained controversial. It was these inconsistencies that necessitated further discussions at the Constantinople Conference and the subsequent [[Budapest Convention 1877|Budapest Convention]], though these largely confirmed or amended the Reichstadt discussions.
+
+== Terms of the agreement ==
+The Balkan Christians would gain a measure of independence.
+
+Austria would allow Russia to make gains in [[Bessarabia]] and the [[Caucasus]].
+
+Russia would allow Austria to gain [[Bosnia (region)|Bosnia]].
+
+Russia and Austria agree not to create a big Slavic state in the Balkans.
+
+== Implications ==
+This effectively meant that Austria was assuring Russia that to stay out of a war between Russia and the [[Ottoman Empire]]. It also meant that the Austrians and the Russians were agreeing on how the [[Balkans]] would be split up in the case of a Russian victory.
+
+<gallery>
+image:Andrássy Gyula 1871.jpg|Andrassy
+image:Franz Joseph 1865.jpg|Franz Joseph
+image:Alexander II 1870 by Sergei Lvovich Levitsky.jpg|Alexander II.
+image:A.M.Gorchakov.jpg|Gorchakov
+</gallery>
+
+== See also ==
+* [[History of Austria]]
+* [[Bulgarian Crisis (1885–1888)]]
+
+== References ==
+{{Reflist}}
+
+== Bibliography ==
+* [https://books.google.com/books?id=Ylz4fe7757cC Crampton, R. J. ''A Concise History of Bulgaria''. Cambridge University Press 1997]
+* [http://www.cambridge.org/gb/knowledge/isbn/item1146483/?site_locale=en_GB Beller, Steven. ''A Concise History of Austria''. Cambridge University Press 2007] {{ISBN|9780521473057}}
+
+{{Treaties of Hungary}}
+{{Great Eastern Crisis}}
+
+[[Category:History of the Balkans]]
+[[Category:1876 treaties]]
+[[Category:1876 in the Russian Empire]]
+[[Category:1876 in Austria-Hungary]]
+[[Category:Treaties of Austria-Hungary]]
+[[Category:Treaties of the Russian Empire]]
+[[Category:Austria-Hungary–Russia relations]]
+[[Category:Bilateral treaties of Russia]]
+
+The '''Three Caesars' Alliance''' or '''Union of the Three Emperors''' ({{lang-de|Dreikaiserbund}}, {{lang-ru|Союз трёх императоров}}) was an alliance between the [[German Empire|German]], [[Russian Empire|Russian]] and [[Austro-Hungarian Empire]]s, from 1873 to 1887. Chancellor [[Otto von Bismarck]] took full charge of German foreign policy from 1870 to his dismissal in 1890.  His goal was a peaceful Europe, based on the balance of power.  Bismarck feared that a hostile combination of Austria, France and Russia would crush Germany.  If two of them were allied, then the third would ally with Germany only if Germany conceded excessive demands.  The solution was to ally with two of the three.  In 1873 he formed the League of the Three Emperors, an alliance of the Kaiser of Germany, the Tsar of Russia, and the Kaiser of Austria-Hungary.  Together they would control [[Eastern Europe]], making sure that restive ethnic groups such as the Poles were kept in control.  It aimed at neutralizing the rivalry between Germany’s two neighbors by an agreement over their respective spheres of influence in the Balkans and at isolating Germany’s enemy, France. The Balkans posed a more serious issue, and Bismarck's solution was to give Austria predominance in the western areas, and Russia in the eastern areas.<ref>Raymond James Sontag, ''European Diplomatic History: 1871–1932''  (1933) pp. 3–58</ref>
+
+The first League of the Three Emperors was in effect from 1873 to 1878. A second one was established June 18, 1881, and lasted for three years. It was renewed in 1884 but lapsed in 1887. Both alliances ended because of continued strong conflicts of interest between Austria-Hungary and Russia in the Balkans. The second treaty provided that no territorial changes should take place in the Balkans without prior agreement and that Austria could annex Bosnia and Herzegovina when it wished; in the event of war between one party and a great power not party to the treaty, the other two parties were to maintain friendly neutrality.
+
+Bismarck was able temporarily to preserve the tie with Russia in the [[Reinsurance Treaty]] of 1887; but, after his dismissal, this treaty was not renewed, and a Franco-Russian alliance developed.<ref>"Dreikaiserbund". Encyclopædia Britannica. Encyclopædia Britannica Online.
+
+Encyclopædia Britannica Inc., 2016. Web. 10 Feb. 2016
+
+<https://www.britannica.com/event/Dreikaiserbund>.
+</ref>
+
+== First agreement (1873) ==
+[[File:Otto von Bismarck.JPG|thumb|100px|right|187px|Bismarck]]
+On 22 October 1873, Bismarck negotiated an agreement between the monarchs of [[Austria–Hungary]], [[Russian Empire|Russia]] and [[German Empire|Germany]]. The alliance sought to resurrect the [[Holy Alliance]] of 1815 and act as a bulwark against radical sentiments that the conservative rulers found unsettling.<ref>[[#refGildea2003|Gildea 2003]], p. 237.</ref> It was preceded by the [[Schönbrunn Palace|Schönbrunn]] Convention, signed by Russia and Austria–Hungary on 6 June 1873.
+
+== Policy ==
+
+Bismarck often led the League as it assessed challenges, centred on maintaining the [[balance of power in international relations|balance of power]] among the states involved and Europe at large. The cornerstone of his political philosophy included preserving the status quo and avoiding war. Despite German victory in the [[Franco-Prussian War]] of 1870-1871, violence remained fresh in the new state's memory and made Germany reluctant to antagonize France but keen as ever to limit its power.
+
+According to the coalition, radical socialist bodies like the [[First International]] represented one of the other key threats to regional stability and dominance. The League actively opposed the expansion of its influence.<ref>{{cite book|last=Henig|first=Ruth Beatrice|title=The Origins of the First World War|year=2002|publisher=Routledge|isbn=0-415-26185-6|page=3}}</ref>
+
+The League also met crisis in the [[Eastern Europe]], where [[Principality of Bulgaria|Bulgarian]] unrest elicited violent reaction from the [[Ottoman Empire|Ottoman]] forces there, which, in turn, met with horror from observing states. The account of the insurrection from an Englishman, Sir [[Edwin Pears]],<ref>Sir Edwin Pears, Forty Years in Constantinople, 1873–1915, (New York: D. Appleton and Co., 1916), pp. 16–19, reprinted in Alfred J. Bannan and Achilles Edelenyi, eds., Documentary History of Eastern Europe, (New York: Twayne Publishers, 1970), pp. 191–94. found at [http://www.fordham.edu/halsall/mod/1876massacre-bulgaria.html], last visited June 24, 2011</ref> describes the gruesome atrocities and reveals British surprise at their extent.
+
+== First dissolution (1878) ==
+
+The collective initially disbanded in 1878 over territorial disputes in the [[Balkans]] as Austria-Hungary feared that Russian support for [[Principality of Serbia|Serbia]] might ultimately ignite irredentist passions in the [[Slav]] populations.<ref name="Gildea03pg240">[[#refGildea2003|Gildea 2003]], p. 240.</ref> Russian authorities, likewise, feared insurrection if a [[Pan-Slavist]] movement gained too much clout.<ref name="Gildea03pg240"/>
+
+The body’s first conclusion in 1879 gave way to the defensive [[Dual Alliance (1879)|Dual Alliance]] between Austria-Hungary and Germany to counter potential Russian aggression. In 1882, [[Italy]] joined the agreement to form the [[Triple Alliance (1882)|Triple Alliance]].<ref>[http://germanhistorydocs.ghi-dc.org/sub_document.cfm?document_id=1860]</ref>
+
+==Revival (1881–1887)==
+
+The 1878 [[Treaty of Berlin (1878)|Treaty of Berlin]] made Russia feel cheated of its gains of the [[Russo-Turkish War (1877–1878)|Russo-Turkish War]]. Its key role in European diplomacy was not, however, forgotten by Bismarck. A more formal Three Emperors' Alliance was concluded on 18 June 1881.<ref>[https://wwi.lib.byu.edu/index.php/The_Three_Emperors%27_League Text of the actual agreement], last visited Oct. 29, 2018</ref>
+
+It lasted for three years and was renewed at [[Skierniewice]] in 1884 but lapsed in 1887. Both alliances ended because of conflicts between Austria-Hungary and Russia in the Balkans. To preserve a common understanding with Russia, Germany signed the mutual [[Reinsurance Treaty]] in 1887.
+
+==See also==
+* [[International relations (1814–1919)]]
+
+==References==
+{{reflist}}
+
+==Sources==
+* {{cite book|last=Gildea|first=Robert|title=Barricades and Borders: Europe 1800–1914|year=2003|publisher=Oxford University Press|isbn=0-19-925300-5|page=237|ref=refGildea2003}}
+* Goriainov, Serge. "The End of the Alliance of the Emperors," ''American Historical Review'',  (1918) 23#2 pp. 324–29.  [https://www.jstor.org/stable/1836570 in JSTOR].
+* Langer, William. ''European Alliances and Alignments 1870–1890'' (2nd ed. 1950), pp. 197–212
+* Medlicott, W. N. "Bismarck and the Three Emperors' Alliance, 1881-87," ''Transactions of the Royal Historical Society'' Vol. 27 (1945), pp. 61-83 [http://www.jstor.org/stable/3678575 online]
+* Meyendorff, A. "Conversations of Gorkachov with Andrassy and Bismarck in 1872," ''The Slavonic and East European Review'' (1929) 8#23 pp. 400–08.  [https://www.jstor.org/stable/4202407 in JSTOR]
+* Schroeder, Paul W. "Quantitative Studies in the Balance of Power: An Historian's Reaction," ''The Journal of Conflict Resolution'' (1977) 21#1 pp. 3–22. [https://www.jstor.org/stable/173680 in JSTOR]
+* Taylor, A.J.P. ''The Struggle for Mastery in Europe 1848–1918'' (1954)
+{{Great power diplomacy}}
+
+[[Category:1873 in Austria-Hungary]]
+[[Category:1873 treaties]]
+[[Category:1873 in Germany]]
+[[Category:1873 in the Russian Empire]]
+[[Category:19th-century military alliances]]
+[[Category:Treaties of Austria-Hungary]]
+[[Category:Treaties of the German Empire]]
+[[Category:Treaties of the Russian Empire]]
+[[Category:Military alliances involving Austria-Hungary]]
+[[Category:Military alliances involving the German Empire]]
+[[Category:Military alliances involving Russia]]
+[[Category:Austria-Hungary–Germany relations]]
+[[Category:Austria-Hungary–Russia relations]]
+[[Category:Germany–Russia relations]]
+
+In [[diplomatic history]], the "'''Eastern Question'''" refers to the strategic competition and political considerations of the European [[Great Powers]] in light of the political and economic instability in the [[Ottoman Empire]] from the late 18th to early 20th centuries. Characterized as the "[[sick man of Europe]]", the relative weakening of the empire's military strength in the second half of the eighteenth century threatened to undermine the fragile [[Balance of power (international relations)|balance of power]] system largely shaped by the [[Concert of Europe]]. The Eastern Question encompassed myriad interrelated elements: Ottoman military defeats, Ottoman institutional insolvency, the ongoing Ottoman political and economic modernization programme, the rise of ethno-religious nationalism in its provinces, and Great Power rivalries.<ref>Theophilus C. Prousis. Review of Macfie, A. L., ''The Eastern Question, 1774-1923''. HABSBURG, H-Net Reviews. December, 1996. [http://www.h-net.org/reviews/showrev.php?id=712]</ref>
+
+The origin of the Eastern Question is normally dated to 1774, when the [[Russo-Turkish War (1768–1774)]] ended in defeat for the Ottomans. As the dissolution of the Ottoman Empire was believed to be imminent, the European powers engaged in a power struggle to safeguard their military, strategic and commercial interests in the Ottoman domains. [[Imperial Russia]] stood to benefit from the [[decline of the Ottoman Empire]]; on the other hand, [[Austria-Hungary]] and [[History of the United Kingdom|Great Britain]] deemed the preservation of the Empire to be in their best interests. The Eastern Question was put to rest after [[World War I]], one of the outcomes of which was the [[collapse of the Ottoman Empire|collapse and division of the Ottoman holdings]].
+==Background==
+{{main article|International relations of the Great Powers (1814–1919)}}
+[[File:Ottoman empire.svg|thumb|300px|At the height of its power (1683), the [[Ottoman Empire]] controlled territory in the Near East and North Africa, as well as Central and Southeastern Europe.]]
+
+The Eastern Question emerged as the power of the Ottoman Empire began to decline during the 18th century. The Ottomans were at the height of their power in 1683, when they lost the [[Battle of Vienna]] to the combined forces of the [[Polish–Lithuanian Commonwealth]] and Austria, under the command of [[John III Sobieski]]. Peace was made much later, in 1699, with the [[Treaty of Karlowitz]], which forced the Ottoman Empire to cede many of its Central European possessions, including those portions of Hungary which it had occupied. Its westward expansion arrested, the Ottoman Empire never again posed a serious threat to Austria, which became the dominant power in its region of Europe. The Eastern Question did not truly develop until the [[History of the Russo-Turkish wars|Russo-Turkish Wars]] of the 18th century.
+
+==Napoleonic Era==
+{{main article|Russo-Turkish War (1806–1812)|Anglo-Turkish War (1807–09)}}
+[[File:Athosbattle.jpg|thumb|300px|''Russian Fleet after the [[Battle of Athos]]'', by [[Aleksey Bogolyubov]] (1824–96)]]
+
+The Napoleonic era (1799–1815) brought some relief to the faltering Ottoman Empire. It distracted Russia from further advances. [[Napoleon I]] himself invaded Egypt, but his army was trapped there when the British sank the French fleet. A peace interlude in 1803 allowed the army to return to France.<ref>Juan Cole, ''Napoleon's Egypt: Invading the Middle East'' (2008)</ref>
+
+To secure his own domination and to render the rest of Europe virtually powerless, Napoleon established an alliance with Russia by concluding the [[Treaties of Tilsit|Treaty of Tilsit]] in 1807. Russia undertook to aid Napoleon in his war against Britain; in turn, the Emperor of Russia would receive the Ottoman territories of [[Moldavia]] and [[Wallachia]]. If the Sultan refused to surrender these territories, France and Russia were to attack the Empire, and the Ottoman domains in Europe were to be partitioned between the two allies.<ref>Michael S. Anderson, ''The Eastern Question, 1774–1923: A Study in International Relations'' (1966) ch 1</ref>
+
+The Napoleonic scheme threatened not only the Sultan, but also Britain, Austria and Prussia, which was almost powerless in the face of such a potent alliance. The alliance naturally proved accommodating to the Austrians, who hoped that a joint Franco-Russian attack, which would probably have utterly devastated the Ottoman Empire, could be prevented by diplomacy; but if diplomatic measures failed, the Austrian minister [[Klemens von Metternich]] decided that he would support the partition of the Ottoman Empire—a solution disadvantageous to Austria, but not as dangerous as a complete Russian takeover of Southeastern Europe.
+
+An attack on the Empire, however, did not come to pass, and the alliance concluded at Tilsit was dissolved by the [[French invasion of Russia]] in 1812. Following Napoleon's defeat by the Great Powers in 1815, representatives of the victors met at the [[Congress of Vienna]], but failed to take any action relating to the territorial integrity of the decaying Ottoman Empire. This omission, together with the exclusion of the Sultan from the [[Holy Alliance]], was interpreted by many as supportive of the position that the Eastern Question was a Russian domestic issue that did not concern any other European nations.<ref>{{cite book|author=Walter Alison Phillips|title=The confederation of Europe: a study of the European alliance, 1813–1823, as an experiment in the international organization of peace|url=https://books.google.com/books?id=K2BJAAAAMAAJ&pg=PA234|year=1914|publisher=Longmans, Green|pages=234–50}}</ref>
+
+==Serbian revolution==
+{{See also|Serbian revolution|}}
+<!-- Deleted image removed: [[File:Uprising.jpg|thumb|left|200px|The takeover of [[Belgrade]], 1806]] -->
+'''Serbian revolution''' or ''Revolutionary Serbia'' refers to the [[Révolution nationale|national]] and [[social revolution]] of the [[Serbs|Serbian people]] between 1804 and 1815, during which Serbia managed to fully emancipate from the [[Ottoman Empire]] and exist as a sovereign European [[nation-state]], and a latter period (1815–1833), marked by intense negotiations between [[Belgrade]] and [[Ottoman Empire]]. The term was invented by a famous German historian [[Leopold von Ranke]] in his book ''Die Serbische Revolution'', published in 1829.<ref>Leopold von Ranke, ''A History of Serbia and the Serbian Revolution'' (1847)</ref> These events marked the foundation of [[Principality of Serbia|modern Serbia]].<ref>L. S. Stavrianos, ''The Balkans since 1453'' (London: Hurst and Co., 2000), p. 248-250.</ref> While the first phase of the revolution (1804–1815) was in fact a war of independence, the second phase (1815–1833) resulted in official recognition of a [[Principality of Serbia|suzerain Serbian state]] by the [[Sublime Porte|Porte]] (the Ottoman government), thus bringing the revolution to its end.<ref>For an overview see Wayne S. Vucinich, "Marxian Interpretations of the First Serbian Revolution." ''Journal of Central European Affairs''  (1961) 21#1: 3–14.</ref>
+
+The revolution took place by stages:  the [[First Serbian Uprising]] (1804–13), led by [[Karađorđe Petrović]]; [[Hadži Prodanova buna|Hadži Prodan's revolt]] (1814); the [[Second Serbian Uprising]] (1815) under [[Miloš Obrenović]]; and official recognition of the Serbian state (1815–1833) by the Porte.
+
+''[[The Proclamation]]'' (1809) by [[Karađorđe]] in the capital [[Belgrade]] represented the peak of the revolution. It called for unity of the [[Serbs|Serbian nation]], emphasizing the importance of freedom of religion, [[Serbian history]] and formal, written rules of law, all of which it claimed the [[Ottoman Empire]] had failed to provide. It also called on Serbs to stop paying the [[Jizya|jizya tax]] to the Porte.
+
+The ultimate result of the uprisings was Serbia's [[suzerainty]] from the [[Ottoman Empire]]. The [[Principality of Serbia]] was established, governed by its own Parliament, Government, Constitution and its own royal dynasty.  Social element of the revolution was achieved through introduction of the bourgeois society values in Serbia, which is why it was considered the world's easternmost bourgeois revolt, which culminated with the abolition of [[feudalism]] in 1806.<ref>http://www.nb.rs/view_file.php?file_id=57</ref> The establishment of the [[Miloš Obrenović#Later rule|first constitution in the Balkans]] in 1835 ([[Miloš Obrenović#Later rule|later abolished]]) and the founding in 1808 of its first university, [[University of Belgrade|Belgrade's Great Academy]], added to the achievements of the young Serb state.<ref>[http://www.bg.ac.rs/en_istorijat.php University of Belgrade<!-- Bot generated title -->]{{dead link|date=September 2017 |bot=InternetArchiveBot |fix-attempted=yes }}</ref> By 1833, Serbia was officially recognized as a tributary to the Ottoman Empire and as such, acknowledged as a hereditary monarchy. Full independence of the Principality was internationally recognized during the second half of the 19th century.<ref>John K. Cox, ''The History of Serbia'' (2002) pp 39–62</ref>
+
+==Greek Revolt==
+{{main article|Greek War of Independence|Russo-Turkish War (1828–1829)}}
+[[File:Vasilika.jpg|thumb|The [[Battle of Vassilika]] in 1821 marked an early turning point in the war.]]
+The Eastern Question once again became a major European issue when the [[Greece|Greeks]] declared independence from the Sultan in 1821. It was at about this time that the phrase "Eastern Question" was coined. Ever since the defeat of Napoleon in 1815, there had been rumours that the Emperor of Russia sought to invade the Ottoman Empire, and the Greek Revolt seemed to make an invasion even more likely. The British foreign minister, [[Robert Stewart, Viscount Castlereagh]], as well as the Austrian foreign minister, Metternich, counselled the Emperor of Russia, [[Alexander I of Russia|Alexander I]], not to enter the war. Instead, they pleaded that he maintain the [[Concert of Europe]] (the spirit of broad collaboration in Europe which had persisted since Napoleon's defeat). A desire for peaceful co-operation was also held by Alexander I, who had founded the Holy Alliance. Rather than immediately putting the Eastern Question to rest by aiding the Greeks and attacking the Ottomans, Alexander wavered, ultimately failing to take any decisive action.
+
+Alexander's death in 1825 brought [[Nicholas I of Russia|Nicholas I]] to the Imperial Throne of Russia. Deciding that he would no longer tolerate negotiations and conferences, he chose to intervene in Greece.  Britain also soon became involved, interested in imposing its will on a newly formed Greek state in part to prevent it becoming a wholly Russian vassal. The spirit of [[Romanticism]] that then dominated Western European cultural life also made support for Greek independence politically viable.  France too aligned itself with the Greeks, but Austria (still worried about Russian expansion) did not. Outraged by the interference of the Great Powers, the Ottoman Sultan, [[Mahmud II]], denounced Russia as an enemy of [[Islam]], prompting Russia to declare war in 1828. An alarmed Austria sought to form an anti-Russian coalition, but its attempts were in vain.
+
+As the war continued into 1829, Russia gained a firm advantage over the Ottoman Empire. By prolonging hostilities further, however, Russia would have invited Austria to enter the war against her and would have resulted in considerable suspicion in Britain. Therefore, for the Russians to continue with the war in hopes of destroying the Ottoman Empire would have been inexpedient.  At this stage, the King of France, [[Charles X of France|Charles X]], proposed the partition of the Ottoman Empire among Austria, Russia and others, but his scheme was presented too belatedly to produce a result.
+
+Thus, Russia was able to secure neither a decisive defeat nor a partition of the Ottoman Empire. She chose, however, to adopt the policy of degrading the Ottoman Empire to a mere dependency. In 1829, the Emperor of Russia concluded the [[Treaty of Adrianople (1829)|Treaty of Adrianople]] with the Sultan; his empire was granted additional territory along the Black Sea, Russian commercial vessels were granted access to the [[Dardanelles]], and the commercial rights of Russians in the Ottoman Empire were enhanced. The Greek War of Independence was terminated shortly thereafter, as Greece was granted independence by the [[Treaty of Constantinople (1832)|Treaty of Constantinople]] in 1832.
+
+==Muhammad Ali of Egypt==
+{{main article|Muhammad Ali of Egypt}}
+[[Image:ModernEgypt, Muhammad Ali by Auguste Couder, BAP 17996.jpg|right|thumb|[[Muhammad Ali of Egypt|Muhammad Ali Pasha]]]]
+Just as the Greek Revolt was coming to an end, a conflict broke out in the Ottoman Empire between the Sultan and his nominal [[viceroy]] in [[Egypt]], [[Muhammad Ali of Egypt|Mehmet Ali]]. The modern and well trained Egyptians looked as though they could conquer the entire empire.  The Tsar of Russia, in keeping with his policy of reducing the Ottoman Sultan to a petty vassal, offered to form an alliance with the Sultan. In 1833, the two rulers negotiated the [[Treaty of Unkiar Skelessi]], in which Russia achieved the aim of securing complete dominance over the Ottomans. The Russians pledged to protect the Empire from external attacks; in turn, the Sultan pledged to close the Dardanelles to warships whenever Russia was at war. This provision of the Treaty raised a problem known as the "Straits Question". The agreement provided for the closure for all warships, but many European statesmen mistakenly believed that the clause allowed Russian vessels. Britain and France were angered by the misinterpreted clause; they also sought to contain Russian expansion. The two kingdoms, however, differed on how to achieve their objective; the British wished to uphold the Sultan, but the French preferred to make Muhammad Ali (whom they saw as more competent) the ruler of the entire Ottoman Empire. Russian intervention led the Sultan to negotiate a peace with Muhammad Ali in 1833, but war broke out once again in 1839.<ref>Henry Dodwell, ''The Founder of Modern Egypt: A Study of Muhammad ‘Ali'' (Cambridge University Press, 1967)</ref>
+
+Sultan Mahmud II died the same year, leaving the Ottoman Empire to his son [[Abdulmejid I]] in a critical state: the Ottoman army had been significantly defeated by the forces of Muhammad Ali. Another disaster followed when the entire Turkish fleet was seized by the Egyptian forces. Great Britain and Russia now intervened to prevent the collapse of the Ottoman Empire, but France still continued to support Muhammad Ali. In 1840, however, the Great Powers agreed to compromise; Muhammad Ali agreed to make a nominal act of submission to the Sultan, but was granted hereditary control of Egypt.
+
+The only unresolved issue of the period was the Straits Question. In 1841, Russia consented to the abrogation of the Treaty of Unkiar Skelessi by accepting the [[London Straits Convention]]. The Great Powers — Russia, Britain, France, Austria and Prussia — agreed to the re-establishment of the "ancient rule" of the Ottoman Empire, which provided that the Turkish straits would be closed to all warships whatsoever, with the exception of the Sultan's allies during wartime.  With the Straits Convention, the Russian Emperor Nicholas I abandoned the idea of reducing the Sultan to a state of dependence, and returned to the plan of partitioning Ottoman territories in Europe.
+
+Thus, after the resolution of the Egyptian struggle which had begun in 1831, the weak Ottoman Empire was no longer wholly dependent on Russia but was dependent on the Great Powers for protection. Attempts at internal reform failed to end the decline of the Empire. By the 1840s, the Ottoman Empire had become the "[[sick man of Europe]]", and its eventual dissolution appeared inevitable.
+
+==Revolutions of 1848==
+{{main article|Revolutions of 1848}}
+After the Great Powers reached a compromise to end the revolt of Mehmet Ali, the Eastern Question lay dormant for about a decade until revived by the [[Revolutions of 1848]]. Although Russia could have seized the opportunity to attack the Ottoman Empire—France and Austria were at the time occupied by their own insurrections—it chose not to. Instead, Emperor Nicholas committed his troops to the defence of Austria, hoping to establish goodwill to allow him to seize Ottoman possessions in Europe later.
+
+After the Austrian Revolution was suppressed, an Austro-Russian war against the Ottoman Empire seemed imminent. The Emperors of both Austria and Russia demanded that the Sultan return Austrian rebels who had sought asylum in the Empire, but he refused. The indignant monarchs withdrew their ambassadors to the [[Ottoman Porte|Sublime Porte]], threatening armed conflict. Almost immediately, however, Britain and France sent their fleets to protect the Ottoman Empire. The two Emperors, deeming military hostilities futile, withdrew their demands for the surrender of the fugitives.  The short crisis created a closer relationship between Britain and France, which led to a joint war against Russia in the Crimean War of 1853–56.<ref>A.J.P. Taylor, ''The Struggle for Mastery in Europe: 1848–1918'' (1954) pp 33–35</ref>
+
+==Crimean War==
+{{main article|Crimean War}}
+A new conflict began during the 1850s with a religious dispute. Under treaties negotiated during the 18th century, France was the guardian of Roman Catholics in the Ottoman Empire, while Russia was the protector of Orthodox Christians. For several years, however, Catholic and Orthodox monks had disputed possession of the [[Church of the Nativity]] and the [[Church of the Holy Sepulchre]] in [[Palestine (region)|Palestine]]. During the early 1850s, the two sides made demands which the Sultan could not possibly satisfy simultaneously. In 1853, the Sultan adjudicated in favour of the French, despite the vehement protestations of the local Orthodox monks.<ref>Orlando Figes, ''Crimea: The Last Crusade'' (2010); also published as ''The Crimean War: A History'' (2010)
+</ref>
+
+Emperor Nicholas of Russia dispatched [[Aleksandr Sergeyevich Menshikov|Prince Menshikov]], on a special mission to the Porte. By previous treaties, the Sultan was committed "to protect the Christian religion and its Churches", but Menshikov tried to negotiate a new treaty, under which Russia would be allowed to interfere whenever it deemed the Sultan's protection inadequate. At the same time, however, the British government sent [[Stratford Canning, 1st Viscount Stratford de Redcliffe]], who learnt of Menshikov's demands upon arriving. Through skillful diplomacy, Lord Stratford convinced the Sultan to reject the treaty, which compromised the independence of the Ottomans. Shortly after he learned of the failure of Menshikov's diplomacy, Nicholas marched into Moldavia and Wallachia (Ottoman principalities in which Russia was acknowledged as a special guardian of the Orthodox Church), with the pretext that the Sultan failed to resolve the issue of the Holy Places. Nicholas believed that the European powers would not object strongly to the annexation of a few neighbouring Ottoman provinces, especially given Russian involvement in suppressing the Revolutions of 1848.
+
+Britain, seeking to maintain the security of the Ottoman Empire, sent a fleet to the Dardanelles, where it was joined by another fleet sent by France. Yet the European powers hoped for a diplomatic compromise. The representatives of the four neutral Great Powers—Britain, France, Austria and Prussia—met in [[Vienna]], where they drafted a note which they hoped would be acceptable to Russia and the Empire. The note was approved by Nicolas but rejected by Sultan Abd-ul-Mejid I, who felt that the document's poor phrasing left it open to many interpretations. Britain, France and Austria were united in proposing amendments to mollify the Sultan, but their suggestions were ignored in the Court of [[Saint Petersburg]]. Britain and France set aside the idea of continuing negotiations, but Austria and Prussia held hope for diplomacy despite the rejection of the proposed amendments. The Sultan proceeded to war, his armies attacking the Russian army near the Danube. Nicholas responded by despatching warships, which destroyed the entire Ottoman fleet at [[Battle of Sinop|Sinop]] on 30 November 1853, allowing Russia to land and supply its forces on the Ottoman shores fairly easily. The destruction of the Ottoman fleet and the threat of Russian expansion alarmed both Britain and France, who stepped forth in defence of the Ottoman Empire. In 1854, after Russia ignored an Anglo-French ultimatum to withdraw from the Danubian Principalities, Britain and France declared war.
+
+Emperor Nicholas I presumed that Austria, in return for the support rendered during the Revolutions of 1848, would side with him, or at the very least remain neutral. However, Austria felt threatened by the Russian troops in the nearby Danubian Principalities. When Britain and France demanded the withdrawal of Russian forces from the Principalities, Austria supported them; and, though it did not immediately declare war on Russia, it refused to guarantee its neutrality. When, in the summer of 1854, Austria made another demand for the withdrawal of troops, Russia (fearing that Austria would enter the war) complied.
+
+Though the original grounds for war were lost when Russia withdrew her troops from the Danubian Principalities, Britain and France continued hostilities. Determined to address the Eastern Question by ending the Russian threat to the Ottoman Empire, the allies posed several conditions for a ceasefire, including that Russia should give up its protectorate over the Danubian Principalities; that Russia should abandon any right to interfere in Ottoman affairs on the behalf of Orthodox Christians; that the Straits Convention of 1841 was to be revised; and finally, all nations were to be granted access to the river Danube. As the Emperor refused to comply with these "Four Points", the [[Crimean War]] proceeded.
+
+Peace negotiations began in 1856 under the Emperor Nicholas I's successor, [[Alexander II of Russia|Alexander II]]. Under the ensuing [[Treaty of Paris (1856)|Treaty of Paris]], the "Four Points" plan proposed earlier was largely adhered to; most notably, Russia's special privileges relating to the Danubian Principalities were transferred to the Great Powers as a group. In addition, warships of all nations were perpetually excluded from the Black Sea, once the home to a Russian fleet (which had been destroyed during the war). The Emperor of Russia and the Sultan agreed not to establish any naval or military arsenal on that sea coast. The Black Sea clauses came at a tremendous disadvantage to Russia, for it greatly diminished the naval threat it posed to the Ottomans. Moreover, all the Great Powers pledged to respect the independence and territorial integrity of the Ottoman Empire.
+
+The Treaty of Paris stood until 1871, when France was crushed in the [[Franco-Prussian War]]. While Prussia and several other German states united into a powerful [[German Empire]], [[Napoleon III of France|Napoleon III]] was deposed in the formation of the [[French Third Republic]]. Napoleon had opposed Russia over the Eastern Question in order to gain the support of Britain. But the new French Republic did not oppose Russian interference in the Ottoman Empire because that did not significantly threaten French interests. Encouraged by the decision of France, and supported by the German minister [[Otto von Bismarck|Otto, Fürst von Bismarck]], Russia denounced the Black Sea clauses of the treaty agreed to in 1856. As Britain alone could not enforce the clauses, Russia once again established a fleet in the Black Sea.
+
+==Great Eastern Crisis (1875–78)==
+{{main article|Great Eastern Crisis}}
+{{see also|Herzegovina uprising (1875–1877)|April Uprising|Constantinople Conference|Russo-Turkish War, 1877–1878}}
+
+Britain, France, and Austria opposed the [[Treaty of San Stefano]] because the Ottoman Empire gave Russia too much influence in the [[Balkans]], where insurrections were frequent. After many attempts, a diplomatic settlement was reached at the [[Congress of Berlin]], and the new [[Treaty of Berlin (1878)]] revised the earlier treaty. Germany's [[Otto von Bismarck]] presided over the Congress, acting as an "honest broker".<ref>A.J.P. Taylor, The Struggle for Mastery in Europe: 1848–1918 (1954) pp 228–54</ref>
+
+In 1875, the territory of [[Herzegovina]] rebelled against the Sultan, in the [[Herzegovina Uprising (1875-1878)|Herzegovinian rebellion]] in the Province of Bosnia, and Bulgaria rebelled in the [[April Uprising]]. The Great Powers believed they should intervene to prevent a bloody war in the Balkans. The first to act were the members of the [[League of the Three Emperors]] (Germany, Austria-Hungary and Russia), whose common attitude toward the Eastern Question was embodied in the Andrassy Note (named for the Hungarian diplomat [[Julius Andrassy|Julius, Count Andrassy]]). The Note, seeking to avoid a widespread conflagration in Southeastern Europe, urged the Sultan to institute various reforms, including granting religious liberty to Christians. A joint commission of Christians and Muslims was to be established to ensure the enactment of appropriate reforms. With the approval of Britain and France, the Note was submitted to the Sultan, and he agreed on 31 January 1876. But the Herzegovinian leaders rejected the proposal, pointing out that the Sultan had already failed his promises of reforms.
+
+Representatives of the Three Emperors met again in Berlin, where they approved the [[Berlin Memorandum]]. To convince the Herzegovinians, the Memorandum suggested that international representatives be allowed to oversee the institution of reforms in the rebelling provinces. But before the Memorandum could be approved by the Porte, the Ottoman Empire was convulsed by internal strife, which led to the deposition of Sultan Abdul-Aziz. The new Sultan, [[Murad V]], was himself deposed three months later due to his mental instability, bringing [[Abdul Hamid II]] to power. In the meantime, the hardships of the Ottomans had increased; their treasury was empty, and they faced insurrections not only in Herzegovina and Bulgaria, but also in [[Serbia]] and [[Montenegro]]. Still, the Ottoman Empire managed to crush the insurgents in August 1876. The result incommoded Russia, which had planned to take possession of various Ottoman territories in Southeastern Europe in the course of the conflict.
+
+After the uprisings were largely suppressed, however, rumours of Ottoman atrocities against the rebellious population shocked European sensibilities. Russia now intended to enter the war on the side of the rebels. Another attempt for peace was made by delegates of the Great Powers (who now numbered six due to the rise of Italy) assembled at the [[Constantinople Conference]] in 1876. However, the Sultan refused to allow international representatives to oversee the reforms in Bosnia and Herzegovina. In 1877, the Great Powers again made proposals to the Ottoman Empire which were rejected.
+
+[[File:SouthEast Europe 1878.jpg|thumb|upright=1.3|South-East Europe after the [[Congress of Berlin]], 1878]]
+
+Russia declared war on 24 April 1877. Its chancellor [[Alexander Gorchakov|Prince Gorchakov]] had effectively secured Austrian neutrality with the [[Reichstadt Agreement]], under which Ottoman territories captured in the course of the war would be partitioned between the Russian and Austria-Hungarian Empires, with the latter obtaining Bosnia and Herzegovina. Britain, though still fearing the Russian threat to British dominance in Southern Asia, did not involve itself in the conflict. However, when Russia threatened to conquer Constantinople, [[British Prime Minister]] [[Benjamin Disraeli]] urged Austria and Germany to ally with him against this war aim. As a result, Russia sued for peace through the [[Treaty of San Stefano]], which stipulated independence to Romania, Serbia, and Montenegro, autonomy to Bulgaria, reforms in Bosnia and Herzegovina; the ceding [[Dobruja]] and parts of [[Armenia]] and a large indemnity to Russia. This would give Russia great influence in Southeastern Europe, as it could dominate the newly independent states. To reduce these advantages to Russia, the Great Powers (especially Britain), insisted that the treaty be heavily revised.
+
+At the [[Congress of Berlin]], the [[Treaty of Berlin, 1878|Treaty of Berlin]] adjusted the boundaries of the new states in the Ottoman Empire's favour. Bulgaria was divided into two states (Bulgaria and [[Eastern Rumelia]]), as it was feared that a single state would be susceptible to Russian domination. Ottoman cessions to Russia were largely sustained. Bosnia and Herzegovina, though still nominally within the Ottoman Empire, were transferred to [[Austro-Hungarian occupation of Bosnia and Herzegovina|Austrian control]]. The Ottoman island of [[Cyprus]] was given to Britain via a secret agreement between Britain and the Ottoman Empire. These final two procedures were predominantly forced by Disraeli, who was famously described by [[Otto von Bismarck]] as "The old Jew, that is the man", after his level-headed Palmerstonian approach to the Eastern Question.<ref>{{cite book |title=The Concise Dictionary of Foreign Quotations |last=Lejeune |first=Anthony |year=2002 |publisher=Taylor & Francis |isbn=1-57958-341-5 |page=139 |url=https://books.google.com/books?id=3KLz2QEdQaoC&pg=PA139 |accessdate=2010-01-03}}</ref>
+
+==Germany and the Ottoman Empire==
+{{Further|Baghdad Railway}}
+Germany drew away from Russia and became closer to Austria-Hungary, with whom she concluded the [[Dual Alliance, 1879|Dual Alliance]] in 1879. Germany also closely allied with the Ottoman Empire. Germany took over the re-organisation of the Ottoman military and financial system; in return, it received several commercial concessions, including permission to build the [[Baghdad Railway]], which secured for them access to several important economic markets and had the potential for German entry into the Persian Gulf area controlled by Britain. Germany was driven not only by commercial interests, but also by an imperialistic and militaristic rivalry with Britain.  Meanwhile Britain agreed to the [[Entente Cordiale]] with France in 1904, thereby resolving differences between the two countries over international affairs. Britain also reconciled with Russia in 1907 with the [[Anglo-Russian Entente]].<ref>Sean McMeekin, ''The Berlin-Baghdad Express: The Ottoman Empire and Germany's Bid for World Power'' (2012) [https://www.amazon.com/Berlin-Baghdad-Express-Ottoman-Empire-Germanys/dp/0674064321/  excerpt and text search]</ref>
+
+==Young Turk Revolution==
+{{main article|Young Turk Revolution}}
+
+In April 1908, the [[Committee of Union and Progress]] (more commonly called the [[Young Turks]]), a political party opposed to the despotic rule of Sultan [[Abdul Hamid II]], led [[Young Turk Revolution|a rebellion against the Sultan]]. The pro-reform Young Turks deposed the Sultan by July 1909, replacing him with the ineffective [[Mehmed V]]. This began the [[Second Constitutional Era]] of the Ottoman Empire.
+
+In the following years, various constitutional and political reforms were instituted, but the decay of the Ottoman Empire continued.
+
+==Bosnian Crisis==
+{{main article|Bosnian crisis}}
+
+In October 1908, Austria-Hungary's plans for the [[Austro-Hungarian occupation of Bosnia and Herzegovina|annexation of Bosnia and Herzegovina]] were opposed by Serbia, which sought Russian assistance. Russia, however, could not comply; a defeat in the [[Russo-Japanese War]] had devastated her, and Germany threatened to support Austria-Hungary during a war. Britain and France, who were not directly concerned by the annexation, did not become involved. Thus unaided, Serbia was forced to renounce her opposition to the annexation of Bosnia and Herzegovina.
+
+==See also==
+*[[Thracian question]]
+*[[History of modern Egypt#British administration|British Occupation of Egypt]]
+*[[Decline of the Ottoman Empire]]
+*[[Sick man of Europe]]
+*[[Armenian Question]]
+*[[Polish Question]]
+
+==Timeline==
+{{See also|Ottoman ancien régime|Decline and modernization of the Ottoman Empire}}
+*1699 – [[Treaty of Karlowitz]] ends Ottoman control in much of Central Europe and brings an end to Ottoman expansionism
+*1710–11 [[Pruth River Campaign|War with Russia]]
+*1711 – [[Treaty of the Pruth]]
+*1714–18 – [[Ottoman–Venetian War (1714–1718)]]
+*1718 – [[Treaty of Passarowitz]] with Austria and Venice; major Turkish losses
+*1730–35 [[Afsharid–Ottoman War (1730–35)]]. Turks lose much of Caucasus
+* 1735–39 [[Austro-Russian–Turkish War (1735–39)]]; stalemate 
+*1739 – Belgrade Convention (English version) (peace treaty of Russo War of 1735), possession of Azov by Russian firm
+*1768–74 – [[Russo-Turkish War (1768–74)]]. Russia gains control of southern [[Ukraine]], [[Crimea]], and the upper northwestern part of the [[North Caucasus]]
+*1774 – Kuchuk, Kainarji treaty Russia wins (Peace Treaty of Russo War of 1768), the Orthodox protection rights of Turkish territory
+*1787–91 [[Austro-Turkish War (1787–91)]]; Turkish loss
+*1789 – [[French Revolution]]. Ottoman Empire is generally neutral
+*1791 – Shisutazu Convention (English version) (1787 Oud War (~ *1791) (English version) of the peace treaty, in 1526 since the Ottoman-Habsburg wars ended summary)
+*1792 – palm Treaty (Treaty of Russo War of 1787)
+*1796 – Catherine II directed the war to Transcaucasia in General Zubov. Baku falls
+*1798–1802 [[French campaign in Egypt and Syria|Napoleon to Egypt and Syria]]
+*1804–13 [[Russo-Persian War (1804–13)]]
+*1813 – Goresutan Treaty (Treaty of Russian-Persian war of 1804), morning car Jarre Iran Georgia and Azerbaijan give up sovereignty.
+*1817 – Caucasus War (~ 1864)
+*1821–29 – [[Greek War of Independence]]; Greek victory
+*1826–28 – Ottoman-Egyptian Invasion of Mani 
+*1826–28  – [[Russo-Persian War (1826–28)]]
+*1829 – [[Treaty of Adrianople (1829)]] Greece gains autonomy
+*1831 – Muhammad Ali of Syria, Anatolia intrusion (first next Egyptian-Turkish War (~ 1833) (English version)). Bosnian uprising (English version).
+*1833 – Kutaya Convention (English version) (peace treaty of the First Egyptian-Turkish War). Unkyaru-Sukeresshi treaty
+*1838 – British soil commercial treaty (English version) entered into
+*1839–41 – Gyoruhane edict, Tanjimato start, second Egyptian-Turkish War (~ 1841) (English version)
+*1840 – London Convention (the Treaty of the Second Egyptian-Turkish War)
+*1841 – London Straits Convention (English version), Unkyaru-Sukeresshi treaty is discarded, the Russian fleet Bosporus, Dardanelles passage of is prohibited.
+*1846 in Baku – oil well drilling machine was made. There were hand-dug oil well before that.
+*1853 – Crimean War (~ 1856 )
+*1856 – Treaty of Paris (peace treaty of the Crimean War)
+*1867 – Alfred Nobel invents dynamite
+*1872 – Russia sold to investors overseas oil well drilling rights in Baku.
+*1875:
+**[[Herzegovina Uprising (1875–77)]]
+**Serbia Uprising
+**Montenegro Uprising
+*1876:
+**Midohato constitution enacted
+**[[April Uprising]], of Bulgarian subject.
+**Nobel brothers in Baku{{citation needed|date=February 2014}}
+*1877–78 [[Russo-Turkish War (1877–78)]]; Armenian issue 
+*1878 – [[Treaty of San Stefano]] (peace treaty of Russo War of 1877), under the influence of Russia Bulgaria and Independence. June, Berlin conference Bulgaria border is reduced by, of Russia Aegean advance was blocked. Russia Ottoman territory six prefecture ( Turkish version ) to support the people of Armenia Armenian folk movement (English version) is increased, the conflict of Muslim and Armenian surfaced. In Baku Nobel Brothers Oil Company (English version) is established
+*1896 – Ottoman Bank hostage (English version)
+*1897 – Greek, Turkish War (primary). Constantinople Convention (1897) (English version) (Peace Treaty (primary) Greco-Turkish War)
+*1899 – German Baghdad Railway won the right-of-way. United Kingdom that has been competing second Boer War withdrew in war expenses increased due to the outbreak of.
+*1904 – Russo-Japanese War (~ 1905 southward policy of Russia is frustrated by defeat in). Japanese Navy had been used in imported oil from Baku war partner country Russia
+*1905 – Yildiz attempted assassination (English version), Armenian Revolutionary Federation according to Abdulhamid II attempted assassination
+*1908 – Young Turk revolution, Bosnia and Herzegovina annexation
+*1912 – Albania Declaration of Independence (English version) for Turkey, four Balkan countries is the Balkan League formed, first Balkan War started
+*1913 – London Convention, Turkey lost Crete Europe and territory except for Istanbul
+*1914–18 – World War I; alliance with Germany; Turkish loss
+*1919 – Sèvres Treaty (Treaty of the First World War). (Second, 1922 -) Greek, Turkish War
+*1920 – Republic of Turkey established. Was started in 1916 in Central Asia Basmachi uprising is, Bukhara Han country overthrew the Bukhara People's Soviet Republic established. Bolshevik is conquered Baku. Oil well of all private, including the Nobel brothers oil company was taken over in the Bolshevik
+*1921 – Operation Nemesis (English version), Talat Pasha old Ottoman government officials have been many assassination. Aimed at Kiriku Zushi Basmachi of the Soviet Union by Turkestan sent into the Enver Pasha is rolling over, I started the anti-Soviet activity.
+*1922 – Treaty of Lausanne (peace treaty of Greco-Turkish War of 1919). Enver Pasha was killed by mopping-up operation of the Red Army.
+
+==References==
+{{Reflist}}
+
+==Bibliography==
+* Anderson, M.S. ''The Eastern Question, 1774–1923: A Study in International Relations'' (1966) [https://www.questia.com/library/7391310/the-eastern-question-1774-1923-a-study-in-international online].
+* Bitis, Alexander. ''Russia and the Eastern Question: Army, Government and Society, 1815–1833'' (2007)
+* Bridge, F.R. ''From Sadowa to Sarajevo: The Foreign Policy of Austria-Hungary 1866–1914'' (1972)
+*  Faroqhi, Suraiya N. ''The Cambridge History of Turkey'' (Volume 3, 2006) [https://www.amazon.com/Cambridge-History-Turkey-3/dp/0521620953/  excerpt and text search]
+* Frary, Lucien J. and Mara Kozelsky, eds. ''Russian-Ottoman Borderlands: The Eastern Question Reconsidered'' (University of Wisconsin, 2014) [http://uwpress.wisc.edu/books/5292.htm]
+* Gallagher, Tom. ''Outcast Europe: The Balkans, 1789-1989: From the Ottomans to Milosevic'' (2013).
+* Gavrilis, George. "The Greek—Ottoman Boundary as Institution, Locality, and Process, 1832–1882." ''American Behavioral Scientist'' (2008) 51#10 pp: 1516–1537.
+* Hale, William. ''Turkish Foreign Policy, 1774–2000.'' (2000). 375 pp.
+* Hall, Richard C. ''The Balkan Wars, 1912–1913: Prelude to the First World War'' (2000) [https://www.questia.com/read/109249433/the-balkan-wars-1912-1913-prelude-to-the-first-world online]
+* Hayes, Paul. ''Modern British Foreign Policy: The Nineteenth Century 1814-80'' (1975) pp. 233-69.
+* Hupchick, Dennis P. ''The Balkans: from Constantinople to communism'' (2004)
+* Kent, Marian, ed. ''The great powers and the end of the Ottoman Empire'' (Routledge, 2005)
+* Langer, William. ''An Encyclopedia of World History'' (5th ed. 1973); highly detailed outline of events
+* Langer, William. ''European Alliances and Alignments 1870–1890'' (2nd ed. 1950); advanced history
+* Langer, William. ''The Diplomacy of Imperialism 1890–1902'' (2nd ed. 1950); advanced history
+* Macfie, Alexander Lyon. ''The Eastern Question, 1774–1923'' (New York: Longman, 1996)
+*  Marriott, J.A. ''The Eastern Question'' (1918),
+* Matthew, H. C. G. ''Gladstone, 1809–1874'' (1988);  ''Gladstone, 1875–1898'' (1995) [https://www.amazon.com/dp/0198206968/  excerpt & text search vol 1]
+*{{cite book|author=Millman, Richard|title=Britain and the Eastern Question, 1875–78|publisher=Oxford University Press|year=1979}}
+* Rathbone, Mark. "Gladstone, Disraeli and the Bulgarian Horrors." ''History Review'' 50 (2004): 3-7. [https://www.questia.com/article/1G1-128205771/gladstone-disraeli-and-the-bulgarian-horrors-mark online]
+* Rich, Norman. ''Great Power Diplomacy: 1814–1914'' (1991), comprehensive survey
+* Šedivý, Miroslav. ''Metternich, the Great Powers and the Eastern Question'' (Pilsen: University of West Bohemia Press, 2013) major scholarly study 1032pp
+* Seton-Watson, Hugh. ''The Russian Empire 1801–1917'' (1967) [https://www.amazon.com/Russian-Empire-1801-1917-Oxford-History/dp/0198221525/  excerpt and text search]
+* Seton-Watson, R. W. ''Disraeli, Gladstone, and the Eastern Question'' (1935) [https://www.questia.com/library/99267864/disraeli-gladstone-and-the-eastern-question online]
+* Smith, M.S. ''The Eastern Question, 1774-1923'' (1966)
+* Stavrianos, L.S. '' The Balkans Since 1453'' (1958), major scholarly history; [https://archive.org/details/balkanssince145300lsst online free to borrow]
+*{{cite book|author=[[A.J.P. Taylor|Taylor, A.J.P.]] |title=The Struggle for Mastery in Europe, 1848–1918|publisher=Oxford University Press|year=1956}}
+
+===Historiography===
+* Abazi, Enika, and Albert Doja. "The past in the present: time and narrative of Balkan wars in media industry and international politics." ''Third World Quarterly'' 38.4 (2017): 1012-1042. Deals with  travel writing, media reporting, diplomatic records, policy-making, truth claims and expert accounts. 
+* Schumacher, Leslie Rogne. "The Eastern Question as a Europe question: Viewing the ascent of ‘Europe’ through the lens of Ottoman decline." ''Journal of European Studies'' 44.1 (2014): 64-80.  Long bibliography pp 77-80 [http://journals.sagepub.com/doi/abs/10.1177/0047244113508363]
+* Tusan, Michelle. "Britain and the Middle East: New Historical Perspectives on the Eastern Question," ''History Compass'' (2010), 8#3 pp 212–222.
+
+==External links==
+*{{Cite NIE|wstitle=Eastern Question |short=x}}
+
+{{History of Ottoman}}
+
+{{Authority control}}
+
+[[Category:19th century in the Ottoman Empire]]
+[[Category:Politics of the Ottoman Empire]]
+[[Category:Diplomacy]]
+[[Category:History of the Balkans]]
+[[Category:History of international relations]]
+[[Category:Ottoman Empire–Russian Empire relations]]
+[[Category:Austria–Turkey relations]]
+[[Category:National questions]]
+
+{{pp-pc1}}
+{{semiprotected|small=yes}}
+{{short description|Former empire in Asia, Europe and Africa}}
+{{redirect|Turkish Empire|empires with Turkic origins|List of Turkic dynasties and countries}}
+{{Use dmy dates|date=November 2013}}
+{{Infobox former country
+|common_name         = Ottoman Empire
+|status = 
+|continent           = Afroeurasia
+|life_span = {{line-height|1.3em|{{nowrap|c. 1299–1922/1923<ref group=note>[[Abolition of the Ottoman sultanate|The sultanate was abolished]] on 1 November 1922 and the [[Republic of Turkey]] was established on 29 October 1923. For further information, see [[Defeat and dissolution of the Ottoman Empire]].</ref>}}}}
+|native_name         = {{lang|ota-Arab|دولت عليه عثمانیه}}<br/>''Devlet-i ʿAlīye-i ʿO<u>s</u>mānīye''
+|conventional_long_name = Ottoman Empire
+|image_coat          = Osmanli-nisani.svg
+|image_flag          = Flag of the Ottoman Empire.svg
+|flag_type_article   = Flags of the Ottoman Empire
+|flag_type           = Flag (1844–1922)
+|symbol_type_article = Coat of arms of the Ottoman Empire
+|symbol_type         = Coat of arms (1882 design)
+|image_map           = OttomanEmpireMain.png
+|image_map_caption   = The Ottoman Empire at its greatest extent in Europe, under Sultan [[Mehmed IV]] in late 17th century
+|image_map2          = 
+|image_map2_caption  =
+|national_motto      = {{lang|ota-Arab|دولت ابد مدت}}<br/>''Devlet-i Ebed-müddet''<br/><small>"The Eternal State"</small>
+|national_anthem     = ''[[Imperial anthems of the Ottoman Empire|(various)]]''<br/>(during 1808–1922)
+|capital             = {{plainlist|
+*[[Söğüt]]<ref name=Shaw-13>Stanford Shaw, ''History of the Ottoman Empire and Modern Turkey'' (Cambridge: University Press, 1976), vol. 1 p. 13</ref>
+* <small>(c. 1299–1335)</small>
+* [[Bursa]]<ref name="auto">"In 1363 the Ottoman capital moved from Bursa to Edirne, although Bursa retained its spiritual and economic importance." [http://www.kultur.gov.tr/–EN,33810/ottoman-capital-bursa.html ''Ottoman Capital Bursa'']. Official website of Ministry of Culture and Tourism of the Republic of Turkey. Retrieved 26 June 2013.</ref>
+* <small>(1335–1363)</small>
+* [[Edirne]]<ref name="auto"/>
+* <small>(1363–1453)</small>
+* [[Constantinople]] <small>(present-day [[Istanbul]])</small><ref group=note>In Ottoman Turkish, the city was known by various names, among which were ''[[Kostantiniyye]]'' ({{lang|ota-Arab|قسطنطينيه}}) (replacing the suffix ''-polis'' with the Arabic [[Nisba (suffix)|nisba]]), ''[[Dersaadet]]'' ({{lang|ota-Arab|در سعادت}}) and ''Istanbul'' ({{lang|ota-Arab|استانبول}}). Names other than Istanbul gradually became obsolete in Turkish, and after Turkey's transition to Latin script in 1928, Istanbul become widely accepted internationally.</ref><small>
+* (1453–1922)</small>}}
+|common_languages    = {{plainlist|
+* [[Ottoman Turkish language|Ottoman Turkish]] (official)
+* [[Languages of the Ottoman Empire|many others]]}}
+|religion                 = {{plainlist|
+* [[Sunni Islam]] 
+* [[Madhab]]: [[Hanafi]]
+* [[Islamic theology|Creed]]: [[Maturidi]]}}
+|government_type     = {{plainlist|
+* [[Absolute monarchy]]
+* <small>(c. 1299–1876)</small>
+* <small>(1878–1908)</small>
+* <small>(1920–1922)</small>
+* [[Constitutional monarchy]]
+* <small>(1876–1878)</small>
+* <small>(1908–1920)</small>}}
+|title_leader        = [[List of sultans of the Ottoman Empire|Sultan]]
+|leader1             = [[Osman I]] <small>(first)</small>
+|year_leader1        = c. 1299–1323/4
+|leader2             = [[Mehmed VI]] <small>(last)</small>
+|year_leader2        = 1918–1922
+|title_representative= [[Caliph of Islam|Caliph]]
+|year_representative1= 1517–1520
+|representative1     = [[Selim I]] <small>(first)</small><ref name="Lambton"/><ref group=note>The sultan from 1512 to 1520.</ref>
+|year_representative2= 1922–1924
+|representative2     = [[Abdülmecid II]] <small>(last)</small>
+|title_deputy        = [[List of Ottoman Grand Viziers|Grand Vizier]]
+|deputy1             = [[Alaeddin Pasha (vizier)|Alaeddin Pasha]] <small>(first)</small>
+|year_deputy1        = 1320–1331
+|deputy2             = [[Ahmet Tevfik Pasha]] <small>(last)</small>
+|year_deputy2        = 1920–1922
+|legislature         = [[General Assembly of the Ottoman Empire|General Assembly]]
+|house1              = [[Senate of the Ottoman Empire|Senate]]
+|type_house1         =
+|house2              = [[Chamber of Deputies of the Ottoman Empire|Chamber of Deputies]]
+|type_house2         =
+|event_start         = [[Rise of the Ottoman Empire|Founded]]
+|year_start          = c. 1299
+|date_start          =
+|event_end           = [[Turkey|Republic of Turkey]] established<ref group=note>The [[Treaty of Sèvres]] (10 August 1920) afforded a small existence to the Ottoman Empire. On 1 November 1922, the [[Grand National Assembly of Turkey|Grand National Assembly]] (GNAT) abolished the sultanate and declared that all the deeds of the Ottoman regime in Istanbul were null and void as of 16 March 1920, the date of the [[occupation of Constantinople]] under the terms of the Treaty of Sèvres. The international recognition of the GNAT and the [[Government of the Grand National Assembly|Government of Ankara]] was achieved through the signing of the [[Treaty of Lausanne (1923)|Treaty of Lausanne]] on 24 July 1923. The Grand National Assembly of Turkey promulgated the Republic on 29 October 1923, which ended the Ottoman Empire in history.</ref>
+|year_end            = 1923
+|date_end            = 29 October
+|event1              = [[Ottoman Interregnum|Interregnum]]
+|date_event1         = 1402–1414
+|event2              = [[Rise of the Ottoman Empire|Transformation to empire]]
+|date_event2         = 1453
+|event3              = [[First Constitutional Era (Ottoman Empire)|1st Constitutional]]
+|date_event3         = 1876–1878
+|event4              = [[Second Constitutional Era (Ottoman Empire)|2nd Constitutional]]
+|date_event4         = 1908–1920
+|event5              = [[Raid on the Sublime Porte]]
+|date_event5         = 23 January 1913
+|event6              = [[Abolition of the Ottoman Sultanate|Sultanate abolished]]<ref group=note>[[Mehmed VI]], the last Sultan, was expelled from Constantinople on 17 November 1922.</ref>
+|date_event6         = 1 November 1922
+|event_post          = [[Abolition of the Ottoman Caliphate|Caliphate abolished]]
+|date_post           = 3 March 1924
+|stat_year1          = 1683
+|ref_area1           = <ref>{{cite journal |last1=Turchin|first1=Peter|last2=Adams|first2=Jonathan M.|last3=Hall|first3=Thomas D |title = East-West Orientation of Historical Empires |journal = Journal of world-systems research|date=December 2006 |volume=12|issue=2 |page=223 |url =http://jwsr.pitt.edu/ojs/index.php/jwsr/article/view/369/381|accessdate=12 September 2016 |issn= 1076-156X}}</ref><ref>{{cite journal|date=September 1997|title=Expansion and Contraction Patterns of Large Polities: Context for Russia|journal=[[International Studies Quarterly]]|volume=41|issue=3|page=498|doi=10.1111/0020-8833.00053|author=Rein Taagepera|authorlink=Rein Taagepera|jstor=2600793}}</ref> 
+|stat_area1          = 5200000
+|stat_year2          = 1914
+|stat_area2          = 1800000
+|ref_area2           = <ref>Dündar, Orhan; Dündar, Erhan, 1.Dünya Savaşı, Millî Eğitim Bakanlığı Yayınları, 1999, {{ISBN|975-11-1643-0}}</ref>
+|stat_year3          = 1683
+|stat_pop3           = 30000000
+|stat_year4          = 1856
+|stat_pop4           = 35350000
+|stat_year5          = 1912
+|stat_pop5           = 24000000
+|ref_pop5            = <ref name="Erickson2003">{{cite book |last=Erickson |first=Edward J.  |title=Defeat in Detail: The Ottoman Army in the Balkans, 1912–1913 |url=https://books.google.com/books?id=3fYuy5iUi_sC |year=2003 |publisher=Greenwood Publishing Group |isbn=978-0-275-97888-4 |page=59}}</ref>
+|stat_year6          = 1914
+|stat_pop6           = 18520000
+|stat_year7          = 1919
+|stat_pop7           = 14629000
+|currency            = [[Akçe]], [[Para (currency)|Para]], [[Sultani]], [[Kuruş]], [[Ottoman lira|Lira]]
+|p1                  = Sultanate of Rum 
+|flag_p1             =  
+|border_p1           = no
+|p2                  = 
+|flag_p2             = 
+|p3                  = Anatolian beyliks
+|flag_p3             = Anadolu Beylikleri.png
+|p4                  = Byzantine Empire
+|flag_p4             = Byzantine imperial flag, 14th century.svg
+|border_p4           = no
+|p5                  = Kingdom of Bosnia
+|flag_p5             = Coat of arms of Kingdom of Bosnia.svg
+|border_p5           = no
+|p6                  = Second Bulgarian Empire
+|flag_p6             = Coat of arms of the Second Bulgarian Empire.svg
+|border_p6           = no
+|p7                  = Serbian Despotate
+|flag_p7             = Despot of Serbia.png
+|border_p7           = no
+|p8                  = Kingdom of Hungary (1000–1538){{!}}Kingdom of Hungary
+|flag_p8             = Flag of Louis II of Hungary.svg
+|border_p8           = no
+|p9                  = Kingdom of Croatia (1102–1526){{!}}Kingdom of Croatia
+|flag_p9             = Coa Croatia Country History (Fojnica Armorial).svg
+|border_p9           = no
+|p10                 = Mamluk Sultanate (Cairo){{!}}Mamluk Sultanate
+|flag_p10            = Mameluke Flag.svg
+|border_p10          = no
+|p11                 = Hafsid dynasty
+|flag_p11            = Tunis Hafsid flag.svg
+|border_p11          = no
+|p12                 = History of Malta under the Order of Saint John{{!}}Hospitallers of Tripolitania
+|flag_p12            = Coat of arms of the Sovereign Military Order of Malta.svg
+|border_p12          = no
+|p13                 = Kingdom of Tlemcen
+|flag_p13            = Dz tlem2.gif
+|p14                 = Empire of Trebizond
+|flag_p14            = Empire of Trebizond arms.jpg
+|border_p14          = no
+|p15                 = Samtskhe-Saatabago{{!}}Principality of Samtskhe
+|flag_p15            = Coat_of_arms_of_Principality_of_Samtskhe.svg
+|border_p15          = no
+<!-- only 15 predecessors are currently (as of September 2017) used by the template -->
+|p16                 = Despotate of the Morea{{!}}Despotate of the Morea
+|flag_p16            = Byzantine imperial flag, 14th century.svg
+|p17                 = Zeta under the Crnojevići{{!}}Zeta
+|flag_p17            = Coat of arms of the house of Crnojevic.svg
+|s1                  = Government of the Grand National Assembly{{!}}'''Turkish Provisional Government'''
+|flag_s1             = Ottoman flag alternative 2.svg
+|s2                  = First Hellenic Republic{{!}}Hellenic Republic
+|flag_s2             = Flag of Greece (1828-1978).svg
+|s3                  = Caucasus Viceroyalty (1801–1917){{!}}Caucasus Viceroyalty
+|flag_s3             = Flag of Russia.svg
+|s4                  = Condominium of Bosnia and Herzegovina{{!}}Bosnia and Herzegovina
+|flag_s4             = Flag of Bosnia (1878-1908).svg
+|s5                  = Revolutionary Serbia{{!}}Revolutionary Serbia
+|flag_s5             = Flag of Revolutionary Serbia.svg
+|s6                  = Provisional Government of Albania{{!}}Albania
+|flag_s6             = Flag of Albanian Provisional Government 1912-1914.gif
+|s7                  = Kingdom of Romania{{!}}Kingdom of Romania
+|flag_s7             = Flag of Romania.svg
+|s8                  = Principality of Bulgaria{{!}}Principality of Bulgaria
+|flag_s8             = Flag of Bulgaria.svg
+|s9                  = Occupied Enemy Territory Administration{{!}}OETA
+|flag_s9             = Flags of France and the UK.png
+|s10                 = Mandatory Iraq
+|flag_s10            = Flag of Iraq (1924–1959).svg
+|s11                 = Kingdom of Hejaz{{!}}Kingdom of Hejaz
+|flag_s11            = Flag of Hejaz 1920.svg
+|s12                 = French Algeria
+|flag_s12            = Flag of France.svg
+|s13                 = British Cyprus (1914–1960){{!}}British Cyprus
+|flag_s13            = Flag of Cyprus (1881-1922).svg
+|s14                 = French protectorate of Tunisia{{!}}French Tunisia
+|flag_s14            = Pre-1999 Flag of Tunisia.svg
+|s15                 = Italian Libya
+|flag_s15            = Flag of Italy (1861-1946).svg
+<!-- only 15 successors are currently (as of September 2017) used by the template -->
+|s16                 = Sheikhdom of Kuwait{{!}}Kuwait
+|flag_s16            = Flag of Kuwait (1915-1956).svg
+|s17                 = Mutawakkilite Kingdom of Yemen{{!}}Kingdom of Yemen
+|flag_s17            = Flag of the Mutawakkilite Kingdom of Yemen.svg
+|s18                 = Italian East Africa
+|flag_s18            = Flag of Italy (1861-1946).svg
+|s19                 = British Somaliland
+|flag_s19            = Flag of British Somaliland (1950-60).png
+|s20                 = French Somaliland
+|flag_s20            = Flag of France.svg
+|s21                 = State of Slovenes, Croats and Serbs
+|flag_s21            = Flag of the State of Slovenes, Croats and Serbs.svg
+<!-- This infobox intentionally does not contain a "today part of" section. Please do not add one without establishing consensus on the talk page. -->
+}}
+{{History of the Ottoman Empire}}
+
+The&nbsp;'''Ottoman Empire'''&nbsp;({{IPAc-en|ˈ|ɒ|t|ə|m|ə|n}}; {{lang-ota|دولت عليه عثمانیه}}, ''{{transl|ota|Devlet-i ʿAlīye-i ʿOsmānīye}}'', literally "The Exalted Ottoman State"; [[Modern Turkish]]: ''{{lang|tr|Osmanlı İmparatorluğu}}'' or ''{{lang|tr|Osmanlı Devleti}}''), also historically known in [[Western Europe]] as the '''Turkish Empire'''<ref name="Hamish">{{cite book|url=https://books.google.com/?id=Jb4DCgAAQBAJ&dq=The+Oxford+Handbook+of+Early+Modern+European+History,+1350-1750:+Volume+II|title=The Oxford Handbook of Early Modern European History, 1350–1750: Volume II|author=Hamish Scott|year=2015|page=612|isbn=9780191020001}}"The Ottoman Empire-also known in Europe as the Turkish Empire"</ref> or simply '''Turkey''',<ref name=":0" /> was a state that controlled much of [[Southeast Europe]], [[Western Asia]] and [[North Africa]] between the 14th and early 20th centuries. It was founded at the end of the 13th century in northwestern [[Anatolia]] in the town of [[Söğüt]] (modern-day [[Bilecik Province]]) by the [[Oghuz Turks|Oghuz Turkish]] tribal leader [[Osman I]].<ref>{{Cite book |last=Finkel |first=Caroline |title=Osman's Dream: The Story of the Ottoman Empire, 1300–1923 |pages=2, 7 |publisher=Basic Books |isbn=978-0-465-02396-7}}</ref> After 1354, the Ottomans crossed into [[Europe]], and with the conquest of [[the Balkans]], the Ottoman [[Anatolian beyliks|beylik]] was transformed into a transcontinental empire. The Ottomans ended the [[Byzantine Empire]] with the 1453 [[Fall of Constantinople|conquest of Constantinople]] by [[Mehmed the Conqueror]].<ref name="Quataert2005">{{cite book|last=Quataert|first=Donald |title=The Ottoman Empire, 1700–1922|url=https://books.google.com/books?id=OX3lsOrXJGcC|publisher=Cambridge University Press|isbn=978-0-521-83910-5|page=4 |edition=2 |date=2005}}</ref>
+
+During the 16th and 17th centuries, at the height of its power under the reign of [[Suleiman the Magnificent]],<ref>{{cite EB1911 |wstitle=Turkey |volume=27 |page=448}}</ref> the Ottoman Empire was a multinational, multilingual empire controlling most of Southeast Europe, parts of [[Central Europe]], Western Asia, parts of [[Eastern Europe]] and the [[Caucasus]], North Africa and the [[Horn of Africa]].<ref>{{cite web|url=http://www.oxfordislamicstudies.com/article/opr/t125/e1801?_hi=41&_pos=3 |title=Ottoman Empire |publisher=Oxford Islamic Studies Online |date=6 May 2008 |accessdate=26 August 2010}}</ref> At the beginning of the 17th century, the empire contained [[Provinces of the Ottoman Empire|32 provinces]] and numerous [[Vassal and tributary states of the Ottoman Empire|vassal states]]. Some of these were later absorbed into the Ottoman Empire, while others were granted various types of autonomy during the course of centuries.<ref group="note">The empire also temporarily gained authority over distant overseas lands through declarations of allegiance to the [[Ottoman Dynasty|Ottoman Sultan and Caliph]], such as the [[Ottoman expedition to Aceh|declaration by the Sultan of Aceh]] in 1565, or through temporary acquisitions of islands such as [[Lanzarote]] in the Atlantic Ocean in 1585, [http://www.dzkk.tsk.tr/turkce/tarihimiras/AtlantikteTurkDenizciligi.php Turkish Navy Official Website: "Atlantik'te Türk Denizciliği"]</ref>
+
+With [[Constantinople during the Ottoman era|Constantinople]] as its capital and control of lands around the [[Mediterranean Sea|Mediterranean basin]], the Ottoman Empire was at the centre of interactions between the [[Eastern world|Eastern]] and [[Western world|Western]] worlds for six centuries. While the empire was once thought to have entered a period of [[Ottoman Decline Thesis|decline]] following the death of [[Suleiman the Magnificent]], this view is no longer supported by the majority of academic historians.<ref name=decline>{{cite book |last=Hathaway |first=Jane |title=The Arab Lands under Ottoman Rule, 1516–1800 |publisher=Pearson Education Ltd. |year=2008 |isbn=978-0-582-41899-8 |page=8 |quote=historians of the Ottoman Empire have rejected the narrative of decline in favor of one of crisis and adaptation}}
+* {{cite book |last=Tezcan|first=Baki |title=The Second Ottoman Empire: Political and Social Transformation in the Early Modern Period |publisher=Cambridge University Press |date=2010 |page=9 |isbn=978-1-107-41144-9 |quote=Ottomanist historians have produced several works in the last decades, revising the traditional understanding of this period from various angles, some of which were not even considered as topics of historical inquiry in the mid-twentieth century. Thanks to these works, the conventional narrative of Ottoman history – that in the late sixteenth century the Ottoman Empire entered a prolonged period of decline marked by steadily increasing military decay and institutional corruption – has been discarded.}}
+* {{Cite book |editor=Christine Woodhead |title=The Ottoman World |chapter=Introduction |last=Woodhead |first=Christine |isbn=978-0-415-44492-7 |date=2011 |page=5 |quote=Ottomanist historians have largely jettisoned the notion of a post-1600 ‘decline’}}</ref> The empire continued to maintain a flexible and strong economy, society and military throughout the 17th and much of the 18th century.<ref>{{Cite book |last=Ágoston |first=Gábor  |editor-last=Ágoston |editor-first=Gábor |editor2=Bruce Masters |title=Encyclopedia of the Ottoman Empire |chapter=Introduction |date=2009 |page=xxxii}}
+* {{cite book |last=Faroqhi|first=Suraiya |editor-last=İnalcık |editor-first=Halil |editor2=Donald Quataert |title=An Economic and Social History of the Ottoman Empire, 1300–1914 |volume=2 |publisher=Cambridge University Press |date=1994 |page=553 |chapter=Crisis and Change, 1590–1699 |isbn=0-521-57456-0 |quote=In the past fifty years, scholars have frequently tended to view this decreasing participation of the sultan in political life as evidence for “Ottoman decadence,” which supposedly began at some time during the second half of the sixteenth century. But recently, more note has been taken of the fact that the Ottoman Empire was still a formidable military and political power throughout the seventeenth century, and that noticeable though limited economic recovery followed the crisis of the years around 1600; after the crisis of the 1683–99 war, there followed a longer and more decisive economic upswing. Major evidence of decline was not visible before the second half of the eighteenth century.}}</ref> However, during a long period of peace from 1740 to 1768, the Ottoman military system fell behind that of their European rivals, the [[Habsburg Empire|Habsburg]] and [[Russian Empire|Russian]] empires.<ref name="AksanOW">{{cite book |last=Aksan |first=Virginia |title=Ottoman Wars, 1700–1860: An Empire Besieged |publisher=Pearson Education Ltd. |date=2007 |pages=130–5 |isbn=978-0-582-30807-7}}</ref> The Ottomans consequently suffered severe military defeats in the late 18th and early 19th centuries, which prompted them to initiate a comprehensive process of reform and modernisation known as the [[Tanzimat]]. Thus, over the course of the 19th century, the Ottoman state became vastly more powerful and organised, despite suffering further territorial losses, especially in the Balkans, where a number of new states emerged.<ref>{{cite book |last=Quataert|first=Donald |editor-last=İnalcık |editor-first=Halil |editor2=Donald Quataert |title=An Economic and Social History of the Ottoman Empire, 1300–1914 |volume=2 |publisher=Cambridge University Press |date=1994 |page=762 |chapter=The Age of Reforms, 1812–1914 |isbn=0-521-57456-0}}</ref> The empire allied with [[German Empire|Germany]] in the early 20th century, hoping to escape from the diplomatic isolation which had contributed to its recent territorial losses, and thus joined [[World War I]] on the side of the [[Central Powers]].<ref>{{cite book |last=Findley |first=Carter Vaughn |title=Turkey, Islam, Nationalism and Modernity: A History, 1789–2007 |place=New Haven |publisher=Yale University Press |date=2010 |isbn=978-0-300-15260-9 |pages=200}}</ref> While the Empire was able to largely hold its own during the conflict, it was struggling with internal dissent, especially with the [[Arab Revolt]] in its Arabian holdings. During this time, atrocities were committed by the Ottoman government against the [[Armenian Genocide|Armenians]], [[Assyrian genocide|Assyrians]] and [[Greek genocide|Pontic Greeks]].<ref>
+<br />{{•}} {{Cite book|first=Donald|last=Quataert | year=2005 | title=The Ottoman Empire, 1700-1922|publisher=Cambridge University Press (Kindle edition)|page=186}}
+<br />{{•}} {{cite journal |last1 = Schaller |first1 = Dominik J |last2 = Zimmerer |first2 = Jürgen |year = 2008 |title = Late Ottoman genocides: the dissolution of the Ottoman Empire and Young Turkish population and extermination policies – introduction |url = |journal = Journal of Genocide Research |volume = 10 |issue = 1|pages = 7–14 |doi = 10.1080/14623520801950820}}
+</ref>
+
+The Empire's defeat and the occupation of part of its territory by the [[Allies of World War I|Allied Powers]] in the [[aftermath of World War I]] resulted in [[partitioning of the Ottoman Empire|its partitioning]] and the loss of its Middle Eastern territories, which were [[Sykes–Picot Agreement|divided between the United Kingdom and France]]. The successful [[Turkish War of Independence]] against the occupying Allies led to the emergence of the [[Republic of Turkey]] in the Anatolian heartland and the [[Abolition of the Ottoman sultanate|abolition of the Ottoman monarchy]].<ref>{{Cite book| last = Howard | first = Douglas A. | title = A History of the Ottoman Empire| publisher = Cambridge University Press | year = 2016|url=https://books.google.com/books?id=e57eDQAAQBAJ&pg=PA318|page=318| isbn = 9781108107471 }}</ref>
+
+== Name ==
+{{Main|Names of the Ottoman Empire}}
+The word ''Ottoman'' is a historical [[anglicisation]] of the name of [[Osman I]], the founder of the Empire and of the ruling [[Ottoman dynasty|House of Osman]] (also known as the Ottoman dynasty). Osman's name in turn was the Turkish form of the Arabic name ''[[Uthman (name)|ʿUthmān]]'' ({{lang|ota-Arab|عثمان}}). In [[Ottoman Turkish language|Ottoman Turkish]], the empire was referred to as ''Devlet-i ʿAlīye-yi ʿO<u>s</u>mānīye'' ({{lang|ota-Arab|دولت عليه عثمانیه}}),<ref name="twareekh.com">{{cite web|url=http://www.twareekh.com/images/upload/aboutus/ottmani10liras1334F-.jpg |title=Ottoman banknote with Arabic script |accessdate=26 August 2010}}</ref> (literally "The Supreme Ottoman State") or alternatively ''ʿO<u>s</u>mānlı Devleti'' ({{lang|ota-Arab|عثمانلى دولتى}}). In [[Turkish language|Modern Turkish]], it is known as ''Osmanlı İmparatorluğu'' ("The Ottoman Empire") or ''Osmanlı Devleti'' ("The Ottoman State").
+
+The Turkish word for "Ottoman" (''Osmanlı'') originally referred to the tribal followers of Osman in the fourteenth century, and subsequently came to be used to refer to the empire's military-administrative elite. In contrast, the term "Turk" (''Türk'') was used to refer to the Anatolian peasant and tribal population, and was seen as a disparaging term when applied to urban, educated individuals.<ref>{{Cite book |last=Ágoston |first=Gábor |editor-last=Ágoston |editor-first=Gábor |editor2=Bruce Masters |title=Encyclopedia of the Ottoman Empire |chapter=Introduction |date=2009 |page=xxvi}}
+* {{Cite book|last=Imber |first=Colin |title=The Ottoman Empire, 1300–1650: The Structure of Power |edition=2 |publisher=Palgrave Macmillan |place=New York |date=2009 |page=3 |quote=By the seventeenth century, literate circles in Istanbul would not call themselves Turks, and often, in phrases such as 'senseless Turks', used the word as a term of abuse.}}</ref> In the [[early modern period]], an educated urban-dwelling Turkish-speaker who was not a member of the military-administrative class would refer to himself neither as an ''Osmanlı'' nor as a ''Türk'', but rather as a ''Rūmī'' ({{lang|ota-Arab|رومى}}), or "Roman", meaning an inhabitant of the territory of the former [[Byzantine Empire]] in the [[Balkans]] and [[Anatolia]]. The term ''Rūmī'' was also used to refer to Turkish-speakers by the other Muslim peoples of the empire and beyond.<ref>{{cite journal |last=Kafadar |first=Cemal |title=A Rome of One's Own: Cultural Geography and Identity in the Lands of Rum |journal=Muqarnas |volume=24 |date=2007 |page=11}}</ref>
+
+In Western Europe, the two names "Ottoman Empire" and "Turkey" were often used interchangeably, with "Turkey" being increasingly favoured both in formal and informal situations. This dichotomy was officially ended in 1920–23, when the newly established Ankara-based Turkish government chose [[Turkey]] as the sole official name. Most scholarly historians avoid the terms "Turkey", "Turks", and "Turkish" when referring to the Ottomans, due to the empire's multinational character.<ref name=":0">{{cite book |last=Soucek |first=Svat |title=Ottoman Maritime Wars, 1416–1700 |publisher=The Isis Press |place=Istanbul |date=2015 |isbn=978-975-428-554-3 |pages=8 |quote=The scholarly community specializing in Ottoman studies has of late virtually banned the use of "Turkey", "Turks", and "Turkish" from acceptable vocabulary, declaring "Ottoman" and its expanded use mandatory and permitting its "Turkish" rival only in linguistic and philological contexts.}}</ref>
+
+== History ==
+{{Main|History of the Ottoman Empire}}
+{{See also|Territorial evolution of the Ottoman Empire}}
+
+=== Rise (c. 1299–1453) ===
+{{main|Rise of the Ottoman Empire}}
+{{further|Osman I|Ottoman dynasty|Gaza Thesis}}
+
+As the Seljuk [[Sultanate of Rum]] declined in the 13th century, Anatolia was divided into a patchwork of independent Turkish principalities known as the [[Anatolian Beyliks]]. One of these beyliks, in the region of [[Bithynia]] on the frontier of the [[Byzantine Empire]], was led by the Turkish tribal leader [[Osman I|Osman]] (d. 1323/4), a figure of obscure origins from whom the name Ottoman is derived.<ref>{{Cite book |last=Kermeli |first=Eugenia  |editor-last=Ágoston |editor-first=Gábor |editor2=Bruce Masters |title=Encyclopedia of the Ottoman Empire |chapter=Osman I |date=2009 |page=444}}</ref> Osman's early followers consisted both of Turkish tribal groups and Byzantine renegades, many but not all converts to Islam.<ref>{{Cite book|last=Lowry |first=Heath |title=The Nature of the Early Ottoman State |publisher=SUNY Press |date=2003 |page=59}}
+* {{Cite book |last=Kafadar |first=Cemal |title=Between Two Worlds: The Construction of the Ottoman State |date=1995 |page=127}}</ref> Osman extended the control of his principality by conquering [[Byzantine]] towns along the [[Sakarya River]]. It is not well understood how the early Ottomans came to dominate their neighbours, due to the lack of sources surviving from this period. The [[Gaza Thesis]] theory popular during the twentieth century credited their success to their rallying of religious warriors to fight for them in the name of [[Islam]], but it is now highly criticised and no longer generally accepted by historians, and no consensus on the nature of the early Ottoman state's expansion has replaced it.<ref>{{cite book|last=Finkel|first=Caroline|title=Osman's Dream: The History of the Ottoman Empire|url=https://books.google.com/books?id=9cTHyUQoTyUC&pg=PA5 |year=2005 |publisher=Basic Books|isbn=978-0-465-00850-6|pages=5, 10}}
+* {{Cite book |editor= Kate Fleet |title=The Cambridge History of Turkey |volume= 1, Byzantium to Turkey, 1071–1453 |date=2009 |publisher=Cambridge University Press |place=Cambridge |last=Lindner |first=Rudi Paul |page=104 |chapter=Anatolia, 1300–1451}}</ref>
+
+[[File:Battle of Nicopolis.jpg|thumb|left|[[Battle of Nicopolis]] in 1396. Painting from 1523.]]
+
+In the century after the death of Osman I, Ottoman rule began to extend over Anatolia and the [[History of the Balkans|Balkans]]. Osman's son, [[Orhan]], captured the northwestern Anatolian city of [[Bursa]] in 1326, making it the new capital of the Ottoman state and supplanting Byzantine control in the region. The important port city of [[Thessaloniki]] was captured from the [[Republic of Venice|Venetians]] in 1387 and sacked. The Ottoman victory at [[Battle of Kosovo|Kosovo in 1389]] effectively marked [[Fall of the Serbian Empire|the end of Serbian power]] in the region, paving the way for Ottoman expansion into Europe.<ref>{{cite book|author=Robert Elsie|title=Historical Dictionary of Kosova|url=https://books.google.com/books?id=Fnbw1wsacSAC&pg=PA95|year=2004|publisher=Scarecrow Press|pages=95–96|isbn=978-0-8108-5309-6}}</ref> The [[Battle of Nicopolis]] in 1396, widely regarded as the last large-scale [[Crusades|crusade]] of the [[Middle Ages]], failed to stop the advance of the victorious Ottoman Turks.<ref>{{cite book|author=David Nicolle|title=Nicopolis 1396: The Last Crusade|url=https://books.google.com/books?id=_hUst0z-oEQC|year=1999|publisher=Osprey Publishing|isbn=978-1-85532-918-8}}</ref>
+
+As the Turks expanded into the Balkans, the [[Sieges of Constantinople#Ottoman Sieges|conquest of Constantinople]] became a crucial objective. The Ottomans had already wrested control of nearly all former [[Byzantine Empire|Byzantine lands]] surrounding the city, but the heavy defence of Constantinople's strategic position on the [[Bosphorus]] Strait made it difficult to conquer. In 1402, the Byzantines were temporarily relieved when the [[Turco-Mongol]] leader [[Timur]], founder of the [[Timurid Empire]], invaded Ottoman Anatolia from the east. In the [[Battle of Ankara]] in 1402, Timur defeated the Ottoman forces and took Sultan [[Bayezid I]] as a prisoner, throwing the empire into disorder. The [[Ottoman Interregnum|ensuing civil war]], also known as the ''Fetret Devri'', lasted from 1402 to 1413 as Bayezid's sons fought over succession. It ended when [[Mehmed I]] emerged as the sultan and restored Ottoman power.<ref>{{cite book|author1=Gábor Ágoston|author2=Bruce Alan Masters|title=Encyclopedia of the Ottoman Empire|url=https://books.google.com/books?id=QjzYdCxumFcC&pg=PA363|year=2009|publisher=Infobase Publishing|page=363|isbn=978-1-4381-1025-7}}</ref>
+
+The Balkan territories lost by the Ottomans after 1402, including Thessaloniki, Macedonia and Kosovo, were later recovered by [[Murad II]] between the 1430s and 1450s. On 10 November 1444, Murad repelled the [[Crusade of Varna]] by defeating the Hungarian, Polish, and [[Wallachia]]n armies under [[Władysław III of Poland]] (also King of Hungary) and [[John Hunyadi]] at the [[Battle of Varna]], although Albanians under [[Skanderbeg]] continued to resist. Four years later, John Hunyadi prepared another army of Hungarian and Wallachian forces to attack the Turks, but was again defeated at the [[Battle of Kosovo (1448)|Second Battle of Kosovo]] in 1448.<ref>{{cite book|author1=Mesut Uyar|author2=Edward J. Erickson|title=A Military History of the Ottomans: From Osman to Atatürk|url=https://books.google.com/books?id=JgfNBKHG7S8C&pg=PA29|year=2009|publisher=ABC-CLIO|page=29|isbn=978-0-275-98876-0}}</ref>
+
+=== Expansion and peak (1453–1566) ===
+{{Main|Growth of the Ottoman Empire}}
+[[File:Zonaro_GatesofConst.jpg|thumb|left|Sultan [[Mehmed II]]'s entry into [[Constantinople]]; painting by [[Fausto Zonaro]] (1854–1929)]]
+The son of Murad II, [[Mehmed the Conqueror]], reorganized the state and the military, and conquered [[fall of Constantinople|Constantinople]] on 29 May 1453. Mehmed allowed the [[Orthodox Church]] to maintain its autonomy and land in exchange for accepting Ottoman authority.<ref name="books.google">{{cite book|last=Stone|first=Norman|editor=Mark Erickson, Ljubica Erickson|title=Russia War, Peace And Diplomacy: Essays in Honour of John Erickson|url=https://books.google.com/books?id=xM9wQgAACAAJ|accessdate=11 February 2013|year=2005|publisher=Weidenfeld & Nicolson|isbn=978-0-297-84913-1|page=94|chapter=Turkey in the Russian Mirror}}</ref> Because of bad relations between the states of western Europe and the later Byzantine Empire, the majority of the Orthodox population accepted Ottoman rule as preferable to Venetian rule.<ref name="books.google"/> Albanian resistance was a major obstacle to Ottoman expansion on the Italian peninsula.<ref>Hodgkinson 2005, p. 240</ref>
+
+In the 15th and 16th centuries, the Ottoman Empire entered a [[Growth of the Ottoman Empire|period of expansion]]. The Empire prospered under the rule of a line of committed and effective [[Ottoman Dynasty|Sultans]]. It also flourished economically due to its control of the major overland trade routes between Europe and Asia.<ref>{{cite book |author=Karpat, Kemal H. |title=The Ottoman state and its place in world history |publisher=Brill |location=Leiden |year=1974 |page=111 |isbn=90-04-03945-7}}</ref><ref group="note">A lock-hold on trade between western Europe and Asia is often cited as a primary motivation for [[Isabella I of Castile]] to fund [[Christopher Columbus]]'s westward journey to find a sailing route to Asia and, more generally, for European seafaring nations to explore alternative trade routes (e.g. K. D. Madan, ''Life and travels of Vasco Da Gama'' (1998), 9; I. Stavans, ''Imagining Columbus: the literary voyage'' (2001), 5; W.B. Wheeler and S. Becker, ''Discovering the American Past. A Look at the Evidence: to 1877'' (2006), 105). This traditional viewpoint has been attacked as unfounded in an influential article by A.H. Lybyer ("The Ottoman Turks and the Routes of Oriental Trade", ''English Historical Review'', 120 (1915), 577–588), who sees the rise of Ottoman power and the beginnings of Portuguese and Spanish explorations as unrelated events. His view has not been universally accepted (cf. K.M. Setton, ''The Papacy and the Levant (1204–1571), Vol. 2: The Fifteenth Century (Memoirs of the American Philosophical Society, Vol. 127)'' (1978), 335).</ref>
+
+Sultan [[Selim I]] (1512–1520) dramatically expanded the Empire's eastern and southern frontiers by defeating [[Ismail I|Shah Ismail]] of [[Safavid dynasty|Safavid]] [[Persia]], in the [[Battle of Chaldiran]].<ref>{{cite journal |last=Savory |first=R. M.|title = The Principal Offices of the Ṣafawid State during the Reign of Ismā'īl I (907-30/1501-24)|journal = Bulletin of the School of Oriental and African Studies, University of London|volume = 23 |issue=1 |pages=91–105 |year=1960|doi = 10.1017/S0041977X00149006 |jstor=609888 |ref=harv}}</ref> Selim I established [[History of Ottoman Egypt|Ottoman rule in Egypt]], and created a naval presence on the [[Red Sea]]. After this Ottoman expansion, a competition started between the [[Portuguese Empire]] and the Ottoman Empire to become the dominant power in the region.<ref>{{cite journal |last=Hess |first=Andrew C.|title = The Ottoman Conquest of Egypt (1517) and the Beginning of the Sixteenth-Century World War|journal = International Journal of Middle East Studies|volume = 4 |issue=1 |pages=55–76 |date=January 1973|jstor = 162225 |doi=10.1017/S0020743800027276 |ref=harv}}</ref>
+[[File:Suleiman I after the victory at Mohács.jpg|thumb|[[Battle of Mohács]] in 1526<ref>{{cite web|last=Lokman |url=http://warfare.atwebpages.com/Ottoman/Ottoman.htm |title=Battle of Mohács (1526) |year=1588 |deadurl=yes |archiveurl=https://web.archive.org/web/20130529094441/http://warfare.atwebpages.com/Ottoman/Ottoman.htm |archivedate=29 May 2013 |df= }}</ref>]]
+
+[[Suleiman the Magnificent]] (1520–1566) captured [[Belgrade]] in 1521, conquered the southern and central parts of the [[Kingdom of Hungary]] as part of the [[Ottoman–Hungarian Wars]],<ref>{{cite web|url=http://www.britannica.com/EBchecked/topic/276730/Hungary/214181/History#ref=ref411152 |title=Origins of the Magyars |work=Hungary |publisher=Britannica Online Encyclopedia |accessdate=26 August 2010}}</ref><ref>{{cite web|url=http://cache-media.britannica.com/eb-media/47/20547-004-D655EA04.gif |title=Encyclopædia Britannica |publisher=Britannica Online Encyclopedia |accessdate=26 August 2010}}</ref>{{failed verification|date=February 2013}} and, after his historic victory in the [[Battle of Mohács]] in 1526, he established Turkish rule in the territory of present-day Hungary (except the western part) and other Central European territories. He then laid [[Siege of Vienna|siege to Vienna]] in 1529, but failed to take the city.<ref>{{cite book|last=Imber|first=Colin|title=The Ottoman Empire, 1300–1650: The Structure of Power|year=2002|publisher=Palgrave Macmillan|isbn=0-333-61386-4|page=50}}</ref> In 1532, he made another [[Little War in Hungary|attack]] on Vienna, but was repulsed in the [[Siege of Güns]].<ref name="Thompson442">{{cite book |last=Thompson |first=Bard |title=Humanists and Reformers: A History of the Renaissance and Reformation |publisher=Wm. B. Eerdmans Publishing |location= |page=442 |year=1996 |isbn=978-0-8028-6348-5}}</ref><ref name="Ágoston and Alan Masters583">{{cite book |last=Ágoston and Alan Masters |first=Gábor and Bruce |title=Encyclopedia of the Ottoman Empire |publisher=Infobase Publishing |page=583 |location= |year=2009 |isbn=978-1-4381-1025-7}}</ref> [[Transylvania]], [[Wallachia]] and, intermittently, [[Moldavia]], became tributary principalities of the Ottoman Empire. In the east, the Ottoman Turks [[Ottoman–Safavid War (1532–55)|took]] [[Baghdad]] from the Persians in 1535, gaining control of [[Mesopotamia]] and naval access to the [[Persian Gulf]]. In 1555, the [[Caucasus]] became officially partitioned for the first time between the Safavids and the Ottomans, a ''[[status quo]]'' that would remain until the end of the [[Russo-Turkish War (1768–74)]]. By this partitioning of the Caucasus as signed in the [[Peace of Amasya]],  [[Western Armenia]], western [[Kurdistan]], and [[Kingdom of Imereti|Western Georgia]] (incl. western [[Samtskhe-Atabagate|Samtskhe]]) fell into Ottoman hands,<ref>''The Reign of Suleiman the Magnificent, 1520–1566'', V.J. Parry, '''A History of the Ottoman Empire to 1730''', ed. M.A. Cook (Cambridge University Press, 1976), 94.</ref> while southern [[Dagestan]], [[Eastern Armenia]], [[Eastern Georgia]], and [[Azerbaijan]] remained Persian.<ref>''A Global Chronology of Conflict: From the Ancient World to the Modern Middle East'', Vol. II, ed. Spencer C. Tucker, (ABC-CLIO, 2010). 516.</ref>
+
+[[File:Battle of Preveza (1538).jpg|thumb|right|[[Barbarossa Hayreddin Pasha]] defeats the [[Holy League (1538)|Holy League]] of [[Charles V, Holy Roman Emperor|Charles V]] under the command of [[Andrea Doria]] at the [[Battle of Preveza]] in 1538]]
+
+[[Early Modern France|France]] and the Ottoman Empire, united by mutual opposition to [[Habsburg]] rule, became strong allies. The French conquests of [[Siege of Nice|Nice]] (1543) and [[Invasion of Corsica (1553)|Corsica]] (1553) occurred as a joint venture between the forces of the French king [[Francis I of France|Francis I]] and Suleiman, and were commanded by the Ottoman admirals [[Barbarossa Hayreddin Pasha]] and [[Turgut Reis]].<ref>{{cite book|last=Imber|first=Colin|title=The Ottoman Empire, 1300–1650: The Structure of Power|year=2002|publisher=Palgrave Macmillan|isbn=0-333-61386-4|page=53}}</ref> A month before the siege of Nice, France supported the Ottomans with an artillery unit during the 1543 Ottoman [[siege of Esztergom (1543)|conquest of Esztergom]] in northern Hungary. After further advances by the Turks, the Habsburg ruler [[Ferdinand I, Holy Roman Emperor|Ferdinand]] officially recognized Ottoman ascendancy in Hungary in 1547.
+
+By the end of Suleiman's reign, the Empire spanned approximately {{convert|877,888|mi2|abbr=on}}, extending over three continents.<ref>{{Cite book |last=Ágoston |first=Gábor  |editor-last=Ágoston |editor-first=Gábor |editor2=Bruce Masters |title=Encyclopedia of the Ottoman Empire |chapter=Süleyman I |date=2009 |page=545}}</ref> In addition, the Empire became a dominant naval force, controlling much of the [[Mediterranean Sea]].<ref>{{cite book|last=Mansel|first=Philip|title=Constantinople : city of the world's desire 1453–1924|year=1997|publisher=Penguin|location=London|isbn=0-14-026246-6|page=61}}</ref> By this time, the Ottoman Empire was a major part of the European political sphere. The success of its political and military establishment was compared to the Roman Empire, by the likes of Italian scholar [[Francesco Sansovino]] and the French political philosopher [[Jean Bodin]].<ref name="deringil709">{{cite journal|last=Deringil|first=Selim|title=The Turks and 'Europe': The Argument from History|journal=Middle Eastern Studies|date=September 2007|volume=43|issue=5|pages=709–723|doi=10.1080/00263200701422600|ref=harv}}</ref>
+
+=== Stagnation and reform (1566–1827) ===
+==== Revolts, reversals, and revivals (1566–1683) ====
+{{main|Transformation of the Ottoman Empire}}
+{{further|Ottoman Decline Thesis}}
+{{Update|inaccurate=yes|talk=The_Decline_Paradigm|date=September 2016}}
+[[File:OttomanEmpire1566.png|thumb|The extent of the Ottoman Empire in 1566, upon the death of [[Suleiman the Magnificent]]]]
+[[File:Szigetvar 1566.jpg|thumb|Ottoman miniature about the [[Siege of Szigetvár|Szigetvár campaign]] showing Ottoman troops and [[Crimean Khanate|Tatars]] as avant-garde]]
+
+In the second half of the sixteenth century the Ottoman Empire came under increasing strain from inflation and the rapidly rising costs of warfare that were impacting both Europe and the Middle East. These pressures led to a series of crises around the year 1600, placing great strain upon the Ottoman system of government.<ref>{{cite book |last=Faroqhi|first=Suraiya |editor-last=İnalcık |editor-first=Halil |editor2=Donald Quataert |title=An Economic and Social History of the Ottoman Empire, 1300–1914 |volume=2 |publisher=Cambridge University Press |date=1994 |pages=413–4 |chapter=Crisis and Change, 1590–1699 |isbn=0-521-57456-0}}</ref> The empire underwent a series of transformations of its political and military institutions in response to these challenges, enabling it to successfully adapt to the new conditions of the seventeenth century and remain powerful, militarily and economically.<ref>{{cite book |last=Hathaway |first=Jane |title=The Arab Lands under Ottoman Rule, 1516–1800 |publisher=Pearson Education Ltd. |year=2008 |isbn=978-0-582-41899-8 |page=8}}</ref><ref>{{Cite book |last=Şahin |first=Kaya |title=Empire and Power in the reign of Süleyman: Narrating the Sixteenth-Century Ottoman World |publisher=Cambridge University Press |year=2013|isbn=978-1-107-03442-6 |page=10}}</ref> Historians of the mid-twentieth century once characterized this period as one of stagnation and decline, but this view is now rejected by the majority of academics.<ref name=decline/>
+
+The discovery of new maritime trade routes by Western European states allowed them to avoid the Ottoman trade monopoly. The [[Kingdom of Portugal|Portuguese]] discovery of the [[Cape of Good Hope]] in 1488 initiated [[Ottoman naval expeditions in the Indian Ocean|a series of Ottoman-Portuguese naval wars]] in the [[Indian Ocean]] throughout the 16th century. Despite the growing European presence in the Indian Ocean, Ottoman trade with the east continued to flourish. Cairo in particular benefitted from the rise of Yemeni coffee as a popular consumer commodity. As coffeehouses appeared in cities and towns across the empire, Cairo developed into a major center for its trade, contributing to its continued prosperity throughout the seventeenth and much of the eighteenth century.<ref>{{cite book |last=Faroqhi|first=Suraiya |editor-last=İnalcık |editor-first=Halil |editor2=Donald Quataert |title=An Economic and Social History of the Ottoman Empire, 1300–1914 |volume=2 |publisher=Cambridge University Press |date=1994 |pages=507–8 |chapter=Crisis and Change, 1590–1699 |isbn=0-521-57456-0}}</ref>
+
+Under [[Ivan IV]] (1533–1584), the [[Tsardom of Russia]] expanded into the Volga and Caspian region at the expense of the Tatar khanates. In 1571, the Crimean khan [[Devlet I Giray]], supported by the Ottomans, [[Russo-Crimean War (1571)|burned Moscow]].<ref name="Davies2007">{{cite book|last=Davies|first=Brian L.|title=Warfare, State and Society on the Black Sea Steppe: 1500–1700|url=https://books.google.com/books?id=XH4hghHo1qoC&pg=PA16|accessdate=11 February 2013|year=2007|publisher=Routledge|isbn=978-0-415-23986-8|page=16}}</ref> The next year, the invasion was repeated but repelled at the [[Battle of Molodi]]. The [[Crimean Khanate]] continued to invade Eastern Europe in a series of [[Tatar invasions|slave raids]],<ref name="Subtelny2000">{{cite book|author=Orest Subtelny|title=Ukraine|url=https://books.google.com/books?id=HNIs9O3EmtQC&pg=PA106|accessdate=11 February 2013|year=2000|publisher=University of Toronto Press|isbn=978-0-8020-8390-6|page=106}}</ref> and remained a significant power in Eastern Europe until the end of the 17th century.<ref>{{cite web|url=http://www.econ.hit-u.ac.jp/~areastd/mediterranean/mw/pdf/18/10.pdf |title=The Crimean Tatars and their Russian-Captive Slaves |first=Eizo |last=Matsuki |publisher=Mediterranean Studies Group at Hitotsubashi University |format=PDF |accessdate=11 February 2013 |deadurl=yes |archiveurl=https://web.archive.org/web/20130115170654/http://www.econ.hit-u.ac.jp/~areastd/mediterranean/mw/pdf/18/10.pdf |archivedate=15 January 2013}}</ref>
+
+In southern Europe, a [[Holy League (1571)|Catholic coalition]] led by [[Philip II of Spain]] won a victory over the Ottoman fleet at the [[Battle of Lepanto]] (1571). It was a startling, if mostly symbolic,{{sfn|Kinross|1979|p=272}} blow to the image of Ottoman invincibility, an image which the victory of the Knights of Malta against the Ottoman invaders in the 1565 [[Great Siege of Malta|Siege of Malta]] had recently set about eroding.<ref>Fernand Braudel, ''The Mediterranean and the Mediterranean World in the Age of Philip II'', vol. II ( University of California Press: Berkeley, 1995).{{page}}</ref> The battle was far more damaging to the Ottoman navy in sapping experienced manpower than the loss of ships, which were rapidly replaced.<ref>{{cite book|last1=Kunt|first1=Metin|last2=Woodhead|first2=Christine|title=Süleyman the Magnificent and His Age: the Ottoman Empire in the Early Modern World|year=1995|publisher=Longman|isbn=978-0-582-03827-1|page=53}}</ref> The Ottoman navy recovered quickly, persuading Venice to sign a peace treaty in 1573, allowing the Ottomans to expand and consolidate their position in North Africa.{{sfn|Itzkowitz|1980|p=67}}
+
+[[File:Battle of Lepanto 1571.jpg|thumb|left|[[Battle of Lepanto]] in 1571]]
+
+By contrast, the [[Habsburg]] frontier had settled somewhat, a stalemate caused by a stiffening of the Habsburg defences.{{sfn|Itzkowitz|1980|p=71}} The [[Long Turkish War|Long War]] against [[Habsburg]] Austria (1593–1606) created the need for greater numbers of Ottoman infantry equipped with firearms, resulting in a relaxation of recruitment policy. This contributed to problems of indiscipline and outright rebelliousness within the corps, which were never fully solved.{{sfn|Itzkowitz|1980|pp=90–92}}{{Obsolete source|date=September 2016}} Irregular sharpshooters ([[Sekban]]) were also recruited, and on demobilization turned to [[brigandage]] in the [[Jelali revolts]] (1590–1610), which engendered widespread anarchy in [[Anatolia]] in the late 16th and early 17th centuries.<ref>{{cite book|author=Halil İnalcık|title=An Economic And Social History of the Ottoman Empire, Vol. 1 1300–1600|url=https://books.google.com/books?id=1j-AtkBmn78C&pg=PA24|accessdate=12 February 2013|year=1997|publisher=Cambridge University Press|isbn=978-0-521-57456-3|page=24}}</ref> With the Empire's population reaching 30 million people by 1600, the shortage of land placed further pressure on the government.{{sfn|Kinross|1979|p=281}}{{Obsolete source|date=September 2016}} In spite of these problems, the Ottoman state remained strong, and its army did not collapse or suffer crushing defeats. The only exceptions were campaigns against the [[Safavid]] dynasty of [[Persia]], where many of the Ottoman eastern provinces were lost, some permanently. This [[Ottoman-Safavid War (1603-1618)|1603–1618]] war eventually resulted in the [[Treaty of Nasuh Pasha]], which ceded the entire Caucasus, except westernmost Georgia, back into Iranian Safavid possession.<ref>Ga ́bor A ́goston, Bruce Alan Masters [https://books.google.com/books?id=QjzYdCxumFcC&pg=PA23 ''Encyclopedia of the Ottoman Empire''] pp. 23 Infobase Publishing, 1 jan. 2009 {{ISBN|1438110251}}</ref>
+
+[[File:Boksida, karta ur Wr.110:5 (Turc. Imper. Asia Geographie (I.34.17) - Skoklosters slott - 82210.tif|thumb|Map from 1654]]
+[[File:Vienna Battle 1683.jpg|thumb|[[Battle of Vienna|Second Siege of Vienna]] in 1683]]
+
+During his brief majority reign, [[Murad IV]] (1623–1640) reasserted central authority and recaptured [[Iraq]] (1639) from the [[Safavids]].{{sfn|Itzkowitz|1980|p=73}} The resulting [[Treaty of Zuhab]] of that same year decisively parted the [[Caucasus]] and adjacent regions between the two neighbouring empires as it had already been defined in the 1555 [[Peace of Amasya]].<ref>{{cite web|url=https://books.google.com/books?id=B8WRAgAAQBAJ&pg=PA47 |title=Armenians: Past and Present in the Making of National Identity|accessdate=30 December 2014}}</ref><ref>{{cite web|url=https://books.google.com/books?id=yED-aVDCbycC&pg=PA228 |title=Genocide and the Modern Age: Etiology and Case Studies of Mass Death|accessdate=30 December 2014}}</ref> The [[Sultanate of women]] (1623–1656) was a period in which the mothers of young sultans exercised power on behalf of their sons. The most prominent women of this period were [[Kösem Sultan]] and her daughter-in-law [[Turhan Hatice]], whose political rivalry culminated in Kösem's murder in 1651.{{sfn|Itzkowitz|1980|pp=74–75}} During the [[Köprülü Era]] (1656–1703), effective control of the Empire was exercised by a sequence of [[Grand Vizier]]s from the Köprülü family. The Köprülü Vizierate saw renewed military success with authority restored in [[Transylvania]], the conquest of [[Crete]] completed in 1669, and expansion into Polish southern [[Ukraine]], with the strongholds of [[Khotyn]] and [[Kamianets-Podilskyi]] and the territory of [[Podolia]] ceding to Ottoman control in 1676.{{sfn|Itzkowitz|1980|pp=80–81}}
+
+This period of renewed assertiveness came to a calamitous end in 1683 when Grand Vizier [[Kara Mustafa Pasha]] led a huge army to attempt a second Ottoman siege of [[Vienna]] in the [[Great Turkish War]] of 1683–1699. The final assault being fatally delayed, the Ottoman forces were swept away by allied Habsburg, German and Polish forces spearheaded by the Polish king [[John III Sobieski]] at the [[Battle of Vienna]]. The alliance of the [[Holy League (1684)|Holy League]] pressed home the advantage of the defeat at Vienna, culminating in the [[Treaty of Karlowitz]] (26 January 1699), which ended the Great Turkish War.{{sfn|Kinross|1979|p=357}} The Ottomans surrendered control of significant territories, many permanently.{{sfn|Itzkowitz|1980|p=84}} [[Mustafa II]] (1695–1703) led the counterattack of 1695–96 against the Habsburgs in Hungary, but was undone at the disastrous defeat at [[Battle of Zenta|Zenta]] (in modern Serbia), 11 September 1697.{{sfn|Itzkowitz|1980|pp=83–84}}
+
+==== Russian threat grows ====
+Aside from the loss of the [[Banat]] and the temporary loss of [[Belgrade]] (1717–39), the Ottoman border on the [[Danube]] and [[Sava]] remained stable during the eighteenth century. [[Expansion of Russia 1500–1800|Russian expansion]], however, presented a large and growing threat.{{sfn|Kinross|1979|p = 371}} Accordingly, King [[Charles XII of Sweden]] was welcomed as an ally in the Ottoman Empire following his defeat by the Russians at the [[Battle of Poltava]] of 1709 in central Ukraine (part of the [[Great Northern War]] of 1700–1721).{{sfn|Kinross|1979|p = 371}} Charles XII persuaded the Ottoman Sultan [[Ahmed III]] to declare war on Russia, which resulted in an Ottoman victory in the [[Pruth River Campaign]] of 1710–1711, in Moldavia.{{sfn|Kinross|1979|p = 372}}
+
+[[File:1720 Huchtenburg Eroberungs Belgrads 1717 anagoria.JPG|thumb|left|Austrian troops led by [[Prince Eugene of Savoy]] capture [[Belgrade]] in 1717]]
+
+After the [[Austro-Turkish War of 1716–1718]] the [[Treaty of Passarowitz]] confirmed the loss of the [[Banat]], Serbia and [[Oltenia|"Little Walachia" (Oltenia)]] to Austria. The Treaty also revealed that the Ottoman Empire was on the defensive and unlikely to present any further aggression in Europe.{{sfn|Kinross|1979|p = 376}} The [[Austro-Russian–Turkish War (1735–1739)|Austro-Russian–Turkish War]] (1735–1739), which was ended by the [[Treaty of Belgrade]] in 1739, resulted in the recovery of Serbia and Oltenia, but the Empire lost the port of [[Azov]], north of the Crimean Peninsula, to the Russians. After this treaty the Ottoman Empire was able to enjoy a generation of peace, as Austria and Russia were forced to deal with the rise of [[Prussia]].{{sfn|Kinross|1979|p = 392}}
+
+[[Science and Technology in the Ottoman Empire#Education|Educational and technological reforms]] came about, including the establishment of higher education institutions such as the [[Istanbul Technical University]].<ref>{{cite web |url=http://www.itu.edu.tr/en/?about/history |title=History |publisher=Istanbul Technical University |accessdate=6 November 2011 |archive-url=https://web.archive.org/web/20120618160944/http://www.itu.edu.tr/en/?about%2Fhistory |archive-date=18 June 2012 |dead-url=yes |df=dmy-all }}</ref> In 1734 an artillery school was established to impart Western-style artillery methods, but the Islamic clergy successfully objected under the grounds of [[theodicy]].<ref name="books.google_a">{{cite book|last=Stone|first=Norman|editor=Mark Erickson, Ljubica Erickson|title=Russia War, Peace And Diplomacy: Essays in Honour of John Erickson|url=https://books.google.com/books?id=xM9wQgAACAAJ|accessdate=11 February 2013|year=2005|publisher=Weidenfeld & Nicolson|isbn=978-0-297-84913-1|page=97|chapter=Turkey in the Russian Mirror}}</ref> In 1754 the artillery school was reopened on a semi-secret basis.<ref name="books.google_a"/> In 1726, [[Ibrahim Muteferrika]] convinced the [[Grand Vizier]] [[Nevşehirli Damat İbrahim Pasha]], the [[Grand Mufti]], and the clergy on the efficiency of the printing press, and Muteferrika was later granted by Sultan Ahmed III permission to publish non-religious books (despite opposition from some [[Islamic calligraphy|calligraphers]] and religious leaders).<ref name="katip celebi">{{cite web |url=http://vitrine.library.uu.nl/en/texts/Rarqu54.htm |title=Presentation of Katip Çelebi, Kitâb-i Cihân-nümâ li-Kâtib Çelebi |publisher=Utrecht University Library |date=5 May 2009 |accessdate=11 February 2013 |deadurl=yes |archiveurl=https://web.archive.org/web/20130212030334/http://vitrine.library.uu.nl/en/texts/Rarqu54.htm |archivedate=12 February 2013 |df=dmy-all }}</ref> Muteferrika's press published its first book in 1729 and, by 1743, issued 17 works in 23 volumes, each having between 500 and 1,000 copies.<ref name="katip celebi"/><ref name="watson">{{cite journal|last=Watson|first=William J.|title=Ibrahim Muteferrika and Turkish Incunabula|journal=Journal of the American Oriental Society|year=1968|volume=88|issue=3|page=435|doi=10.2307/596868|jstor=596868}}</ref>
+
+[[File:January Suchodolski - Ochakiv siege.jpg|thumb|Ottoman troops attempt to halt advancing Russians during the [[Siege of Ochakov (1788)|Siege of Ochakov]] in 1788.]]
+
+In 1768 Russian-backed Ukrainian [[Haidamaka]]s, pursuing Polish confederates, entered [[Balta, Ukraine|Balta]], an Ottoman-controlled town on the border of Bessarabia in Ukraine, and massacred its citizens and burned the town to the ground. This action provoked the Ottoman Empire into the [[Russo-Turkish War (1768–1774)|Russo-Turkish War of 1768–1774]]. The [[Treaty of Küçük Kaynarca]] of 1774 ended the war and provided freedom to worship for the Christian citizens of the Ottoman-controlled provinces of Wallachia and Moldavia.{{sfn|Kinross|1979|p = 405}} By the late 18th century, after a number of defeats in the wars with Russia, some people in the Ottoman Empire began to conclude that the reforms of [[Peter the Great]] had given the Russians an edge, and the Ottomans would have to keep up with Western technology in order to avoid further defeats.<ref name="books.google_a"/>
+
+[[Selim III]] (1789–1807) made the first major attempts to [[Ottoman military reform efforts|modernize the army]], but his reforms were hampered by the religious leadership and the [[Janissary]] corps. Jealous of their privileges and firmly opposed to change, the Janissary [[Janissary revolts|revolted]]. Selim's efforts cost him his throne and his life, but were resolved in spectacular and bloody fashion by his successor, the dynamic [[Mahmud II]], who [[The Auspicious Incident|eliminated the Janissary corps]] in 1826.
+
+[[File:Ottoman Sultan Selim III (1789).jpg|thumb|left|[[Selim III]] receiving dignitaries during an audience at the Gate of Felicity, [[Topkapı Palace]]]]
+
+The [[Serbian revolution]] (1804–1815) marked the beginning of an era of [[Rise of nationalism under the Ottoman Empire|national awakening]] in the [[Balkans]] during the [[Eastern Question]]. In 1811, the fundamentalist Wahhabis of Arabia, led by the al-Saud family revolted against the Ottomans. Unable to defeat the Wahhabi rebels, the Sublime Porte had Mohammad Ali the Great, the ''vali'' (governor) of Egypt tasked with retaking Arabia which ended with the destruction of the [[Emirate of Diriyah]] in 1818. The [[Suzerainty]] of Serbia as a hereditary monarchy under its own [[Obrenović dynasty|dynasty]] was acknowledged ''de jure'' in 1830.<ref>{{cite web|url=http://www.njegos.org/past/liunion.htm |title=Liberation, Independence And Union of Serbia And Montenegro |publisher=Serb Land of Montenegro |accessdate=26 August 2010}}</ref><ref name="Berend2003">{{cite book|last=Berend|first=Tibor Iván|authorlink=Iván T. Berend|title=History Derailed: Central and Eastern Europe in the Long 19th Century|url=https://books.google.com/books?id=a9csmhIT_BQC&pg=PA127|accessdate=11 February 2013|year=2003|publisher=University of California Press|isbn=978-0-520-93209-8|page=127}}</ref> In 1821, the [[Ottoman Greece|Greeks]] [[Greek War of Independence|declared war]] on the Sultan. A rebellion that originated in Moldavia as a diversion was followed by the main revolution in the [[Peloponnese]], which, along with the northern part of the [[Gulf of Corinth]], became the first parts of the Ottoman Empire to achieve independence (in 1829). In 1830, the French invaded Algeria, which was lost to the empire. In 1831, Mohammad Ali revolted with the aim of making himself sultan and founding a new dynasty, and his French-trained army under his son Ibrahim Pasha defeated the Ottoman Army as it marched on Constantinople, coming within 200 miles of the capital.<ref>Karsh, Effraim ''Islamic Imperialism A History'', New Haven: Yale University Press, 2006 page 95.</ref> In desperation, the Sultan [[Mahmud II]] appealed to the empire's traditional archenemy Russia for help, asking the Emperor Nicholas I to send an expeditionary force to save him.<ref name="Karsh, Effraim page 96">Karsh, Effraim ''Islamic Imperialism A History'', New Haven: Yale University Press, 2006 page 96.</ref> In return for signing the [[Treaty of Hünkâr İskelesi]], the Russians sent the expeditionary force, which deterred Ibrahim from taking Constantinople.<ref name="Karsh, Effraim page 96"/> Under the terms of Peace of Kutahia, signed on 5 May 1833 Mohammad Ali agreed to abandon his claim to the throne, in exchange for which he was made the ''vali'' of the ''vilayets'' (provinces) of Crete, Aleppo, Tripoli, Damascus and Sidon (the latter four comprising modern Syria and Lebanon), and given the right to collect taxes in Adana.<ref name="Karsh, Effraim page 96"/> Had it not been for the Russian intervention, it is almost certain Mahumd II would have been overthrown and Mohammad Ali would have become the new sultan, marking the beginning of a recurring pattern where the Sublime Porte needed the help of outsiders to save itself.<ref>Karsh, Effraim ''Islamic Imperialism A History'', New Haven: Yale University Press, 2006 pages 95–96.</ref> 
+[[File:Η μάχη της Αλαμάνας.jpg|thumb|The [[Greek War of Independence]] (1821–1829) against the Ottomans]]
+In 1839, the Sublime Porte attempted to take back what it lost to the de facto independent ''vilayet'' of Egypt, and suffered a crushing defeat, leading to the [[Oriental Crisis of 1840|Oriental Crisis]] as Mohammad Ali was very close to France, and the prospect of him as Sultan was widely viewed as putting the entire empire into the French sphere of influence.<ref name="Karsh, Effraim page 96"/> As the Sublime Porte had proved itself incapable of defeating the Egyptians, Britain and Austria intervened to defeat Egypt.<ref name="Karsh, Effraim page 96"/> By the mid-19th century, the Ottoman Empire was called the [[Sick man of Europe|"sick man"]] by Europeans. The [[suzerainty|suzerain states]] – the [[Principality of Serbia]], Wallachia and [[Moldavia]] – moved towards ''de jure'' independence during the 1860s and 1870s.
+
+=== Decline and modernization (1828–1908) ===
+{{Main|Decline of the Ottoman Empire}}
+During the [[Tanzimat]] period (1839–1876), the government's series of constitutional reforms led to a fairly modern [[Conscription in the Ottoman Empire|conscripted army]], banking system reforms, the decriminalization of homosexuality, the replacement of religious law with secular law<ref>{{cite web|last=Ishtiaq|first=Hussain|title=The Tanzimat: Secular reforms in the Ottoman Empire|url=http://faith-matters.org/images/stories/fm-publications/the-tanzimat-final-web.pdf|publisher=Faith Matters}}</ref> and [[guild]]s with modern factories. The Ottoman Ministry of Post was established in Istanbul on 23 October 1840.<ref name="PTT">{{cite web|url=http://www.ptt.gov.tr/tr/kurumsal/tarihce.html |archiveurl=https://web.archive.org/web/20080913233443/http://www.ptt.gov.tr/tr/kurumsal/tarihce.html |archivedate=13 September 2008 |title=PTT Chronology |publisher=PTT Genel Müdürlüğü |language=Turkish |date=13 September 2008 |accessdate=11 February 2013 |deadurl=yes |df= }}</ref><ref name="PTT2">{{cite web|url=http://www.ptt.gov.tr/index.snet?wapp=histor_en&open=1 |title=History of the Turkish Postal Service |publisher=Ptt.gov.tr |accessdate=6 November 2011}}</ref>
+
+[[Samuel Morse]] received a Turkish [[patent]] for the [[telegraphy|telegraph]] in 1847, which was issued by Sultan [[Abdülmecid I|Abdülmecid]] who personally tested the new invention.<ref>{{cite web|url=http://www.istanbulcityguide.com/history/body_mansions_palaces.htm |archiveurl=https://web.archive.org/web/20071010112702/http://www.istanbulcityguide.com/history/body_mansions_palaces.htm |archivedate=10 October 2007 |title=Beylerbeyi Palace |publisher=Istanbul City Guide |accessdate=11 February 2013 |deadurl=yes |df= }}</ref> Following this successful test, work on the first Turkish telegraph line (Istanbul-[[Edirne]]-[[Şumnu]])<ref name="NTVtarih2">{{cite journal|url=http://www.ntvtarih.com.tr/ |issue=July 2011 |title=Sultan Abdülmecid: İlklerin Padişahı |page=49 |language=Turkish |publisher=NTV Tarih |accessdate=11 February 2013 |deadurl=yes |archiveurl=https://web.archive.org/web/20130212143841/http://www.ntvtarih.com.tr/ |archivedate=12 February 2013 |df= }}</ref> began on 9 August 1847.<ref name="telekomhistory">{{cite web|url=http://www.turktelekom.com.tr/webtech/eng_default.asp?sayfa_id=30 |archiveurl=https://web.archive.org/web/20070928164731/http://www.turktelekom.com.tr/webtech/eng_default.asp?sayfa_id=30 |archivedate=28 September 2007 |title=History |publisher=Türk Telekom |accessdate=11 February 2013 |deadurl=yes |df= }}</ref> The reformist period peaked with the Constitution, called the ''[[Kanûn-u Esâsî]]''. The empire's [[First Constitutional Era (Ottoman Empire)|First Constitutional era]] was short-lived. The parliament survived for only two years before the sultan suspended it.
+
+[[File:Battle at river Skit 1877.jpg|thumb|left|[[United Principalities|Romania]], fighting on the Russian side, [[Romanian War of Independence|gained independence]] from the Ottoman Empire in 1878 after the end of [[Russo-Turkish War (1877–1878)|Russo-Turkish War]].]]
+The Christian population of the empire, owing to their higher educational levels, started to pull ahead of the Muslim majority, leading to much resentment on the part of the latter.<ref name="books.google_b">{{cite book|last=Stone|first=Norman|editor=Mark Erickson, Ljubica Erickson|title=Russia War, Peace And Diplomacy: Essays in Honour of John Erickson|url=https://books.google.com/books?id=xM9wQgAACAAJ|accessdate=11 February 2013|year=2005|publisher=Weidenfeld & Nicolson|isbn=978-0-297-84913-1|page=95|chapter=Turkey in the Russian Mirror}}</ref> In 1861, there were 571 primary and 94 secondary schools for Ottoman Christians with 140,000 pupils in total, a figure that vastly exceeded the number of Muslim children in school at the same time, who were further hindered by the amount of time spent learning Arabic and Islamic theology.<ref name="books.google_b"/> Stone further suggested that the Arabic alphabet, which Turkish was written in until 1928, was very ill-suited to reflect the sounds of the Turkish language (which is a Turkic as opposed to Semitic language), which imposed a further difficulty on Turkish children.<ref name="books.google_b"/> In turn, the higher educational levels of the Christians allowed them to play a larger role in the economy, with the rise in prominence of groups such as the [[Sursock family]] indicative of this shift in influence. <ref>{{cite web|title=Sursock House|url=https://sursockhouse.com/|accessdate=29 May 2018}}</ref> <ref name="books.google_b"/> In 1911, of the 654 wholesale companies in Istanbul, 528 were owned by ethnic Greeks.<ref name="books.google_b"/> In many cases, Christians and also Jews were able to gain protection from European consuls and citizenship, meaning they were protected from Ottoman law and not subject to the same economic regulations as their Muslim comrades.<ref>{{Cite book|title = The Arabs: A History|last = Rogan|first = Eugene|publisher = Penguin|year = 2011|isbn = |location = |page = 93}}</ref>
+
+[[File:Konstantin Makovsky - The Bulgarian martyresses.jpg|thumb|upright|''The Bulgarian martyresses'' (1877) by [[Konstantin Makovsky]], a Russian propaganda painting which depicts the rape of Bulgarian women by the [[bashi-bazouk]]s during the [[April Uprising]], with the purpose of mobilizing public support for the [[Russo-Turkish War (1877–78)]].<ref>Repin, Volume 1; Igor Emanuilovich Grabar'; 1948; [https://books.google.com/books?id=WnsFAAAAMAAJ p.391] (in Russian)</ref><ref>Bulgaria today: Volume 15, Issue 4; 1966; [https://www.google.com/search?tbm=bks&tbo=1&q=%22Konstantin+Makovsky%22+%22april+uprising%22&btnG=Search+Books p.35]</ref>
+Unrestrained by the laws that governed regular soldiers in the [[Ottoman Army]], the bashi-bazouks became notorious for preying on civilians.<ref>{{Cite EB1911|wstitle=Bashi-Bazouk |volume=3 |page=465}}</ref>]]
+
+The [[Crimean War]] (1853–1856) was part of a long-running contest between the major European powers for influence over territories of the [[Decline of the Ottoman Empire|declining Ottoman Empire]]. The financial burden of the war led the Ottoman state to issue [[Ottoman public debt|foreign loans]] amounting to 5 million pounds sterling on 4 August 1854.<ref>{{cite book|author=V. Necla Geyikdagi|title=Foreign Investment in the Ottoman Empire: International Trade and Relations 1854–1914|url=https://books.google.com/books?id=fGRMOzJZ4aEC&pg=PA32|accessdate=12 February 2013|date=15 March 2011|publisher=I.B.Tauris|isbn=978-1-84885-461-1|page=32}}</ref><ref>{{cite book|author=Douglas Arthur Howard|title=The History of Turkey|url=https://books.google.com/books?id=Ay-IkMqrTp4C&pg=PA71|accessdate=11 February 2013|publisher=Greenwood Publishing Group|isbn=978-0-313-30708-9|page=71|year=2001}}</ref> The war caused an exodus of the [[Crimean Tatars]], about 200,000 of whom moved to the Ottoman Empire in continuing waves of emigration.<ref>{{cite journal|last=Williams|first=Bryan Glynn|title=Hijra and forced migration from nineteenth-century Russia to the Ottoman Empire|journal=Cahiers du Monde russe|year=2000|volume=41|issue=1|pages=79–108|url=http://monderusse.revues.org/39|doi=10.4000/monderusse.39}}</ref> Toward the end of the [[Caucasian Wars]], 90% of the [[Circassians]] were [[Ethnic cleansing of Circassians|ethnically cleansed]]<ref>Memoirs of Miliutin, "the plan of action decided upon for 1860 was to cleanse [ochistit'] the mountain zone of its indigenous population", per Richmond, W. <u>The Northwest Caucasus: Past, Present, and Future</u>. Routledge. 2008.</ref> and exiled from their homelands in the [[Caucasus]] and fled to the Ottoman Empire,<ref>{{cite book|first=Walter|last=Richmond|title=The Northwest Caucasus: Past, Present, Future|url=https://books.google.com/books?id=LQJyLvMWB8MC&pg=PA79|accessdate=11 February 2013|date=29 July 2008|publisher=Taylor & Francis US|isbn=978-0-415-77615-8|page=79|quote=the plan of action decided upon for 1860 was to cleanse [ochistit'] the mountain zone of its indigenous population}}</ref> resulting in the settlement of 500,000 to 700,000 Circassians in Turkey.<ref name="Jaimoukha2001">{{cite book|author=Amjad M. Jaimoukha|title=The Circassians: A Handbook|url=https://books.google.com/books?id=5jVmQgAACAAJ|accessdate=4 May 2013|year=2001|publisher=Palgrave Macmillan|isbn=978-0-312-23994-7}}</ref>{{page needed|date=June 2013}}<ref name="Hille2010">{{cite book|author=Charlotte Mathilde Louise Hille|title=State building and conflict resolution in the Caucasus|url=https://books.google.com/books?id=yxFP6K8iZzQC&pg=PA50|accessdate=4 May 2013|year=2010|publisher=BRILL|isbn=978-90-04-17901-1|page=50}}</ref><ref name="ChirotMcCauley2010">{{cite book|author1=Daniel Chirot|author2=Clark McCauley|title=Why Not Kill Them All?: The Logic and Prevention of Mass Political Murder (New in Paper)|url=https://books.google.com/books?id=9sPJnd0cwV0C&pg=PA23|accessdate=4 May 2013|date=1 July 2010|publisher=Princeton University Press|isbn=978-1-4008-3485-3|page=23}}</ref> Some Circassian organisations give much higher numbers, totaling 1–1.5 million deported or killed. Crimean Tartar refugees in the late 19th century played an especially notable role in seeking to modernize Ottoman education and in first promoting both Pan-Turkicism and a sense of Turkish nationalism.<ref name="ReferenceA">Stone, Norman "Turkey in the Russian Mirror" pages 86–100 from ''Russia War, Peace and Diplomacy'' edited by Mark & Ljubica Erickson, Weidenfeld & Nicolson: London, 2004 page 95.</ref>
+
+In this period, the Ottoman Empire spent only small amounts of public funds on education; for example in 1860–61 only 0.2 per cent of the total budget was invested in education.<ref>{{cite book|author=Baten, Jörg |title=A History of the Global Economy. From 1500 to the Present.|date=2016|publisher=Cambridge University Press|page=50|isbn=9781107507180}}</ref>
+As the Ottoman state attempted to modernize its infrastructure and army in response to threats from the outside, it also opened itself up to a different kind of threat: that of creditors. Indeed, as the historian Eugene Rogan has written, "the single greatest threat to the independence of the Middle East" in the nineteenth century "was not the armies of Europe but its banks."<ref>{{Cite book|title = The Arabs: A History|last = Rogan|first = Eugene|publisher = Penguin|year = 2011|isbn = |location = |page = 105}}</ref> The Ottoman state, which had begun taking on debt with the Crimean War, was forced to declare bankruptcy in 1875.<ref name="auto1">{{Cite book|title = The Arabs: A History|last = Rogan|first = Eugene|publisher = Penguin|year = 2011|isbn = |location = |page = 106}}</ref> By 1881, the Ottoman Empire agreed to have its debt controlled by an institution known as the [[Ottoman Public Debt Administration]], a council of European men with presidency alternating between France and Britain. The body controlled swaths of the Ottoman economy, and used its position to ensure that European capital continued to penetrate the empire, often to the detriment of local Ottoman interests.<ref name="auto1"/>
+
+The Ottoman [[bashi-bazouk]]s brutally suppressed the [[April Uprising|Bulgarian uprising]] of 1876, massacring up to 100,000 people in the process.<ref>{{cite book |title=The Establishment of the Balkan National States, 1804–1920 |first1=Charles |last1=Jelavich |first2=Barbara |last2=Jelavich |year=1986 |url=https://books.google.com/?id=LBYriPYyfUoC&pg=PA139&dq=massacre+bulgarians++1876#v=onepage&q&f=false |page=139|isbn=978-0-295-80360-9}}</ref> The [[Russo-Turkish War (1877–78)]] ended with a decisive victory for Russia. As a result, Ottoman holdings in Europe declined sharply: [[Principality of Bulgaria|Bulgaria]] was established as an independent principality inside the Ottoman Empire; [[United Principalities|Romania]] achieved full independence; and [[History of Serbia|Serbia]] and [[Montenegro]] finally gained complete independence, but with smaller territories. In 1878, [[Austria-Hungary]] unilaterally occupied the Ottoman provinces of [[Bosnia Vilayet|Bosnia-Herzegovina]] and [[Sanjak of Novi Pazar|Novi Pazar]].
+
+[[Prime Minister of the United Kingdom|British Prime Minister]] [[Benjamin Disraeli]] advocated for restoring the Ottoman territories on the Balkan Peninsula during the [[Congress of Berlin]], and in return Britain assumed the administration of [[Cyprus]] in 1878.<ref>{{cite book|last=Taylor|first=A.J.P.|authorlink=A. J. P. Taylor|title=The Struggle for Mastery in Europe, 1848–1918|year=1955|publisher=Oxford University Press|location=Oxford|isbn=978-0-19-822101-2|pages=228–54}}</ref> Britain later sent troops to [[Egypt]] in 1882 to put down the [[Urabi Revolt]] – Sultan [[Abdul Hamid II]] was too paranoid to mobilize his own army, fearing this would result in a coup d'état – effectively gaining control in both territories. Abdul Hamid II, popularly known as "Abdul Hamid the Damned" on the account of his cruelty and paranoia, was so fearful of the threat of a coup that he did not allow his army to conduct war games, lest this serve as the cover for a coup, but he did see the need for military mobilization. In 1883, a German military mission under General Baron [[Colmar Freiherr von der Goltz|Colmar von der Goltz]] arrived to train the Ottoman Army, leading to the so-called "Goltz generation" of German-trained officers who were to play a notable role in the politics of the last years of the empire.<ref>Akmeșe, Handan Nezir ''The Birth of Modern Turkey The Ottoman Military and the March to World I'', London: I.B Tauris page 24</ref>
+
+From 1894 to 1896, between 100,000 and 300,000 Armenians living throughout the empire were killed in what became known as the [[Hamidian massacres]].<ref>{{cite book|last=Akçam|first=Taner|title=A Shameful Act: The Armenian Genocide and the Question of Turkish Responsibility|year=2006|publisher=Metropolitan Books|location=New York|isbn=0-8050-7932-7|page=42|authorlink=Taner Akçam}}</ref>
+
+As the Ottoman Empire gradually shrank in size, some 7–9 million Muslims from its former territories in the [[Caucasus]], [[Crimea]], [[Balkans]], and the [[Mediterranean]] islands migrated to [[Anatolia]] and [[Eastern Thrace]].<ref name="Karpat2004">{{cite book|author=Kemal H Karpat|title=Studies on Turkish politics and society: selected articles and essays|url=https://books.google.com/books?id=cL4Ua6gGyWUC|accessdate=24 May 2013|year=2004|publisher=BRILL|isbn=978-90-04-13322-8}}</ref> After the Empire lost the [[First Balkan War]] (1912–13), it lost all its [[Balkan peninsula|Balkan]] territories except [[East Thrace]] (European Turkey). This resulted in around 400,000 Muslims fleeing with the retreating Ottoman armies (with many dying from cholera brought by the soldiers), and with some 400,000 non-Muslims fleeing territory still under Ottoman rule.<ref>{{cite journal|place=NL |format=PDF |url=http://tulp.leidenuniv.nl/content_docs/wap/ejz18.pdf |archiveurl=https://web.archive.org/web/20070716155929/http://tulp.leidenuniv.nl/content_docs/wap/ejz18.pdf |archivedate=16 July 2007 |title=Greek and Turkish refugees and deportees 1912–1924 |page=1 |publisher=[[Universiteit Leiden]] |ref=harv |deadurl=yes |df= }}</ref> [[Justin McCarthy (American historian)|Justin McCarthy]] estimates that during the period 1821 to 1922 several million Muslims died in the Balkans, with the expulsion of a similar number.<ref name="McCarthy1995">{{cite book|author=Justin McCarthy|title=Death and exile: the ethnic cleansing of Ottoman Muslims, 1821–1922|url=https://books.google.com/books?id=1ZntAAAAMAAJ|accessdate=1 May 2013|year=1995|publisher=Darwin Press|isbn=978-0-87850-094-9}}</ref><ref name="Carmichael2012">{{cite book|last = Carmichael|first = Cathie|title = Ethnic Cleansing in the Balkans: Nationalism and the Destruction of Tradition|url = https://books.google.com/books?id=ybORI4KWwdIC|accessdate = 1 May 2013|date = 12 November 2012|publisher = Routledge|isbn = 978-1-134-47953-5|quote = During the period from 1821 to 1922 alone, Justin McCarthy estimates that the ethnic cleansing of Ottoman Muslims led to the death of several million individuals and the expulsion of a similar number.|page = 21}}</ref><ref name="Buturovic2010">{{cite book|last=Buturovic|first=Amila|title=Islam in the Balkans: Oxford Bibliographies Online Research Guide|url=https://books.google.com/books?id=Kck_-B7MubIC|accessdate=1 May 2013|date=1 May 2010|publisher=Oxford University Press|isbn=978-0-19-980381-1|page=9}}</ref>
+
+<gallery mode="packed" heights="130px">
+File:Friday Procession.jpg|Sultan [[Abdul Hamid II]] going to the Friday Prayer (Friday Procession)
+File:Opening ceremony of the First Ottoman Parliament at the Dolmabahce Palace in 1876.jpg|Opening ceremony of the First [[Ottoman Parliament]] at the [[Dolmabahçe Palace]] in 1876. The [[First Constitutional Era (Ottoman Empire)|First Constitutional Era]] lasted for only two years until 1878. The Ottoman Constitution and Parliament were [[Second Constitutional Era (Ottoman Empire)|restored 30 years later]] with the [[Young Turk Revolution]] in 1908.
+File:Turkish troops storming Fort Shefketil (cropped).jpg|Turkish troops storming [[Shekvetili|Fort Shefketil]] during the [[Crimean War]] of 1853–1856
+File:The ruined gateway of Prince Eugene, Belgrade.jpg|[[Belgrade]], c. 1865. In 1867, [[British Empire|Britain]] and [[Second French Empire|France]] forced the Ottoman military to retreat from northern [[Serbia]], securing its ''de facto'' independence (formalized after the [[Russo-Turkish War (1877–78)|Russo-Turkish War of 1877–78]] and the [[Congress of Berlin]] in 1878.)
+</gallery>
+
+=== Defeat and dissolution (1908–1922) ===
+{{Main|Defeat and dissolution of the Ottoman Empire|History of the Ottoman Empire during World War I}}
+[[File:Le Petir Journal, Proclamation of Mehmed V.jpg|thumb|upright=0.8|[[Mehmed V]] was proclaimed Sultan of the Ottoman Empire after the [[Young Turk Revolution]]]]
+
+The [[defeat and dissolution of the Ottoman Empire]] (1908–1922) began with the [[Second Constitutional Era]], a moment of hope and promise established with the [[Young Turk Revolution]]. It restored the [[Ottoman constitution of 1876]] and brought in [[List of political parties in the Ottoman Empire|multi-party politics]] with a [[Elections in the Ottoman Empire|two-stage electoral system]] ([[Ottoman electoral law|electoral law]]) under the [[General Assembly of the Ottoman Empire|Ottoman parliament]]. The constitution offered hope by freeing the empire’s citizens to modernize the state’s institutions, rejuvenate its strength, and enable it to hold its own against outside powers. Its guarantee of liberties promised to dissolve inter-communal tensions and transform the empire into a more harmonious place.<ref>{{harvnb|Reynolds|2011|p= 1}}</ref> Instead, this period became the story of the twilight struggle of the Empire.
+
+[[File:Declaration of the 1908 Revolution in Ottoman Empire.png|thumb|upright=0.9|left|Declaration of the [[Young Turk Revolution]] by the leaders of the Ottoman [[Millet (Ottoman Empire)|millets]] in 1908]]
+[[File:Sultanvahideddin.jpg|thumb|upright=0.9|left|[[Mehmed VI]], the last Sultan of the Ottoman Empire, leaving the country after the [[Abolition of the Ottoman Sultanate|abolition of the Ottoman sultanate]], 17 November 1922]]
+
+Members of [[Young Turks]] movement who had once gone underground now established their parties.<ref>{{Harvard citation|Erickson|2013|p=32}}</ref> Among them “[[Committee of Union and Progress]],” and “[[Freedom and Accord Party]]” were major parties. On the other end of the spectrum were ethnic parties which included [[Jewish Social Democratic Labour Party in Palestine (Poale Zion)|Poale Zion]], [[Al-Fatat]], and [[Armenian national movement]] organized under [[Armenian Revolutionary Federation]]. Profiting from the civil strife, [[Austria-Hungary]] officially annexed [[Bosnia and Herzegovina]] in 1908. The last of the [[Census in the Ottoman Empire|Ottoman censuses]] was performed in [[1914 population statistics for the Ottoman Empire|1914]]. Despite [[Ottoman military reforms|military reforms]] which reconstituted the [[Ottoman Modern Army]], the Empire lost its North African territories and the Dodecanese in the [[Italo-Turkish War]] (1911) and almost all of its European territories in the [[Balkan Wars]] (1912–1913). The Empire faced continuous unrest in the years leading up to [[World War I]], including the [[Ottoman countercoup of 1909]], the [[31 March Incident]] and two further coups in [[1912 Ottoman coup d'état|1912]] and [[1913 Ottoman coup d'état|1913]].
+
+The [[history of the Ottoman Empire during World War I]] began with the [[Ottoman entry into World War I|Ottoman surprise attack]] on the Russian Black Sea coast on 29 October 1914. Following the attack, Russia and its allies, France and Britain, declared war on the Ottomans. There were several important Ottoman victories in the early years of the war, such as the [[Battle of Gallipoli]] and the [[Siege of Kut]].
+
+[[File:Morgenthau336.jpg|thumb|The [[Armenian Genocide]] was the Ottoman government's systematic extermination of its Armenian subjects. An estimated 1.5 million people were killed.]]
+
+In 1915 the Ottoman government started the extermination of its ethnic Armenian population, resulting in the death of approximately 1.5 million Armenians in the [[Armenian Genocide]].<ref>{{cite book|author=Peter Balakian|title=The Burning Tigris|url=https://books.google.com/books?id=DrYoyAM3PBYC&pg=PR17|accessdate=8 June 2013|date=13 October 2009|publisher=HarperCollins|isbn=978-0-06-186017-1|page=xvii}}</ref> The genocide was carried out during and after [[World War I]] and implemented in two phases: the wholesale killing of the able-bodied male population through massacre and subjection of army conscripts to forced labor, followed by the deportation of women, children, the elderly and infirm on [[death march]]es leading to the [[Syrian desert]]. Driven forward by military escorts, the deportees were deprived of food and water and subjected to periodic robbery, rape, and systematic massacre.<ref>{{Citation|first1=Hans-Lukas|last1=Kieser|first2=Dominik J.|last2=Schaller|language=German|title=Der Völkermord an den Armeniern und die Shoah|trans-title=The Armenian genocide and the Shoah|publisher=Chronos|year=2002|isbn=3-0340-0561-X|page=114}}</ref><ref>{{Citation |title = Armenia: The Survival of A Nation |first = Christopher J. |last = Walker |publisher = Croom Helm |place = London |year = 1980 |pages = 200–3}}</ref><ref>{{Citation |title = The Treatment of Armenians in the Ottoman Empire, 1915–1916: Documents Presented to Viscount Grey of Falloden |first1 = Viscount James |last1 = Bryce |authorlink= James Bryce, 1st Viscount Bryce |first2 = Arnold |last2 = Toynbee |edition = uncensored |editor-first = Ara |editor-last = Sarafian |place = Princeton, [[New Jersey|NJ]] |publisher = [[Gomidas Institute]] |year = 2000 |isbn = 0-9535191-5-5 |pages = 635–49}}</ref> Large-scale massacres were also committed against the Empire's [[Greek genocide|Greek]] and [[Assyrian genocide|Assyrian]] minorities as part of the same campaign of ethnic cleansing.<ref>{{cite journal|doi=10.1080/14623520801950820|last1=Schaller|first1=Dominik J|last2=Zimmerer|first2=Jürgen|year=2008|title=Late Ottoman genocides: the dissolution of the Ottoman Empire and Young Turkish population and extermination policies&nbsp;– introduction|journal=Journal of Genocide Research|volume=10|issue=1|pages=7–14|url=http://bridging-the-divide.org/sites/default/files/files/Late%20Ottoman%20genocides-%20the%20dissolution%20of%20the%20Ottoman%20Empire%20and%20Young%20Turkish%20population%20and%20extermination%20policies%281%29.pdf|quote=The genocidal quality of the murderous campaigns against Greeks and Assyrians is obvious|postscript=<!-- Bot inserted parameter. Either remove it; or change its value to "." for the cite to end in a ".", as necessary. -->{{inconsistent citations}}}}{{dead link|date=December 2017 |bot=InternetArchiveBot |fix-attempted=yes }}</ref>
+
+The [[Arab Revolt]] began in 1916 and turned the tide against the Ottomans on the Middle Eastern front, where they seemed to have the upper hand during the first two years of the war. The [[Armistice of Mudros]] was signed on 30 October 1918, setting the [[partition of the Ottoman Empire]] under the terms of the [[Treaty of Sèvres]]. This treaty, as designed in the [[Conference of London (1920)|conference of London]], allowed the Sultan to retain his position and title. The [[occupation of Constantinople]] and [[occupation of İzmir|İzmir]] led to the establishment of a [[Turkish national movement]], which won the [[Turkish War of Independence]] (1919–23) under the leadership of [[Mustafa Kemal Atatürk|Mustafa Kemal]] (later given the surname "Atatürk"). The [[Abolition of the Ottoman Sultanate|sultanate was abolished]] on 1 November 1922, and the last sultan, [[Mehmed VI]] (reigned 1918–22), left the country on 17 November 1922. The [[Ottoman Caliphate|caliphate]] was abolished on 3 March 1924.<ref name="Ozoglu">{{cite book|author=Hakan Ozoglu|title=From Caliphate to Secular State: Power Struggle in the Early Turkish Republic|url=https://books.google.com/books?id=Cw5V1c1ej_cC&pg=PA8|accessdate=8 June 2013|date=24 June 2011|publisher=ABC-CLIO|isbn=978-0-313-37957-4|page=8}}</ref>
+
+== Historical debate on the origins and nature of the Ottoman state ==
+{{main|Gaza Thesis}}
+{{one source|section|date=May 2017}}
+Several historians such as British historian [[Edward Gibbon]] and the Greek historian Dimitri Kitzikis have argued that after the fall of Constantinople, the Ottoman state took over the machinery of the Roman state, and that in essence the Ottoman Empire was a continuation of the Eastern Roman Empire under a thin Turkish Islamic guise.<ref>Stone, Norman "Turkey in the Russian Mirror" pages 86–100 from ''Russia War, Peace and Diplomacy'' edited by Mark & Ljubica Erickson, Weidenfeld & Nicolson: London, 2004 pages 92–93</ref> Kitzikis called the Ottoman state "a Greek-Turkish condominium".<ref name="Stone pages 86-100">Stone, Norman "Turkey in the Russian Mirror" pages 86–100 from ''Russia War, Peace and Diplomacy'' edited by Mark & Ljubica Erickson, Weidenfeld & Nicolson: London, 2004 page 93</ref> The American historian [[Speros Vryonis]] wrote that the Ottoman state was centered on "a Byzantine-Balkan base with a veneer of the Turkish language and the Islamic religion".<ref name="Stone pages 86-100"/> Other historians have followed the lead of the Austrian historian [[Paul Wittek]] who emphasized the Islamic character of the Ottoman state, seeing the Ottoman state as a "Jihad state" dedicated to expanding the world of Islam.<ref name="Stone pages 86-100"/> Another group of historians led by the Turkish historian M. Fuat Koprulu championed the "''[[Ghazi (warrior)|gazi]]'' thesis" that saw the Ottoman state as a continuation of the way of life of the [[nomad]]ic [[Turkic peoples|Turkic tribes]] who had come from East Asia to Anatolia via Central Asia and the Middle East on a much larger scale, and argued that the most important cultural influences on the Ottoman state came from Persia.<ref name="Stone pages 86-100"/> More recently, the American historian [[Heath Lowry]] called the Ottoman state a "predatory confederacy" led in equal parts by Turks and Greeks converted to Islam.<ref name="Stone pages 86-100"/> 
+        
+The British historian [[Norman Stone]] suggested many continuities between the Eastern Roman and Ottoman empires such as the ''zeugarion'' tax of Byzantium becoming the Ottoman ''Resm-i çift'' tax, the ''[[pronoia]]'' land-holding system that linked the amount of land one owned with one's ability to raise cavalry becoming the Ottoman ''[[timar]]'' system, and the Ottoman measurement for land the ''donum'' was the same as the Byzantine ''stremma''. Stone also pointed out that despite the fact that Sunni Islam was the state religion, the [[Eastern Orthodox Church]] was supported and controlled by the Ottoman state, and in return to accepting that control became the largest land-holder in the Ottoman Empire. Despite the similarities, Stone argued that a crucial difference was that the land grants under the ''timar'' system were not hereditary at first. Even after land grants under the ''timar'' system became inheritable, land ownings in the Ottoman Empire remained highly insecure, and the sultan could and did revoke land grants whenever he wished.{{citation needed|date=April 2017}} Stone argued this insecurity in land tenure strongly discouraged ''[[Timariot]]s'' from seeking long-term development of their land, and instead led the ''timariots'' to adopt a strategy of short term exploitation, which ultimately had deleterious effects on the Ottoman economy.<ref>Stone, Norman "Turkey in the Russian Mirror" pages 86–100 from ''Russia War, Peace and Diplomacy'' edited by Mark & Ljubica Erickson, Weidenfeld & Nicolson: London, 2004 pages 94–95</ref>
+
+== Government ==
+{{Main|State organisation of the Ottoman Empire}}
+[[File:Jean Baptiste Vanmour - Dinner at the Palace in Honour of an Ambassador - Google Art Project.jpg|thumb|Ambassadors at the [[Topkapı Palace]]]]
+
+Before the reforms of the 19th and 20th centuries, the [[state organisation of the Ottoman Empire]] was a system with two main dimensions, the military administration and the civil administration. The Sultan was the highest position in the system. The civil system was based on local administrative units based on the region's characteristics. The state had control over the clergy. Certain pre-Islamic Turkish traditions that had survived the adoption of administrative and legal practices from Islamic [[Iran]] remained important in Ottoman administrative circles.{{sfn|Itzkowitz|1980|p = 38}} According to Ottoman understanding, the state's primary responsibility was to defend and extend the land of the Muslims and to ensure security and harmony within its borders in the overarching context of [[Sunni|orthodox]] Islamic practice and dynastic sovereignty.<ref name="Kapucu">{{cite book|author1=Naim Kapucu|author2=Hamit Palabiyik|title=Turkish Public Administration: From Tradition to the Modern Age|url=https://books.google.com/books?id=DWceNjwTggUC&pg=PA77|accessdate=11 February 2013|year=2008|publisher=USAK Books|isbn=978-605-4030-01-9|page=77}}</ref>
+
+The Ottoman Empire, or as a dynastic institution, the [[Ottoman dynasty|House of Osman]], was unprecedented and unequaled in the Islamic world for its size and duration.<ref>{{cite book|last=Black|first=Antony|title=The History of Islamic Political Thought: From the Prophet to the Present|url=https://books.google.com/books?id=nspmqLKPU-wC&pg=PA199|accessdate=11 February 2013|year=2001|publisher=Psychology Press|isbn=978-0-415-93243-1|page=199}}</ref> In Europe, only the [[House of Habsburg]] had a similarly unbroken line of sovereigns (kings/emperors) from the same family who ruled for so long, and during the same period, between the late 13th and early 20th centuries. The Ottoman dynasty was Turkish in origin. On eleven occasions, the sultan was deposed (replaced by another sultan of the Ottoman dynasty, who were either the former sultan's brother, son or nephew) because he was perceived by his enemies as a threat to the state. There were only two attempts in Ottoman history to unseat the ruling Ottoman dynasty, both failures, which suggests a political system that for an extended period was able to manage its revolutions without unnecessary instability.<ref name="Kapucu"/> As such, the last Ottoman sultan [[Mehmed VI]] (r. 1918–1922) was a [[List of sultans of the Ottoman Empire|direct patrilineal (male-line) descendant]] of the first Ottoman sultan [[Osman I]] (d. 1323/4), which was unparallelled in both Europe (e.g. the male line of the [[House of Habsburg]] became extinct in 1740) and in the Islamic world. The primary purpose of the [[Imperial Harem]] was to ensure the birth of male heirs to the Ottoman throne and secure the continuation of the direct patrilineal (male-line) descendance of the Ottoman sultans.
+
+[[File:Thomas allom, c1840, The Enterance to Divan.png|thumb|left|''Bâb-ı Âlî'', the [[Ottoman Porte|Sublime Porte]]]]
+
+The highest position in Islam, ''[[caliphate]]'', was claimed by the sultans starting with [[Murad I]],<ref name="Lambton">{{cite book |last1=Lambton |first1=Ann |author-link1=Ann Lambton |last2=Lewis |first2=Bernard |author-link2=Bernard Lewis |title=The Cambridge History of Islam: The Indian sub-continent, South-East Asia, Africa and the Muslim west |volume=2 |url=https://books.google.com/books?id=4AuJvd2Tyt8C |page=320 |publisher=Cambridge University Press |year=1995 |isbn=978-0-521-22310-2|access-date=}}</ref> which was established as [[Ottoman Caliphate]]. The Ottoman sultan, ''[[Padishah|pâdişâh]]'' or "lord of kings", served as the Empire's sole regent and was considered to be the embodiment of its government, though he did not always exercise complete control. The [[Imperial Harem]] was one of the most important powers of the Ottoman court. It was ruled by the [[Valide Sultan]]. On occasion, the Valide Sultan would become involved in state politics. For a time, the women of the Harem effectively controlled the state in what was termed the "[[Sultanate of the women|Sultanate of Women]]". New sultans were always chosen from the sons of the previous sultan.{{dubious|reason= this is demonstrably not true, just look at any list of sultans |date=September 2016}} The strong educational system of the [[palace school]] was geared towards eliminating the unfit potential heirs, and establishing support among the ruling elite for a successor. The palace schools, which would also educate the future administrators of the state, were not a single track. First, the [[Madrasa]] (''{{lang-ota|Medrese}}'') was designated for the Muslims, and educated scholars and state officials according to Islamic tradition. The financial burden of the Medrese was supported by vakifs, allowing children of poor families to move to higher social levels and income.<ref>{{cite book|last=Lewis|first=Bernard|title=Istanbul and the Civilization of the Ottoman Empire|url=https://books.google.com/books?id=7FQRrbUMojcC&pg=PA151|accessdate=11 February 2013|year=1963|publisher=University of Oklahoma Press|isbn=978-0-8061-1060-8|page=151}}</ref> The second track was a free [[boarding school]] for the Christians, the ''[[Enderûn]]'',<ref>{{cite journal|title=The Ottoman Palace School Enderun and the Man with Multiple Talents, Matrakçı Nasuh|journal=Journal of the Korea Society of Mathematical Education, Series D|date=March 2010|volume=14|issue=1|pages=19–31|url=https://tamu.academia.edu/SencerCorlu/Papers/471488/The_Ottoman_Palace_School_Enderun_and_the_Man_with_Multiple_Talents_Matrakci_Nasuh|series=Research in Mathematical Education}}</ref> which recruited 3,000 students annually from Christian boys between eight and twenty years old from one in forty families among the communities settled in [[Rumelia]] or the Balkans, a process known as [[Devshirme in the Ottoman Palace School|Devshirme]] (''{{lang|ota|Devşirme}}'').<ref>{{cite book|last=Karpat|first=Kemal H.|title=Social Change and Politics in Turkey: A Structural-Historical Analysis|url=https://books.google.com/books?id=rlhD9SjavRcC&pg=PA204|accessdate=11 February 2013|year=1973|publisher=BRILL|isbn=978-90-04-03817-2|page=204}}</ref>
+
+Though the sultan was the supreme monarch, the sultan's political and executive authority was delegated. The politics of the state had a number of advisors and ministers gathered around a council known as [[Divan]]. The Divan, in the years when the Ottoman state was still a ''[[Bey]]lik'', was composed of the elders of the tribe. Its composition was later modified to include military officers and local elites (such as religious and political advisors). Later still, beginning in 1320, a [[Grand Vizier]] was appointed to assume certain of the sultan's responsibilities. The Grand Vizier had considerable independence from the sultan with almost unlimited powers of appointment, dismissal and supervision. Beginning with the late 16th century, sultans withdrew from politics and the Grand Vizier became the ''de facto'' head of state.<ref name="Black p199"/>
+
+[[File:Yusuf Ziya Paşa.jpg|thumb|[[Yusuf Ziya Pasha]], Ottoman ambassador to the [[United States]], in [[Washington, D.C.|Washington]], 1913]]
+
+Throughout Ottoman history, there were many instances in which local governors acted independently, and even in opposition to the ruler. After the Young Turk Revolution of 1908, the Ottoman state became a constitutional monarchy. The sultan no longer had executive powers. A parliament was formed, with representatives chosen from the provinces. The representatives formed the [[Imperial Government of the Ottoman Empire]].
+
+This eclectic administration was apparent even in the diplomatic correspondence of the Empire, which was initially undertaken in the [[Greek language]] to the west.<ref>{{cite book|author1=Naim Kapucu|author2=Hamit Palabiyik|title=Turkish Public Administration: From Tradition to the Modern Age|url=https://books.google.com/books?id=DWceNjwTggUC&pg=PA78|accessdate=12 February 2013|year=2008|publisher=USAK Books|isbn=978-605-4030-01-9|page=78}}</ref>
+
+The [[Tughra]] were calligraphic monograms, or signatures, of the Ottoman Sultans, of which there were 35. Carved on the Sultan's seal, they bore the names of the Sultan and his father. The statement and prayer, "ever victorious," was also present in most. The earliest belonged to [[Orhan|Orhan Gazi]]. The ornately stylized ''Tughra'' spawned a branch of Ottoman-Turkish [[calligraphy]].
+
+=== Law ===
+{{Main|Ottoman law}}
+The Ottoman legal system accepted the [[religious law]] over its subjects. At the same time the ''[[Qanun (law)|Qanun]]'' (or ''Kanun''), a secular legal system, co-existed with religious law or [[Sharia]].<ref name=otmkanun>{{cite web|title=Balancing Sharia: The Ottoman Kanun|url=http://www.bbc.co.uk/religion/0/24365067|publisher=BBC|accessdate=5 October 2013}}</ref> The Ottoman Empire was always organized around a system of local [[jurisprudence]]. Legal administration in the Ottoman Empire was part of a larger scheme of balancing central and local authority.<ref name="Benton 109-110">{{cite book|last=Benton|first=Lauren|title=Law and Colonial Cultures: Legal Regimes in World History, 1400–1900|url=https://books.google.com/books?id=rZtjR9JnwYwC&pg=109|accessdate=11 February 2013|date=3 December 2001|publisher=Cambridge University Press|isbn=978-0-521-00926-3|pages=109–110}}</ref> Ottoman power revolved crucially around the administration of the rights to land, which gave a space for the local authority to develop the needs of the local [[Millet (Ottoman Empire)|millet]].<ref name="Benton 109-110"/> The jurisdictional complexity of the Ottoman Empire was aimed to permit the integration of culturally and religiously different groups.<ref name="Benton 109-110"/> The Ottoman system had three court systems: one for Muslims, one for non-Muslims, involving appointed Jews and Christians ruling over their respective religious communities, and the "trade court". The entire system was regulated from above by means of the administrative ''Qanun'', i.e. laws, a system based upon the Turkic ''[[Yassa]]'' and ''[[Töre (law)|Töre]]'', which were developed in the pre-Islamic era.{{citation needed|date=February 2013}}
+
+[[File:1879-Ottoman Court-from-NYL.png|thumb|left|An Ottoman trial, 1877]]
+
+These court categories were not, however, wholly exclusive: for instance, the Islamic courts, which were the Empire's primary courts, could also be used to settle a trade conflict or disputes between litigants of differing religions, and Jews and Christians often went to them to obtain a more forceful ruling on an issue. The Ottoman state tended not to interfere with non-Muslim religious law systems, despite legally having a voice to do so through local governors. The Islamic ''Sharia'' law system had been developed from a combination of the [[Qur'an]]; the [[Hadith|Hadīth]], or words of the prophet [[Muhammad in Islam|Muhammad]]; ''[[ijma|ijmā']]'', or consensus of the members of the [[Ummah|Muslim community]]; [[qiyas]], a system of analogical reasoning from earlier precedents; and local customs. Both systems were taught at the Empire's law schools, which were in [[Istanbul]] and [[Bursa]].
+
+[[File:Zibik.jpg|thumb|An unhappy wife complains to the [[Qadi]] about her husband's impotence, [[Ottoman miniature]].]]
+
+The Ottoman Islamic legal system was set up differently from traditional European courts. Presiding over Islamic courts would be a ''Qadi'', or judge. Since the closing of the ''[[ijtihad]]'', or ''Gate of Interpretation, Qadis ''throughout the Ottoman Empire focused less on legal precedent, and more with local customs and traditions in the areas that they administered.<ref name="Benton 109-110"/> However, the Ottoman court system lacked an appellate structure, leading to jurisdictional case strategies where plaintiffs could take their disputes from one court system to another until they achieved a ruling that was in their favor.
+
+In the late 19th century, the Ottoman legal system saw substantial reform. This process of legal modernization began with the [[Edict of Gülhane]] of 1839.<ref name="review-niza">{{cite web|title=Review of "Ottoman Nizamiye Courts. Law and Modernity"|url=http://research.sabanciuniv.edu/19475/1/Avi_Rubin_Ottoman_Nizamiye_Courts_Somel.pdf|publisher=Sabancı Üniversitesi|author=Selçuk Akşin Somel|page=2}}</ref> These reforms included the "fair and public trial[s] of all accused regardless of religion," the creation of a system of "separate competences, religious and civil," and the validation of testimony on non-Muslims.<ref name="int-handbook"/> Specific land codes (1858), civil codes (1869–1876), and a code of civil procedure also were enacted.<ref name="int-handbook">{{cite web |title=Middle East |url=http://epstein.usc.edu/research/MiddleEast.pdf |work=Legal Traditions and Systems: an International Handbook |publisher=Greenwood Press |last1=Epstein |first1=Lee |last2=O'Connor |first2=Karen |last3=Grub |first3=Diana |pages=223–224 |deadurl=yes |archiveurl=https://web.archive.org/web/20130525015655/http://epstein.usc.edu/research/MiddleEast.pdf |archivedate=25 May 2013 |df=dmy-all }}</ref>
+
+These reforms were based heavily on French models, as indicated by the adoption of a three-tiered court system. Referred to as [[Nizamiye]], this system was extended to the local magistrate level with the final promulgation of the [[Mecelle]], a civil code that regulated marriage, divorce, alimony, will, and other matters of personal status.<ref name="int-handbook"/> In an attempt to clarify the division of judicial competences, an administrative council laid down that religious matters were to be handled by religious courts, and statute matters were to be handled by the Nizamiye courts.<ref name="int-handbook"/>
+
+=== Military ===
+{{Main|Military of the Ottoman Empire}}
+[[File:Walka o sztandar turecki.jpg|thumb|left|Ottoman [[sipahi]]s in battle, holding the crescent banner (by [[Józef Brandt]])]]
+[[File:Zapotocny.jpg|thumb|Ottoman officers in Istanbul, 1897]]
+[[File:Nizami-cedid-ordusu.jpg|thumb|left|[[Selim III]] watching the parade of his new army, the ''[[Nizam-i Djedid|Nizam-ı Cedid]]'' (New Order) troops, in 1793]]
+[[File:Turkish pilots in 1912.jpg|thumb|[[Ottoman Air Force|Ottoman pilots]] in early 1912]]
+[[File:Ahmet_Ali_Celikten_in_flight_suit.jpg|thumb|upright|[[Ahmet Ali Çelikten]] is amongst the first black military pilots in history, clearly showing military diversification in the Ottoman Empire.]]
+[[File:Soldiers 1900.png|thumb|upright|The [[Military of the Ottoman Empire|Ottoman Imperial Army]] in 1900]]
+
+The first military unit of the Ottoman State was an army that was organized by [[Osman I]] from the tribesmen inhabiting the hills of western Anatolia in the late 13th century. The military system became an intricate organization with the advance of the Empire. The Ottoman military was a complex system of recruiting and fief-holding. The main corps of the [[Ottoman Army]] included [[Janissary]], [[Sipahi]], [[Akinci|Akıncı]] and [[Ottoman military band|Mehterân]]. The Ottoman army was once among the most advanced fighting forces in the world, being one of the first to use muskets and cannons. The Ottoman Turks began using ''[[Falconet (cannon)|falconets]]'', which were short but wide cannons, during the [[Siege of Constantinople (1422)|Siege of Constantinople]]. The Ottoman cavalry depended on high speed and mobility rather than heavy armour, using bows and short swords on fast [[Turkoman horse|Turkoman]] and [[Arabian horse|Arabian]] horses (progenitors of the [[Thoroughbred#Foundation stallions|Thoroughbred]] racing horse),<ref>{{cite book|last=Milner|first=Mordaunt|title=The Godolphin Arabian: The Story of the Matchem Line|year=1990|publisher=Robert Hale Limited|isbn=978-0-85131-476-1|pages=3–6}}</ref><ref>{{cite book|last=Wall|first=John F|title=Famous Running Horses: Their Forebears and Descendants|isbn=978-1-163-19167-5|page=8}}</ref> and often applied tactics similar to those of the [[Mongol Empire]], such as pretending to retreat while surrounding the enemy forces inside a crescent-shaped formation and then making the real attack. The Ottoman army continued to be an effective fighting force throughout the seventeenth and early eighteenth centuries,<ref>{{cite book |last=Murphey |first=Rhoads |title=Ottoman Warfare, 1500–1700 |date=1999 |publisher=UCL Press |page=10}}
+* {{cite book |last=Ágoston |first=Gábor |title=Guns for the Sultan: Military Power and the Weapons Industry in the Ottoman Empire |publisher=Cambridge University Press |date=2005 |pages= 200–2}}</ref> falling behind the empire's European rivals only during a long period of peace from 1740–1768.<ref name=AksanOW/>
+
+The modernization of the Ottoman Empire in the 19th century started with the military. In 1826 Sultan [[Mahmud II]] abolished the Janissary corps and established the modern Ottoman army. He named them as the [[Nizam-ı Cedid]] (New Order). The Ottoman army was also the first institution to hire foreign experts and send its officers for training in western European countries. Consequently, the [[Young Turks]] movement began when these relatively young and newly trained men returned with their education.
+
+The [[Ottoman Navy]] vastly contributed to the expansion of the Empire's territories on the European continent. It initiated the conquest of North Africa, with the addition of [[Algeria]] and [[Egypt]] to the Ottoman Empire in 1517. Starting with the loss of [[Greece]] in 1821 and Algeria in 1830, Ottoman naval power and control over the Empire's distant overseas territories began to decline. Sultan [[Abdülaziz]] (reigned 1861–1876) attempted to reestablish a strong Ottoman navy, building the largest fleet after those of Britain and France. The shipyard at Barrow, England, built its first [[submarine]] in 1886 for the Ottoman Empire.<ref name="first submarine at shipyard">{{cite web|url=http://www.ellesmereportstandard.co.uk/latest-north-west-news/Petition-created-for-submarine-name.4001190.jp |archiveurl=https://web.archive.org/web/20080423225019/http://www.ellesmereportstandard.co.uk/latest-north-west-news/Petition-created-for-submarine-name.4001190.jp |archivedate=23 April 2008 |title=Petition created for submarine name |publisher=Ellesmere Port Standard |accessdate=11 February 2013 |deadurl=yes |df= }}</ref>
+
+[[File:Ottoman Navy at the Golden Horn.jpg|thumb|left|A German postcard depicting the [[Ottoman Navy]] at the [[Golden Horn]] in the early stages of [[World War I]]. At top left is a portrait of Sultan [[Mehmed V]].]]
+
+However, the collapsing Ottoman economy could not sustain the fleet's strength for too long. Sultan [[Abdülhamid II]] distrusted the admirals who sided with the reformist [[Midhat Pasha]], and claimed that the large and expensive fleet was of no use against the Russians during the [[Russo-Turkish War (1877–78)|Russo-Turkish War]]. He locked most of the fleet inside the [[Golden Horn]], where the ships decayed for the next 30 years. Following the [[Young Turk Revolution]] in 1908, the [[Committee of Union and Progress]] sought to develop a strong Ottoman naval force. The ''Ottoman Navy Foundation'' was established in 1910 to buy new ships through public donations.
+
+The establishment of [[Ottoman Air Force|Ottoman military aviation]] dates back to between June 1909 and July 1911.<ref>{{cite web|url=http://www.turkeyswar.com/aviation/aviation.htm |archiveurl=https://web.archive.org/web/20120512225046/http://www.turkeyswar.com/aviation/aviation.htm |archivedate=12 May 2012 |title=Story of Turkish Aviation |publisher=Turkey in the First World War |accessdate=6 November 2011 |deadurl=yes |df= }}</ref><ref>{{cite web |url=http://www.hvkk.tsk.tr/EN/IcerikDetay.aspx?ID=19 |title=Founding |publisher=Turkish Air Force |accessdate=6 November 2011 |deadurl=yes |archiveurl=https://web.archive.org/web/20111007104345/http://www.hvkk.tsk.tr/EN/IcerikDetay.aspx?ID=19 |archivedate=7 October 2011 |df=dmy-all }}</ref> The Ottoman Empire started preparing its first pilots and planes, and with the founding of the Aviation School (''Tayyare Mektebi'') in [[Yeşilköy]] on 3 July 1912, the Empire began to tutor its own flight officers. The founding of the Aviation School quickened advancement in the military aviation program, increased the number of enlisted persons within it, and gave the new pilots an active role in the [[Ottoman Army]] and [[Ottoman Navy|Navy]]. In May 1913 the world's first specialized Reconnaissance Training Program was started by the Aviation School and the first separate reconnaissance division was established.{{citation needed|date=June 2011}} In June 1914 a new military academy, the Naval Aviation School (''Bahriye Tayyare Mektebi'') was founded. With the outbreak of World War I, the modernization process stopped abruptly. The [[Aviation Squadrons (Ottoman Empire)|Ottoman aviation squadrons]] fought on many fronts during World War I, from [[Galicia (Central Europe)|Galicia]] in the west to the [[Caucasus]] in the east and [[Yemen]] in the south.
+
+== Administrative divisions ==
+{{Main|Administrative divisions of the Ottoman Empire}}
+[[File:Ottoman Empire (1795).png|thumb|[[Eyalet]]s in 1795]]
+
+The Ottoman Empire was first subdivided into provinces, in the sense of fixed territorial units with governors appointed by the sultan, in the late 14th century.<ref name="Imber">{{cite web|last=Imber |first=Colin |title=The Ottoman Empire, 1300–1650: The Structure of Power |url=http://www.fatih.edu.tr/~ayasar/HIST236/Colin%20_Imber.pdf |year=2002 |pages=177–200 |deadurl=yes |archiveurl=https://web.archive.org/web/20140726115700/http://www.fatih.edu.tr/~ayasar/HIST236/Colin%20_Imber.pdf |archivedate=26 July 2014 |df= }}</ref>
+
+The [[Eyalet]] (also ''Pashalik'' or ''Beylerbeylik'') was the territory of office of a [[Beylerbey]] (“lord of lords” or governor), and was further subdivided in [[Sanjaks]].<ref>{{cite book|author1=Raymond Detrez|author2=Barbara Segaert|title=Europe and the historical legacies in the Balkans|url=https://books.google.com/books?id=htMUx8qlWCMC&pg=PA167|accessdate=1 June 2013|date=1 January 2008|publisher=Peter Lang|isbn=978-90-5201-374-9|page=167}}</ref>
+
+The [[Vilayets]] were introduced with the promulgation of the "Vilayet Law" ({{lang-tr|Teskil-i Vilayet Nizamnamesi}})<ref>{{cite book|author1=Naim Kapucu|author2=Hamit Palabiyik|title=Turkish Public Administration: From Tradition to the Modern Age|url=https://books.google.com/books?id=DWceNjwTggUC&pg=PA164|accessdate=1 June 2013|year=2008|publisher=USAK Books|isbn=978-605-4030-01-9|page=164}}</ref> in 1864, as part of the Tanzimat reforms.<ref name="trt">{{cite book|author=Maḥmūd Yazbak|title=Haifa in the Late Ottoman Period 1864–1914: A Muslim Town in Transition|url=https://books.google.com/books?id=DPseCvbPsKsC&pg=PA28|accessdate=1 June 2013|year=1998|publisher=BRILL|isbn=978-90-04-11051-9|page=28}}</ref> Unlike the previous eyalet system, the 1864 law established a hierarchy of administrative units: the vilayet, [[liva (sanjak)|liva]]/[[sanjak]], [[qadaa|kaza]] and [[Town council|village council]], to which the 1871 Vilayet Law added the [[nabiye]].<ref name="jpn">{{cite book |last1=Mundy |first1=Martha |last2=Smith |first2=Richard Saumarez |title=Governing Property, Making the Modern State: Law, Administration and Production in Ottoman Syria |url=https://books.google.com/books?id=thUKJ53-yyQC&pg=PA50 |accessdate=1 June 2013 |date=15 March 2007 |publisher=I.B.Tauris |isbn=978-1-84511-291-2 |page=50}}</ref>
+
+== Economy ==
+{{Main|Economic history of the Ottoman Empire}}
+
+Ottoman government deliberately pursued a policy for the development of Bursa, Edirne, and Istanbul, successive Ottoman capitals, into major commercial and industrial centres, considering that merchants and artisans were indispensable in creating a new metropolis.<ref name="Inalcik1970209">{{cite book |last=İnalcık |first=Halil |authorlink=Halil İnalcık |editor-last=Cook |editor-first=M. A. |title=Studies in the Economic History of the Middle East: from the Rise of Islam to the Present Day |chapter=The Ottoman Economic Mind and Aspects of the Ottoman Economy |publisher=Oxford University Press |year=1970 |isbn=978-0-19-713561-7 |page=209}}</ref> To this end, Mehmed and his successor Bayezid, also encouraged and welcomed migration of the Jews from different parts of Europe, who were settled in Istanbul and other port cities like Salonica. In many places in Europe, Jews were suffering persecution at the hands of their Christian counterparts, such as in Spain after the conclusion of Reconquista. The tolerance displayed by the Turks was welcomed by the immigrants.
+
+[[File:Mehmed the Conqueror (1432 –1481).jpg|thumb|left|A European bronze medal from the period of [[Mehmed the Conqueror|Sultan Mehmed the Conqueror]], 1481]]
+
+The Ottoman economic mind was closely related to the basic concepts of state and society in the Middle East in which the ultimate goal of a state was consolidation and extension of the ruler's power, and the way to reach it was to get rich resources of revenues by making the productive classes prosperous.<ref name="Inalcik1970217">{{cite book |last=İnalcık |first=Halil |authorlink=Halil İnalcık |editor-last=Cook |editor-first=M. A. |title=Studies in the Economic History of the Middle East: from the Rise of Islam to the Present Day |chapter=The Ottoman Economic Mind and Aspects of the Ottoman Economy |publisher=Oxford University Press |year=1970 |isbn=978-0-19-713561-7 |page=217}}</ref> The ultimate aim was to increase the state revenues without damaging the prosperity of subjects to prevent the emergence of social disorder and to keep the traditional organization of the society intact. The Ottoman economy greatly expanded during the [[Early Modern Period]], with particularly high growth rates during first half of the eighteenth century. The empire's annual income quadrupled between 1523 and 1748, adjusted for inflation.<ref>{{cite book |last=Darling |first=Linda |title=Revenue-Raising and Legitimacy: Tax Collection and Finance Administration in the Ottoman Empire, 1560–1660. |publisher=E.J. Brill |year=1996 |isbn=90-04-10289-2 |pages=238–9}}</ref>
+
+The organization of the treasury and chancery were developed under the Ottoman Empire more than any other Islamic government and, until the 17th century, they were the leading organization among all their contemporaries.<ref name="Black p199">{{cite book|last=Black|first=Antony|title=The History of Islamic Political Thought: From the Prophet to the Present|url=https://books.google.com/books?id=nspmqLKPU-wC&pg=PA197|accessdate=11 February 2013|year=2001|publisher=Psychology Press|isbn=978-0-415-93243-1|page=197}}</ref> This organization developed a scribal bureaucracy (known as "men of the pen") as a distinct group, partly highly trained [[ulama]], which developed into a professional body.<ref name="Black p199"/> The effectiveness of this professional financial body stands behind the success of many great Ottoman statesmen.<ref>{{cite book|last1=İnalcık|first1=Halil|last2=Quataert|first2=Donald|title=An Economic and Social History of the Ottoman Empire, 1300–1914|year=1971|page=120}}</ref>
+
+[[File:Ottoman Bank.jpg|thumb|The [[Ottoman Bank]] was founded in 1856 in [[Istanbul]]; in August 1896, the bank was [[1896 Ottoman Bank takeover|captured]] by members of the [[Armenian Revolutionary Federation]].]]
+
+Modern Ottoman studies indicate that the change in relations between the Ottoman Turks and central Europe was caused by the opening of the new sea routes. It is possible to see the decline in the significance of the land routes to the East as Western Europe opened the ocean routes that bypassed the Middle East and Mediterranean as parallel to the decline of the Ottoman Empire itself.<ref>Donald Quataert, ''The Ottoman Empire 1700–1922" (2005) p 24</ref>{{failed verification|date=September 2016}} The [[Anglo-Ottoman Treaty]], also known as the [[Treaty of Balta Liman]] that opened the Ottoman markets directly to English and French competitors, would be seen as one of the staging posts along this development.
+
+By developing commercial centres and routes, encouraging people to extend the area of cultivated land in the country and international trade through its dominions, the state performed basic economic functions in the Empire. But in all this the financial and political interests of the state were dominant. Within the social and political system they were living in, Ottoman administrators could not have seen the desirability of the dynamics and principles of the capitalist and mercantile economies developing in Western Europe.<ref name="Inalcik1970218">{{cite book |last=İnalcık |first=Halil |authorlink=Halil İnalcık |editor-last=Cook |editor-first=M. A. |title=Studies in the Economic History of the Middle East: from the Rise of Islam to the Present Day |chapter=The Ottoman Economic Mind and Aspects of the Ottoman Economy |publisher=Oxford University Press |year=1970 |isbn=978-0-19-713561-7 |page=218}}</ref>
+
+In the early 19th century, [[Ottoman Egypt]] had an advanced economy, with a [[per-capita income]] comparable to that of leading [[Western Europe]]an countries such as [[France]], and higher than the overall average income of [[Europe]] and [[Japan]].<ref name="batou">{{cite book|title=Between Development and Underdevelopment: The Precocious Attempts at Industrialization of the Periphery, 1800-1870|author=Jean Batou|publisher=[[:fr:Librairie Droz|Librairie Droz]]|year=1991|url=https://books.google.com/books?id=HjD4SCOE6IgC|pages=181–196|isbn=9782600042932}}</ref> Economic historian Jean Barou estimated that, in terms of 1960 dollars, [[Egypt]] in 1800 had a per-capita income of $232 (${{Inflation|US|232|1960|1990|fmt=c}} in 1990 dollars). In comparison, per-capita income in terms of 1960 dollars for France in 1800 was $240 (${{Inflation|US|240|1960|1990|fmt=c}} in 1990 dollars), for [[Eastern Europe]] in 1800 was $177 (${{Inflation|US|177|1960|1990|fmt=c}} in 1990 dollars), and for Japan in 1800 was $180 (${{Inflation|US|180|1960|1990|fmt=c}} in 1990 dollars).<ref name="batou189">{{cite book|title=Between Development and Underdevelopment: The Precocious Attempts at Industrialization of the Periphery, 1800-1870|author=Jean Batou|publisher=[[:fr:Librairie Droz|Librairie Droz]]|year=1991|url=https://books.google.com/books?id=HjD4SCOE6IgC&pg=PA189|page=189|isbn=9782600042932}}</ref><ref>{{cite book|title=Poverty From The Wealth of Nations: Integration and Polarization in the Global Economy since 1760|author=[[M. Shahid Alam]]|publisher=[[Springer Science+Business Media]]|year=2016|page=33|url=https://books.google.com/books?id=suKKCwAAQBAJ&pg=PA33|isbn=9780333985649}}</ref>
+
+Economic historian [[Paul Bairoch]] argues that [[free trade]] contributed to [[deindustrialization]] in the Ottoman Empire. In contrast to the [[protectionism]] of [[China]], Japan, and [[Spain]], the Ottoman Empire had a [[Economic liberalism|liberal trade]] policy, open to foreign imports. This has origins in [[capitulations of the Ottoman Empire]], dating back to the first commercial treaties signed with France in 1536 and taken further with [[Capitulation (treaty)|capitulations]] in 1673 and 1740, which lowered [[Duty (economics)|duties]] to 3% for imports and exports. The liberal Ottoman policies were praised by British economists such as [[J. R. McCulloch]] in his ''Dictionary of Commerce'' (1834), but later criticized by British politicians such as [[Prime Minister of the United Kingdom|Prime Minister]] [[Benjamin Disraeli]], who cited the Ottoman Empire as "an instance of the injury done by unrestrained competition" in the 1846 [[Corn Laws]] debate.<ref>{{cite book|title=Economics and World History: Myths and Paradoxes|author=[[Paul Bairoch]]|publisher=[[University of Chicago Press]]|year=1995|url=https://www.scribd.com/document/193124153/Economics-and-World-History-Myths-and-Paradoxes-Paul-Bairoch|pages=31–32}}</ref>
+
+{{quote|There has been free trade in Turkey, and what has it produced? It has destroyed some of the finest manufactures of the world. As late as 1812 these manufactures existed; but they have been destroyed. That was the consequences of competition in Turkey, and its effects have been as pernicious as the effects of the contrary principle in Spain.}}
+
+== Demographics ==
+{{Main|Demographics of the Ottoman Empire}}
+A population estimate for the empire of 11,692,480 for the 1520–1535 period was obtained by counting the households in Ottoman tithe registers, and multiplying this number by 5.<ref name="Kabadayı"/> For unclear reasons, the population in the 18th century was lower than that in the 16th century.<ref>{{cite journal|title=Population Rise and Fall in Anatolia 1550–1620|journal=Middle Eastern Studies|date=October 1979|volume=15|issue=3|pages=322–345|author=Leila Erder and Suraiya Faroqhi|doi=10.1080/00263207908700415}}</ref> An estimate of 7,230,660 for the first census held in 1831 is considered a serious undercount, as this census was meant only to register possible conscripts.<ref name="Kabadayı"/>
+
+[[File:Ottoman Smyrna.jpg|thumb|left|[[Smyrna]] under Ottoman rule in 1900]]
+
+Censuses of Ottoman territories only began in the early 19th century. Figures from 1831 onwards are available as official census results, but the censuses did not cover the whole population. For example, the 1831 census only counted men and did not cover the whole empire.{{sfn|Kinross|1979|p = 281}}<ref name="Kabadayı">{{cite web|last=Kabadayı |first=M. Erdem |title=Inventory for the Ottoman Empire / Turkish Republic |url=http://www.iisg.nl/research/labourcollab/turkey.pdf |publisher=Istanbul Bilgi University |archivedate=28 October 2011 |archiveurl=https://web.archive.org/web/20111028114335/http://www.iisg.nl/research/labourcollab/turkey.pdf |date=28 October 2011 |deadurl=yes |df= }}</ref> For earlier periods estimates of size and distribution of the population are based on observed demographic patterns.<ref>{{cite book|last=Shaw|first=S. J.|title=The Ottoman Census System and Population, 1831–1914|year=1978|publisher=Cambridge University Press|page=325|work=International Journal of Middle East Studies|quote=The Ottomans developed an efficient system for counting the empire's population in 1826, a quarter of a century after such methods were introduced in Britain, France and America.}}</ref>
+
+However, it began to rise to reach 25–32 million by 1800, with around 10 million in the European provinces (primarily the [[Balkans]]), 11 million in the Asiatic provinces and around 3 million in the African provinces. Population densities were higher in the European provinces, double those in Anatolia, which in turn were triple the population densities of Iraq and [[Syria]] and five times the population density of Arabia.{{sfn|Quataert|2000|pp = 110–111}}
+
+[[File:Bridge and Galata Area, Istanbul, Turkey by Abdullah Frères, ca. 1880-1893 (LOC).jpg|thumb|View of [[Galata]] ([[Karaköy]]) and the [[Galata Bridge]] on the [[Golden Horn]], {{circa|1880–1893}}]]
+
+Towards the end of the empire's existence [[life expectancy]] was 49 years, compared to the mid-twenties in Serbia at the beginning of the 19th century.{{sfn|Quataert|2000|p = 112}} Epidemic diseases and [[famine]] caused major disruption and demographic changes. In 1785 around one sixth of the Egyptian population died from plague and Aleppo saw its population reduced by twenty percent in the 18th century. Six famines hit Egypt alone between 1687 and 1731 and the last famine to hit Anatolia was four decades later.{{sfn|Quataert|2000|p = 113}}
+
+The rise of port cities saw the clustering of populations caused by the development of steamships and railroads. Urbanization increased from 1700 to 1922, with towns and cities growing. Improvements in health and sanitation made them more attractive to live and work in. Port cities like Salonica, in Greece, saw its population rise from 55,000 in 1800 to 160,000 in 1912 and İzmir which had a population of 150,000 in 1800 grew to 300,000 by 1914.{{sfn|Quataert|2000|p = 114}}<ref>{{cite journal|last=Pamuk|first=S|title=The Ottoman Empire and the World Economy: The Nineteenth Century|journal=International Journal of Middle East Studies|date=August 1991|volume=23|issue=3|publisher=Cambridge University Press}}</ref> Some regions conversely had population falls – Belgrade saw its population drop from 25,000 to 8,000 mainly due to political strife.{{sfn|Quataert|2000|p = 114}}
+
+Economic and political migrations made an impact across the empire. For example, the [[Russian Empire|Russian]] and Austria-Habsburg annexation of the Crimean and Balkan regions respectively saw large influxes of Muslim refugees – 200,000 Crimean Tartars fleeing to Dobruja.{{sfn|Quataert|2000|p = 115}} Between 1783 and 1913, approximately 5–7 million refugees flooded into the Ottoman Empire, at least 3.8 million of whom were from Russia. Some migrations left indelible marks such as political tension between parts of the empire (e.g. Turkey and Bulgaria) whereas centrifugal effects were noticed in other territories, simpler demographics emerging from diverse populations. Economies were also impacted with the loss of artisans, merchants, manufacturers and agriculturists.{{sfn|Quataert|2000|p = 116}} Since the 19th century, a large proportion of Muslim peoples from the Balkans emigrated to present-day Turkey. These people are called ''[[Muhacir]]''.<ref>{{cite book|last=McCarthy|first=Justin|title=Death and exile: the ethnic cleansing of Ottoman Muslims, 1821–1922|year=1995|publisher=Darwin Press|isbn=978-0-87850-094-9|page={{page needed|date=February 2013}}}}</ref> By the time the Ottoman Empire came to an end in 1922, half of the urban population of Turkey was descended from Muslim refugees from Russia.<ref name="books.google_b"/>
+
+=== Language ===
+{{Main|Languages of the Ottoman Empire}}
+
+[[File:1911 Ottoman Calendar.jpg|thumb|1911 Ottoman calendar in [[Ottoman Turkish language|Ottoman Turkish]], [[Arabic language|Arabic]], [[Greek language|Greek]], [[Armenian language|Armenian]], [[Hebrew language|Hebrew]], [[French language|French]] and [[Bulgarian language|Bulgarian]]]]
+Ottoman Turkish was the official language of the Empire. It was an [[Oghuz languages|Oghuz]] [[Turkic languages|Turkic language]] highly influenced by [[Persian language|Persian]] and [[Arabic]]. The Ottomans had several influential languages: Turkish, spoken by the majority of the people in [[Anatolia]] and by the majority of Muslims of the Balkans except in [[Albania]] and [[Bosnia]]; Persian, only spoken by the educated;<ref name="Bertold Spuler page 69">{{cite book|author=Bertold Spuler|title=Persian Historiography And Geography|url=https://books.google.com/books?id=rD1vvympVtsC&pg=PA69|accessdate=11 February 2013|year=2003|publisher=Pustaka Nasional Pte Ltd|isbn=978-9971-77-488-2|page=69}}</ref> Arabic, spoken mainly in [[Arabia]], [[Iraq]], [[Kuwait]], the [[Levant]] and parts of the [[Horn of Africa]] and [[Berber language|Berber]] in North Africa. In the last two centuries, usage of these became limited, though, and specific: Persian served mainly as a literary language for the educated,<ref name="Bertold Spuler page 69"/> while [[Arabic]] was used for Islamic prayers.
+
+[[Turkish language|Turkish]], in its Ottoman variation, was a language of military and administration since the nascent days of the Ottomans. The Ottoman constitution of 1876 did officially cement the official imperial status of Turkish.<ref>{{cite journal|title=The Ottoman Constitution, promulgated the 7th Zilbridge, 1293 (11/23 December, 1876)|journal=The American Journal of International Law|year=1908|volume=2|issue=4|page=376|jstor=2212668}}</ref>
+
+Because of a low literacy rate among the public (about 2–3% until the early 19th century and just about 15% at the end of the 19th century), ordinary people had to hire [[scribes]] as "special request-writers" (''arzuhâlci''s) to be able to communicate with the government.<ref>{{cite book|author=Kemal H. Karpat|title=Studies on Ottoman Social and Political History: Selected Articles and Essays|url=https://books.google.com/books?id=082osLxyBDgC&pg=PA266|accessdate=11 February 2013|year=2002|publisher=BRILL|isbn=978-90-04-12101-0|page=266}}</ref><ref>{{Cite web|url=https://www.saylor.org/site/wp-content/uploads/2011/08/HIST351-8.1-Ottoman-Empire.pdf|title=Ottoman Empire|last=|first=|date=|website=|access-date=}}</ref> The ethnic groups continued to speak within their families and neighborhoods ([[mahalle]]s) with their own languages (e.g., Jews, Greeks, Armenians, etc.). In villages where two or more populations lived together, the inhabitants would often speak each other's language. In cosmopolitan cities, people often spoke their family languages; many of those who were not ethnic [[Turkish people|Turks]] spoke Turkish as a second language.
+
+=== Religion ===
+{{Unbalanced section|reason = very little attention given to Islam even though it was the primary religion|date=November 2010}}
+[[File:Portrait Caliph Abdulmecid II.jpg|thumb|[[Abdülmecid II]] was the last [[caliph]] of Islam and a member of the [[Ottoman dynasty]].]]
+
+In the Ottoman imperial system, even though there existed a hegemonic power of Muslim control over the non-Muslim populations, non-Muslim communities had been granted state recognition and protection in the Islamic tradition.<ref name="emigrnonm"/> The officially accepted state [[Dīn]] ''([[Madh'hab]])'' of the Ottomans was [[Sunni]] ''([[Hanafi jurisprudence]]).''<ref name=Gunduz>Gunduz, Sinasi [https://books.google.com/books?id=4BXsV0_qhs4C&pg=PA104&lpg#v Change And Essence: Dialectical Relations Between Change And Continuity in the Turkish Inrtellectual Traditions] Cultural Heritage and Contemporary Change. Series IIA, Islam, V. 18, p.104-105</ref>
+
+Until the second half of the 15th century the empire had a Christian majority, under the rule of a Muslim minority.<ref name="Benton 109-110"/> In the late 19th century, the non-Muslim population of the empire began to fall considerably, not only due to secession, but also because of migratory movements.<ref name="emigrnonm"/> The proportion of Muslims amounted to 60% in the 1820s, gradually increasing to 69% in the 1870s and then to 76% in the 1890s.<ref name="emigrnonm"/> By 1914, only 19.1% of the empire's population was non-Muslim, mostly made up of Jews and Christian Greeks, Assyrians, and Armenians.<ref name="emigrnonm">{{cite journal |last1=Içduygu |first1=Ahmet |last2=Toktas |first2=Şule |last3=Ali Soner |first3=B. |title=The politics of population in a nation-building process: emigration of non-Muslims from Turkey |journal=Ethnic and Racial Studies |date=1 February 2008 |volume=31 |issue=2 |pages=358–389 |doi=10.1080/01419870701491937}}</ref>
+
+==== Islam ====
+{{Main|Islam in the Ottoman Empire|Ottoman Caliphate|Ottoman persecution of Alevis}}
+[[File:Tile with Calligraphy.JPG|thumb|[[Calligraphic]] writing on a [[fritware]] tile, depicting the names of [[God in Islam|God]], [[Muhammad in Islam|Muhammad]] and the first [[Caliphate|caliphs]], {{circa|1727}}<ref>{{cite web|url=https://collections.vam.ac.uk/item/O106609/tile/ |title=Tile |publisher=Victoria & Albert Museum |date=25 August 2009 |accessdate=26 August 2010}}</ref>]]
+
+Turkic peoples practiced a variety of [[shamanism]] before adopting Islam. [[Abbasid]] influence in Central Asia was ensured through a process that was greatly facilitated by the [[Muslim conquest of Transoxiana]]. Many of the various Turkic tribes—including the [[Oghuz Turks]], who were the ancestors of both the Seljuks and the Ottomans—gradually converted to Islam, and brought the religion with them to Anatolia beginning in the 11th century.
+
+Muslim sects regarded as heretical, such as the [[Druze]], [[Ismailis]], [[Alevi]]s, and [[Alawites]], ranked below Jews and Christians.<ref>{{cite web|title=Why there is more to Syria conflict than sectarianism|url=https://www.bbc.co.uk/news/world-middle-east-22770219|publisher=BBC News|accessdate=5 June 2013}}</ref> In 1514, Sultan [[Selim I]] ordered the massacre of 40,000 Anatolian [[Alevi]]s (''[[Qizilbash]]''), whom he considered a [[fifth column]] for the rival [[Safavid]] empire. Selim was also responsible for an unprecedented and rapid expansion of the Ottoman Empire into the Middle East, especially through his [[Ottoman–Mamluk War (1516–17)|conquest of the entire Mamluk Sultanate of Egypt]]. With these conquests, Selim further solidified the Ottoman claim for being an Islamic [[caliphate]], although Ottoman sultans had been claiming the title of caliph since the 14th century starting with [[Murad I]] (reigned 1362 to 1389).<ref name="Lambton"/> The caliphate would remain held by Ottoman sultans for the rest of the office's duration, which ended with its abolition on 3 March 1924 by the [[Grand National Assembly of Turkey]] and the exile of the last caliph, [[Abdülmecid II]], to France.
+
+==== Christianity and Judaism ====
+{{Main|Christianity in the Ottoman Empire|History of the Jews in the Ottoman Empire}}
+[[File:Gennadios II and Mehmed II.jpg|thumb|upright=0.8|[[Mehmed the Conqueror]] and Patriarch [[Gennadius Scholarius|Gennadius II]]]]
+
+In the Ottoman Empire, in accordance with the Muslim ''[[dhimmi]]'' system, Christians were guaranteed limited freedoms (such as the right to worship). They were forbidden to carry weapons or ride on horseback, their houses could not overlook those of Muslims, in addition to various other legal limitations.<ref>{{cite book|last=Akçam|first=Taner|title=A shameful act: the Armenian genocide and the question of Turkish responsibility|year=2006|publisher=Metropolitan Books|location=New York|isbn=0-8050-7932-7|page=24|authorlink=Taner Akçam}}</ref> Many Christians and Jews converted in order to secure full status in the society. Most, however, continued to practice their old religions without restriction.<ref>{{cite web|url=http://global.britannica.com/EBchecked/topic/434996/Ottoman-Empire/44379/Institutional-evolution#ref482041|title=Ottoman Empire|work=Encyclopædia Britannica}}</ref>
+
+Under the [[Millet (Ottoman Empire)|millet]] system, non-Muslim people were considered subjects of the Empire, but were not subject to the Muslim faith or Muslim law. The Orthodox millet, for instance, was still officially legally subject to [[Corpus Juris Civilis|Justinian's Code]], which had been in effect in the Byzantine Empire for 900 years. Also, as the largest group of non-Muslim subjects (or ''[[Dhimmi|zimmi]]'') of the Islamic Ottoman state, the Orthodox millet was granted a number of special privileges in the fields of politics and commerce, and had to pay higher taxes than Muslim subjects.<ref>{{cite journal|url=http://www.loyno.edu/history/journal/1998-9/Krummerich.htm |archiveurl=https://web.archive.org/web/20090610014150/http://www.loyno.edu/history/journal/1998-9/Krummerich.htm |archivedate=10 June 2009 |title=The Divinely-Protected, Well-Flourishing Domain: The Establishment of the Ottoman System in the Balkan Peninsula |first=Sean |last=Krummerich |journal=The Student Historical Journal |volume=30 |year=1998–99 |publisher=Loyola University New Orleans |accessdate=11 February 2013 |deadurl=yes |df= }}</ref><ref>{{cite web |url=http://www.globaled.org/nyworld/materials/ottoman/turkish.html |archive-url=https://web.archive.org/web/20010320091629/http://globaled.org/nyworld/materials/ottoman/turkish.html |dead-url=yes |archive-date=20 March 2001 |title=Turkish Toleration |publisher=The American Forum for Global Education |accessdate=11 February 2013 }}</ref>
+
+Similar millets were established for the Ottoman Jewish community, who were under the authority of the ''[[Hakham Bashi|Haham Başı]]'' or Ottoman [[Chief rabbi]]; the [[Armenian Apostolic Church|Armenian Orthodox]] community, who were under the authority of a head bishop; and a number of other religious communities as well.<ref name=":1">{{Cite book|title=A Concise History of Islam|last=Syed|first=Muzaffar Husain|publisher=Vij Books India|year=2011|isbn=978-9381411094|location=New Delhi, India|pages=97}}</ref> Some argue that the millet system is an example of pre-modern [[religious pluralism]].<ref>{{cite book |last=Sachedina |first=Abdulaziz Abdulhussein |date=2001 |title=The Islamic Roots of Democratic Pluralism |publisher=[[Oxford University Press]] |pages=96–97 |isbn=0-19-513991-7 |quote=The millet system in the Muslim world provided the pre-modern paradigm of a religiously pluralistic society by granting each religious community an official status and a substantial measure of self-government.}}</ref>
+
+=== Social-political-religious structure===
+Society, government and religion was inter-related in complex ways after about 1800, in a complex overlapping, inefficient system that Atatürk systematically dismantled after 1922.<ref>Philip D. Curtin, ''The World and the West: The European Challenge and the Overseas Response in the Age of Empire'' (2002), pp 173-92.</ref><ref>Fatma Muge Gocek, ''Rise of the Bourgeoisie, Demise of Empire: Ottoman Westernization and Social Change'' (1996) pp 138-42</ref>  In Constantinople, the Sultan  ruled two distinct domains the secular government and the religious hierarchy. Religious officials formed the [[Ulama]] Who had control of religious teachings and theology, and also the Empire's judicial system, Giving them a major voice in day-to-day affairs in communities across the Empire (but not including the non-Moslem millets). They were powerful enough to reject the military reforms proposed by Sultan [[Selim III]]. His successor Sultan [[Mahmud II]] (r. 1808–1839) first won ulama approval before proposing similar reforms.<ref>Kemal H. Karpat, "The transformation of the Ottoman State, 1789-1908." ''International Journal of Middle East Studies'' 3#3 (1972): 243-281. [http://psi424.cankaya.edu.tr/uploads/files/Karpat,%20Transformation%20of%20the%20Ott%20State,%201789-1908%20(1972).pdf online]</ref>  The secularization program of Atatürk brought ended the ulema and their institutions. The caliphate was abolished, madrasas were closed down and the sharia courts abolished.  He replaced the Arabic alphabet with Latin letters, ended the religious school system, and gave women some political rights.  Many rural traditionalists never accepted this secularization, and by the 1990s they were reasserting a demand for a larger role for Islam.<ref>{{cite book|author=Amit Bein|title=Ottoman Ulema, Turkish Republic: Agents of Change and Guardians of Tradition|url=https://books.google.com/books?id=D1xfDfgPJr8C&pg=PA141|year=2011|publisher=Stanford UP|page=141}}</ref>
+
+The political system was transformed by the destruction of the [[Janissaries]] in the [[Auspicious Incident]] of 1826. They were very powerful military/governmental/police force that revolted. Sultan [[Mahmud II]] crushed the revolt, executed the leaders, and disbanded the large organization.  That set the stage for a slow process of modernization of government functions, as the government sought, with mixed success, to adopt the main elements of Western bureaucracy and military technology. The Janissaries had been recruited from Christians and other minorities; their abolition enabled the emergence of a Turkish elite to control the Ottoman Empire.  The problem was that the Turkish element was very poorly educated, lacking higher schools of any sort, and locked into a Turkish language that used Arabic alphabet that inhibited wider learning.  The large number of ethnic and religious minorities were tolerated in their own separate segregated domains called "[[milletts]]".<ref>Karen Barkey, and George Gavrilis, "The Ottoman millet system: Non-territorial autonomy and its contemporary legacy." ''Ethnopolitics'' 15.1 (2016): 24-42.</ref> They were primarily Greek, Armenian or Jewish.  In each locality they governed themselves, spoke their own language, ran their own schools, cultural and religious institutions, and paid somewhat higher taxes. They had no power outside the millett. The Imperial government protected them, and prevented major violent clashes between ethnic groups. However the millets showed very little loyalty to the Empire. Ethnic nationalism, based on distinctive religion and language, provided a centripetal force that eventually destroyed the Ottoman Empire.<ref>Donald Quataert, ''Social Disintegration and Popular Resistance in the Ottoman Empire 1881–1908'' (1083) </ref> In addition, Muslim ethnic groups, which were not part of the millett system, especially the Arabs and the Kurds, were outside the Turkish culture and develop their own separate nationalism. The British sponsored Arab nationalism in the First World War, promising an independent Arab state in return for Arab support.  Most Arabs supported the Sultan but those near Mecca bought the British promise.<ref>Youssef M. Choueiri, ''Arab Nationalism: A History: Nation and State in the Arab World'' (2001), pp 56-100.</ref>
+
+At the local level, power was held beyond the control of the Sultan by the [[Ottoman Ayan|"ayan"]] or local notables. The ayan collected taxes, formed local armies to compete with other notables, took a reactionary attitude toward political or economic change, and often defied policies handed down by the Sultan.<ref>{{cite book|author=Gábor Ágoston and Bruce Alan Masters|title=Encyclopedia of the Ottoman Empire|url=https://books.google.com/books?id=QjzYdCxumFcC&pg=PA64|year=2010|publisher=Infobase |page=64}}</ref>
+
+The economic system made little progress. Printing was forbidden until the 18th century,  for fear of defiling the secret documents of Islam. The millets, however, Were allowed their own presses, using Greek, Hebrew, Armenian and other languages that greatly facilitated nationalism. The religious prohibition on charging interest foreclosed most of the entrepreneurial skills among Muslims, although it did flourish among the Jews and Christians. 
+
+After the 18th century, the Ottoman Empire was clearly shrinking, as Russia put on heavy pressure and expanded to its south; Egypt became effectively independent in 1805 and the British later took it over, along with Cyprus. Greece became independent, and Serbia and other Balkan areas became highly restive is the force of nationalism pushed against imperialism.  The French took over Algeria and Tunisia.  Europeans all thought it was a sick man in rapid decline. Only the Germans seemed helpful, in their support led to the Empire joining the central powers in 1915, and coming out one of the heaviest losers of the First World War in 1918.<ref>Naci Yorulmaz, ''Arming the Sultan: German Arms Trade and Personal Diplomacy in the Ottoman Empire Before World War I'' (IB Tauris, 2014).</ref>
+
+== Culture ==
+{{Main|Culture of the Ottoman Empire}}
+{{also|Ottoman slave trade}}
+{{Culture of the Ottoman Empire sidebar}}
+[[File:WaldmeierLebanon.gif|thumb|left|Depiction of a [[hookah]] shop in [[Lebanon]], Ottoman Empire]]
+
+The Ottomans absorbed some of the traditions, art and institutions of cultures in the regions they conquered, and added new dimensions to them. Numerous traditions and cultural traits of previous empires (in fields such as architecture, cuisine, music, leisure and government) were adopted by the Ottoman Turks, who elaborated them into new forms, resulting in a new and distinctively Ottoman cultural identity. Despite newer added amalgamations, the Ottoman dynasty, like their predecessors in the [[Sultanate of Rum]] and the [[Seljuk Empire]], were thoroughly Persianised in their culture, language, habits and customs, and therefore the empire has been described as a [[Persianate society|Persianate]] empire.<ref name="iranica">{{cite encyclopedia|first=O. |last=Özgündenli |title=Persian Manuscripts in Ottoman and Modern Turkish Libraries |encyclopedia=Encyclopaedia Iranica |edition=online |url=http://www.iranica.com/newsite/articles/ot_grp7/ot_pers_mss_ott_20050106.html |deadurl=yes |archiveurl=https://web.archive.org/web/20120122005207/http://www.iranica.com/newsite/articles/ot_grp7/ot_pers_mss_ott_20050106.html |archivedate=22 January 2012 |df= }}</ref><ref>{{citation|chapter = Persian in service of the state: the role of Persophone historical writing in the development of an Ottoman imperial aesthetic|title = Studies on Persianate Societies|volume = 2|date = 2004|pages = 145–63}}</ref><ref>{{cite encyclopedia|title = Historiography. xi. Persian Historiography in the Ottoman Empire|encyclopedia = [[Encyclopaedia Iranica]]|volume = 12, fasc. 4|date = 2004|pages = 403–11}}</ref><ref>{{cite book|first1 = F.|last1 = Walter|title = Music of the Ottoman court|chapter = The Departure of Turkey from the 'Persianate' Musical Sphere|url = http://www.vwb-verlag.com/Katalog/m641.html}}</ref> Intercultural marriages also played a part in creating the characteristic Ottoman elite culture. When compared to the Turkish folk culture, the influence of these new cultures in creating the culture of the Ottoman elite was clear.
+
+[[File:Flickr - …trialsanderrors - Yeni Cami and Eminönü bazaar, Constantinople, Turkey, ca. 1895.jpg|thumb|[[Yeni Mosque (Istanbul)|Yeni Mosque]] and [[Eminönü]] bazaar, Constantinople, {{circa|1895}}]]
+
+[[Slavery (Ottoman Empire)|Slavery]] was a part of Ottoman society,<ref>{{cite web|author=Halil Inalcik |title=Servile Labor in the Ottoman Empire |publisher=Michigan State University |url=http://coursesa.matrix.msu.edu/~fisher/hst373/readings/inalcik6.html |accessdate=26 August 2010 |deadurl=yes |archiveurl=https://web.archive.org/web/20090911101051/http://coursesa.matrix.msu.edu/~fisher/hst373/readings/inalcik6.html |archivedate=11 September 2009 |df= }}</ref> with most slaves employed as domestic servants. Agricultural slavery, such as that which was widespread in the Americas, was relatively rare. Unlike systems of [[chattel slavery]], slaves under Islamic law were not regarded as movable property, but maintained basic, though limited, rights. This gave them a degree of protection against abuse.<ref>{{cite book |first=Pál |last=Fodor |chapter=Introduction |editor1-last=Dávid |editor1-first=Géza |editor2=Pál Fodor |title=Ransom Slavery along the Ottoman Borders |publisher=Brill |place=Leiden |date=2007 |pages=XII–XVII |isbn=978-90-04-15704-0}}</ref> Female slaves were still sold in the Empire as late as 1908.<ref>{{cite web |title=Islam and slavery: Sexual slavery |publisher=BBC |url=http://www.bbc.co.uk/religion/religions/islam/history/slavery_7.shtml |accessdate=26 August 2010}}</ref> During the 19th century the Empire came under pressure from Western European countries to outlaw the practice. Policies developed by various Sultans throughout the 19th century attempted to curtail the [[Ottoman slave trade]] but, since slavery did have centuries of religious backing and sanction, they never directly abolished the institution outright.<ref name=":1" />
+
+[[Plague (disease)|Plague]] remained a major scourge in Ottoman society until the second quarter of the 19th century. "Between 1701 and 1750, 37 larger and smaller plague epidemics were recorded in Istanbul, and 31 between 1751 and 1801."<ref>{{cite journal |last=Faroqhi |first=Suraiya |year=1998 |title=Migration into Eighteenth-century 'Greater Istanbul' as Reflected in the Kadi Registers of Eyüp |url=https://secure.peeters-leuven.be/POJ/purchaseform.php?id=2004296&sid= |journal=Turcica |volume=30 |publisher=Éditions Klincksieck |location=Louvain |page=165 |doi=10.2143/TURC.30.0.2004296}}</ref>
+
+=== Literature ===
+{{Main|Ottoman literature}}
+
+The two primary streams of Ottoman written literature are poetry and [[prose]]. Poetry was by far the dominant stream. Until the 19th century, Ottoman prose did not contain any examples of fiction: there were no counterparts to, for instance, the European [[Romance (heroic literature)|romance]], short story, or novel. Analogue genres did exist, though, in both [[Turkish folk literature]] and in [[Divan poetry]].
+
+Ottoman [[Divan poetry]] was a highly ritualized and symbolic art form. From the [[Persian poetry]] that largely inspired it, it inherited a wealth of symbols whose meanings and interrelationships—both of similitude (مراعات نظير mura'ât-i nazîr / تناسب tenâsüb) and opposition (تضاد tezâd) were more or less prescribed. Divan poetry was composed through the constant juxtaposition of many such images within a strict metrical framework, thus allowing numerous potential meanings to emerge. The vast majority of Divan poetry was [[Lyric poetry|lyric]] in nature: either [[gazel]]s (which make up the greatest part of the repertoire of the tradition), or kasîdes. There were, however, other common genres, most particularly the mesnevî, a kind of [[Courtly romance|verse romance]] and thus a variety of [[narrative poetry]]; the two most notable examples of this form are the [[Leyli and Majnun]] of [[Fuzûlî]] and the [[Hüsn ü Aşk]] of [[Şeyh Gâlib]].
+
+[[File:Nedim (divan edb.şairi).JPG|thumb|[[Ahmet Nedîm Efendi]], one of the most celebrated Ottoman poets]]
+
+Until the 19th century, [[Prose of the Ottoman Empire|Ottoman prose]] did not develop to the extent that contemporary Divan poetry did. A large part of the reason for this was that much prose was expected to adhere to the rules of sec (سجع, also transliterated as seci), or [[rhymed prose]],<ref>{{cite book |author=Murat Belge |title=Osmanlı'da kurumlar ve kültür |year=2005 |publisher=İstanbul Bilgi Üniversitesi Yayınları |isbn=978-975-8998-03-6 |page=389}}</ref> a type of writing descended from the Arabic [[saj']] and which prescribed that between each adjective and [[noun]] in a string of words, such as a sentence, there must be a [[rhyme]]. Nevertheless, there was a tradition of prose in the literature of the time, though exclusively non-fictional in nature. One apparent exception was [[Muhayyelât]] ("Fancies") by [[Giritli Ali Aziz Efendi]], a collection of stories of the fantastic written in 1796, though not published until 1867. The first novel published in the Ottoman Empire was by an Armenian named [[Vartan Pasha]]. Published in 1851, the novel was entitled The Story of Akabi (Turkish: Akabi Hikyayesi) and was written in Turkish but with [[Armenian language|Armenian]] script.<ref>{{cite book|last1=Mignon|first1=Laurent|title=Neither Shiraz nor Paris : papers on modern Turkish literature|date=2005|publisher=ISIS|location=Istanbul|isbn=9754283036|page=20|url=https://books.google.com/books?id=AbQZAQAAIAAJ|quote=Those words could have been readily adopted by Hovsep Vartanyan (1813– 1879), the author, who preferred to remain anonymous, of The Story of Akabi (Akabi Hikyayesi), the first novel in Turkish, published with Armenian characters in the same year as [[Hovhannes Hisarian|Hisarian]]'s novel.}}</ref><ref>{{cite book|last1=Masters|first1=Bruce|last2=Ágoston|first2=Gábor|title=Encyclopedia of the Ottoman Empire|date=2009|publisher=Facts On File|location=New York, NY|isbn=1438110251|page=440|url=https://books.google.com/books?id=QjzYdCxumFcC|quote=Written in Turkish using the Armenian alphabet, the Akabi History (1851) by Vartan Pasha is considered by some to be the first Ottoman novel.}}</ref><ref>{{cite book|last1=Pultar|first1=Gönül|title=Imagined identities : identity formation in the age of globalism|date=2013|publisher=Syracuse University Press|location=[S.l.]|isbn=0815633424|page=329|edition=First|url=https://books.google.com/books?id=KhiQAwAAQBAJ|quote=In fact, one of the first Turkish works of fiction in Western-type novel form, Akabi Hikayesi (Akabi's Story), was written in Turkish by Vartan Pasha (born Osep/Hovsep Vartanian/Vartanyan, 1813– 1879) and published in Armenian characters in 1851.}}</ref><ref>{{cite book |last1=Gürçaglar |first1=Şehnaz |last2=Paker |first2=Saliha |last3=Milton |first3=John |date=2015 |title=Tradition, Tension and Translation in Turkey |publisher=John Benjamins Publishing Company |page=5 |isbn=90-272-6847-9 |quote=It is interesting that the first Ottoman novel in Turkish, Akabi Hikayesi (1851, Akabi's Story), was written and published in Armenian letters (for Armenian communities who read in Turkish) by Hovsep Vartanyan (1813–1879), known as Vartan Paşa, a leading Ottoman man of letters and journalist.}}</ref>
+
+Due to historically close ties with France, [[French literature]] came to constitute the major Western influence on Ottoman literature throughout the latter half of the 19th century. As a result, many of the same movements prevalent in France during this period also had their Ottoman equivalents: in the developing Ottoman prose tradition, for instance, the influence of [[Romanticism]] can be seen during the Tanzimat period, and that of the [[Realism (arts)|Realist]] and [[Naturalism (literature)|Naturalist]] movements in subsequent periods; in the poetic tradition, on the other hand, it was the influence of the [[Symbolism (arts)|Symbolist]] and [[Parnassian poets|Parnassian]] movements that became paramount.
+
+Many of the writers in the Tanzimat period wrote in several different genres simultaneously: for instance, the poet [[Namık Kemal]] also wrote the important 1876 novel İntibâh ("Awakening"), while the journalist [[İbrahim Şinasi]] is noted for writing, in 1860, the first modern Turkish play, the [[One act play|one-act]] comedy "Şair Evlenmesi" ("The Poet's Marriage"). An earlier play, a [[farce]] entitled "Vakâyi'-i 'Acibe ve Havâdis-i Garibe-yi Kefşger Ahmed" ("The Strange Events and Bizarre Occurrences of the Cobbler Ahmed"), dates from the beginning of the 19th century, but there remains some doubt about its authenticity. In a similar vein, the novelist [[Ahmed Midhat Efendi]] wrote important novels in each of the major movements: Romanticism (Hasan Mellâh yâhud Sırr İçinde Esrâr, 1873; "Hasan the Sailor, or The Mystery Within the Mystery"), Realism (Henüz On Yedi Yaşında, 1881; "Just Seventeen Years Old"), and Naturalism (Müşâhedât, 1891; "Observations"). This diversity was, in part, due to the Tanzimat writers' wish to disseminate as much of the new literature as possible, in the hopes that it would contribute to a revitalization of Ottoman [[social structure]]s.<ref>{{cite book|last=Moran|first=Berna|title=Türk Romanına Eleştirel Bir Bakış Vol. 1|isbn=975-470-054-0|page=19}}</ref>
+
+=== Architecture ===
+{{Main|Ottoman architecture}}
+[[File:Dolmabahçe Palace in 1862.jpg|thumb|left|Photo of the main entrance of [[Dolmabahçe Palace]] in 1862, taken by [[Francis Bedford (photographer)|Francis Bedford]]]]
+
+[[Ottoman architecture]] was influenced by [[Persian Architecture|Persian]], [[Byzantine architecture|Byzantine Greek]] and [[Islamic architecture|Islamic]] architectures. During the [[Rise of the Ottoman Empire|Rise period]] the early or first Ottoman architecture period, Ottoman art was in search of new ideas. The [[Growth of the Ottoman Empire|growth period]] of the Empire become the classical period of architecture, when Ottoman art was at its most confident. During the years of the [[Stagnation of the Ottoman Empire|Stagnation period]], Ottoman architecture moved away from this style, however.
+
+[[File:Bridge on the Drina July 2009.jpg|thumb|[[Mehmed Paša Sokolović Bridge]], completed in 1577 by [[Mimar Sinan]], the greatest architect of the classical period of Ottoman architecture]]
+
+During the [[Tulip Era in the Ottoman Empire|Tulip Era]], it was under the influence of the highly ornamented styles of Western Europe; [[Baroque]], [[Rococo]], [[Empire (style)|Empire]] and other styles intermingled. Concepts of Ottoman architecture concentrate mainly on the [[Mosque#Architecture|mosque]]. The mosque was integral to society, [[Urban planning|city planning]] and communal life. Besides the mosque, it is also possible to find good examples of Ottoman architecture in [[soup kitchen]]s, theological schools, hospitals, [[Turkish bath]]s and tombs.
+
+Examples of Ottoman architecture of the classical period, besides Istanbul and [[Edirne]], can also be seen in Egypt, Eritrea, Tunisia, Algiers, the Balkans and Romania, where mosques, bridges, fountains and schools were built. The art of Ottoman decoration developed with a multitude of influences due to the wide ethnic range of the Ottoman Empire. The greatest of the court artists enriched the Ottoman Empire with many pluralistic artistic influences, such as mixing traditional [[Byzantine art]] with elements of [[Chinese art]].<ref>{{cite web|author=Eli Shah |url=http://www.mfa.gov.il/MFA/MFAArchive/1990_1999/1999/2/The%20Ottoman%20Artistic%20Legacy |title=The Ottoman Artistic Legacy |publisher=Israel Ministry of Foreign Affairs |accessdate=26 August 2010 |deadurl=yes |archiveurl=https://web.archive.org/web/20090213131926/http://www.mfa.gov.il/MFA/MFAArchive/1990_1999/1999/2/The%20Ottoman%20Artistic%20Legacy |archivedate=13 February 2009 |df= }}</ref>
+
+=== Decorative arts ===
+[[File:Ottoman_miniature_painters.jpg|thumb|left|Ottoman miniature painters]]
+
+The tradition of [[Ottoman miniature]]s, painted to illustrate manuscripts or used in dedicated albums, was heavily influenced by the [[Persian miniature|Persian]] art form, though it also included elements of the [[Byzantine art|Byzantine]] tradition of [[manuscript illumination|illumination]] and painting.{{Citation needed|date=January 2010}} A Greek academy of painters, the ''Nakkashane-i-Rum'', was established in the [[Topkapi Palace]] in the 15th century, while early in the following century a similar Persian academy, the ''Nakkashane-i-Irani'', was added.
+
+[[Ottoman illumination]] covers non-figurative painted or drawn decorative art in books or on sheets in ''[[muraqqa]]'' or albums, as opposed to the figurative images of the [[Ottoman miniature]]. It was a part of the Ottoman Book Arts together with the Ottoman miniature (''taswir''), calligraphy (''hat''), [[Islamic calligraphy]], bookbinding (''cilt'') and [[paper marbling]] (''ebru''). In the Ottoman Empire, [[Illuminated manuscript|illuminated and illustrated manuscripts]] were commissioned by the Sultan or the administrators of the court. In Topkapi Palace, these manuscripts were created by the artists working in ''Nakkashane'', the atelier of the miniature and illumination artists. Both religious and non-religious books could be illuminated. Also sheets for albums ''levha'' consisted of illuminated calligraphy (''hat'') of ''[[tughra]]'', religious texts, verses from poems or proverbs, and purely decorative drawings.
+
+The art of carpet [[weaving]] was particularly significant in the Ottoman Empire, carpets having an immense importance both as decorative furnishings, rich in religious and other symbolism, and as a practical consideration, as it was customary to remove one's shoes in living quarters.<ref name="foroqhi">{{cite book|last=Faroqhi|first=Suraiya|title=Subjects of the Sultan: culture and daily life in the Ottoman Empire|year=2005|publisher=I.B. Tauris|location=London|isbn=1-85043-760-2|page=152|edition=New}}</ref> The weaving of such carpets originated in the [[nomad]]ic cultures of central Asia (carpets being an easily transportable form of furnishing), and eventually spread to the settled societies of Anatolia. Turks used carpets, rugs and [[kilim]]s not just on the floors of a room, but also as a hanging on walls and doorways, where they provided additional insulation. They were also commonly donated to [[mosques]], which often amassed large collections of them.<ref name="foroqhip153">{{cite book |last=Faroqhi |first=Suraiya |title=Subjects of the Sultan: culture and daily life in the Ottoman Empire |edition=New |year=2005 |publisher=I.B. Tauris |location=London |isbn=1-85043-760-2 |page=153}}</ref>
+
+=== Music and performing arts ===
+[[Ottoman classical music]] was an important part of the education of the Ottoman elite. A number of the Ottoman sultans were accomplished musicians and composers themselves, such as [[Selim III]], whose compositions are often still performed today. Ottoman classical music arose largely from a confluence of [[Byzantine music]], [[Armenian music]], [[Arabic music]], and [[Persian traditional music|Persian music]]. Compositionally, it is organised around rhythmic units called [[Usul (music)|usul]], which are somewhat similar to [[Metre (music)|meter]] in Western music, and [[Melody|melodic]] units called [[makam]], which bear some resemblance to Western [[musical mode]]s.
+
+The [[Musical instrument|instruments]] used are a mixture of Anatolian and Central Asian instruments (the [[baglama|saz]], the [[Baglama|bağlama]], the [[Kemenche|kemence]]), other Middle Eastern instruments (the [[Oud|ud]], the [[tanbur]], the [[Qanun (instrument)|kanun]], the [[ney]]), and—later in the tradition—Western instruments (the violin and the piano). Because of a geographic and cultural divide between the capital and other areas, two broadly distinct styles of music arose in the Ottoman Empire: Ottoman classical music, and folk music. In the provinces, several different kinds of [[folk music]] were created. The most dominant regions with their distinguished musical styles are: Balkan-Thracian Türküs, North-Eastern ([[Laz people|Laz]]) Türküs, Aegean Türküs, Central Anatolian Türküs, Eastern Anatolian Türküs, and Caucasian Türküs. Some of the distinctive styles were: [[Ottoman military band|Janissary Music]], [[Roma music]], [[Belly dance]], [[Turkish folk music]].
+
+The traditional [[shadow play]] called [[Karagöz and Hacivat]] was widespread throughout the Ottoman Empire and featured characters representing all of the major ethnic and social groups in that culture.<ref>{{cite web |title=Karagöz and Hacivat, a Turkish shadow play |publisher=All About Turkey |date=20 November 2006 |url=http://www.allaboutturkey.com/karagoz.htm |accessdate=20 August 2012}}</ref><ref>{{cite web |author=Emin Şenyer |title=Karagoz, Traditional Turkish Shadow Theatre |publisher=Karagoz.net |url=http://www.karagoz.net/english/shadowplay.htm |accessdate=11 February 2013}}</ref> It was performed by a single puppet master, who voiced all of the characters, and accompanied by [[tambourine]] (''def''). Its origins are obscure, deriving perhaps from an older Egyptian tradition, or possibly from an Asian source.
+
+<gallery widths="200px" heights="200px">
+File:Abdulaziz.jpg|[[Sultan Abdülaziz]] was also a music composer.
+File:Surname 171b.jpg|Miniature from ''[[Abdulcelil Levni|Surname-i Vehbi]]'' showing the [[Mehteran]], the music band of the [[Janissaries]]
+File:Karagoz figures.jpg|The shadow play [[Karagöz and Hacivat]] was widespread throughout the Ottoman Empire.
+</gallery>
+
+=== Cuisine ===
+{{Main|Ottoman cuisine}}
+[[File:Enjoying Coffee Pera Museum 2 b.jpg|thumb|left|upright|Enjoying [[Turkish coffee|coffee]] at the [[harem]]]]
+[[File:François-Marie Rosset - Femmes Turcs turques de Serquin, leur manière de faire leur pain - Syrie - 1790.jpg|thumb|upright|Turkish women baking bread, 1790]]
+
+[[Ottoman cuisine]] refers to the cuisine of the capital, [[Istanbul]], and the regional capital cities, where the melting pot of cultures created a common cuisine that most of the population regardless of ethnicity shared. This diverse cuisine was honed in the Imperial Palace's kitchens by chefs brought from certain parts of the Empire to create and experiment with different ingredients. The creations of the Ottoman Palace's kitchens filtered to the population, for instance through [[Ramadan]] events, and through the cooking at the [[Yalı]]s of the [[Pasha]]s, and from there on spread to the rest of the population.
+
+Much of the cuisine of former Ottoman territories today is descended from a shared Ottoman cuisine, especially [[Turkish cuisine|Turkish]], and including [[Greek cuisine|Greek]], [[Balkan cuisine|Balkan]], [[Armenian cuisine|Armenian]], and [[Middle Eastern cuisine|Middle Eastern]] cuisines.<ref name="Fragner">Bert Fragner, "From the Caucasus to the Roof of the World: a culinary adventure", in Sami Zubaida and Richard Tapper, ''A Taste of Thyme: Culinary Cultures of the Middle East'', London, [[Prague]] and New York, p. 52</ref> Many common dishes in the region, descendants of the once-common Ottoman cuisine, include [[yogurt]], [[döner kebab]]/[[Gyro (food)|gyro]]/[[shawarma]], [[cacık]]/tzatziki, [[ayran]], [[pita]] bread, [[feta]] cheese, [[baklava]], [[lahmacun]], [[moussaka]], [[yuvarlak]], [[köfte]]/keftés/kofta, [[börek]]/boureki, [[rakı]]/[[rakia]]/[[tsipouro]]/[[tsikoudia]], [[meze]], [[dolma]], [[Sarma (food)|sarma]], rice [[pilaf]], [[Turkish coffee]], [[sujuk]], [[kashk]], [[keşkek]], [[Manti (dumpling)|manti]], [[lavash]], [[kanafeh]], and more.
+
+== Science and technology ==
+{{Main|Science and technology in the Ottoman Empire}}
+[[File:Ottoman Imperial Museum (Today- Istanbul Archaeology Museums).jpg|thumb|left|Ottoman Imperial Museum, today the [[Istanbul Archaeology Museums]]]]
+
+Over the course of Ottoman history, the Ottomans managed to build a large collection of libraries complete with translations of books from other cultures, as well as original manuscripts.<ref name="Ágoston and Alan Masters583"/> A great part of this desire for local and foreign manuscripts arose in the 15th century. [[Mehmet II|Sultan Mehmet II]] ordered [[Georgios Amiroutzes]], a Greek scholar from [[Trabzon]], to translate and make available to Ottoman educational institutions the geography book of [[Ptolemy]]. Another example is [[Ali Qushji]] – an [[Islamic astronomy|astronomer]], [[Islamic mathematics|mathematician]] and [[Islamic physics|physicist]] originally from [[Samarkand]] – who became a professor in two madrasas and influenced Ottoman circles as a result of his writings and the activities of his students, even though he only spent two or three years in Istanbul before his death.<ref>{{cite journal |last1=Ragep |first1=F. J. |year=2005 |title=Ali Qushji and Regiomontanus: eccentric transformations and Copernican Revolutions |journal=Journal for the History of Astronomy |volume=36 |issue=125 |pages=359–371 |publisher=Science History Publications Ltd. |doi= |bibcode=2005JHA....36..359R}}</ref>
+
+[[File:Istambul observatory in 1577.jpg|thumb|[[Istanbul observatory of Taqi ad-Din]] in 1577]]
+
+[[Taqi al-Din Muhammad ibn Ma'ruf|Taqi al-Din]] built the [[Istanbul observatory of Taqi al-Din]] in 1577, where he carried out observations until 1580. He calculated the [[Orbital eccentricity|eccentricity]] of the Sun's orbit and the annual motion of the [[apogee]].<ref name="Tekeli">{{cite encyclopedia|author=Sevim Tekeli |title=Encyclopaedia of the history of science, technology and medicine in non-western cultures|entry=Taqi al-Din|year=1997 |publisher=Kluwer |isbn=0-7923-4066-3|bibcode=2008ehst.book.....S|journal=Encyclopaedia of the History of Science}}</ref> However, the observatory's primary purpose was almost certainly [[astrology|astrological]] rather than astronomical, leading to its destruction in 1580 due to the rise of a clerical faction that opposed its use for that purpose.<ref>{{cite book |last=El-Rouayheb |first=Khaled |title=Islamic Intellectual History in the Seventeenth Century: Scholarly Currents in the Ottoman Empire and the Maghreb |publisher=Cambridge University Press |year=2015 |isbn=978-1-107-04296-4 |pages=18–9}}</ref> He also experimented with [[steam power]] in [[Ottoman Egypt]] in 1551, when he invented a [[steam jack]] driven by a rudimentary [[steam turbine]].<ref>[[Ahmad Y Hassan]] (1976), ''Taqi al-Din and Arabic Mechanical Engineering'', p. 34–35, Institute for the History of Arabic Science, [[University of Aleppo]]</ref>
+
+In 1660 the Ottoman scholar [[Ibrahim Efendi al-Zigetvari Tezkireci]] translated [[Noël Duret]]'s French astronomical work (written in 1637) into Arabic.<ref>{{cite journal |last=Ben-Zaken |first=Avner |year=2004 |url=https://www.academia.edu/1607448/The_heavens_of_the_sky_and_the_heavens_of_the_heart_the_Ottoman_cultural_context_for_the_introduction_of_post-Copernican_astronomy_I_would_like_to_thank_Theodore_Porter_Hossein_Ziai_Carlo_Ginzburg_Robert_Westman_Mary_Terrall_Benjamin_Elman_Norton_Wise_Herbert_Davidson_and_Ahmad_Alwisha_for_the_notes_and_the_encouragement._Thanks_to_Howard_Goodman_for_the_notes_and_the_stylish_English._Special_thanks_to_the_anonymous_referees_for_the_illuminating_notes._The_paper_was_first_presented_at_the_History_of_Science_Colloquium_at_UCLA |title=The Heavens of the Sky and the Heavens of the Heart: the Ottoman Cultural Context for the Introduction of Post-Copernican Astronomy |journal=The British Journal for the History of Science |publisher=[[Cambridge University Press]] |volume=37 |pages=1–28 |doi=10.1017/S0007087403005302 |ref=harv}}</ref>
+
+[[Şerafeddin Sabuncuoğlu]] was the author of the first surgical atlas and the last major [[Medicine in medieval Islam|medical encyclopedia from the Islamic world]]. Though his work was largely based on [[Abu al-Qasim al-Zahrawi]]'s ''[[Al-Tasrif]]'', Sabuncuoğlu introduced many innovations of his own. Female surgeons were also illustrated for the first time.<ref>{{cite journal |last=Bademci |first=G. |title=First illustrations of female Neurosurgeons in the fifteenth century by Serefeddin Sabuncuoglu |journal=Neurocirugía |year=2006 |volume=17 |issue=2 |pages=162–5 |doi=10.4321/S1130-14732006000200012}}</ref>
+
+An example of a watch that measured time in minutes was created by an Ottoman watchmaker, [[Meshur Sheyh Dede]], in 1702.<ref>{{cite journal |last=Horton |first=Paul |title=Topkapi's Turkish Timepieces |date=July–August 1977 |journal=[[Saudi Aramco World]] |pages=10–13 |url=http://www.saudiaramcoworld.com/issue/197704/topkapi.s.turkish.timepieces.htm |accessdate=12 July 2008 |ref=harv |archive-url=https://web.archive.org/web/20081122021637/http://www.saudiaramcoworld.com/issue/197704/topkapi.s.turkish.timepieces.htm |archive-date=22 November 2008 |dead-url=yes |df=dmy-all }}</ref>
+
+In the early 19th century, [[Egypt under Muhammad Ali]] began using [[steam engine]]s for industrial manufacturing, with industries such as [[ironworks]], [[textile manufacturing]], [[paper mill]]s and [[hulling]] mills moving towards steam power.<ref name="batou193">{{cite book|title=Between Development and Underdevelopment: The Precocious Attempts at Industrialization of the Periphery, 1800-1870|author=Jean Batou|publisher=[[:fr:Librairie Droz|Librairie Droz]]|year=1991|url=https://books.google.com/books?id=HjD4SCOE6IgC&pg=PA193|pages=193–196|isbn=9782600042932}}</ref> Economic historian Jean Batou argues that the necessary economic conditions existed in Egypt for the adoption of [[oil]] as a potential energy source for its steam engines later in the 19th century.<ref name="batou193"/>
+
+In the 19th century, [[Ishak Efendi]] is credited with introducing the then current Western scientific ideas and developments to the Ottoman and wider Muslim world, as well as the invention of a suitable Turkish and Arabic scientific terminology, through his translations of Western works.
+
+== Sports ==
+[[File:Oil wrestling match in the gardens of the Sultan's Palace.jpg|thumb|right|Ottoman wrestlers in the gardens of [[Topkapı Palace]], in the 19th century]]
+
+The main sports Ottomans were engaged in were [[Turkish wrestling]], [[hunting]], [[Turkish archery]], [[horseback riding]], [[Cirit|equestrian javelin throw]], [[arm wrestling]], and [[Swimming (sport)|swimming]]. European model sports clubs were formed with the spreading popularity of [[football]] matches in 19th century [[Constantinople]]. The leading clubs, according to timeline, were [[Beşiktaş J.K.|Beşiktaş Gymnastics Club]] (1903), [[Galatasaray S.K.|Galatasaray Sports Club]] (1905), [[Fenerbahçe S.K.|Fenerbahçe Sports Club]] (1907), [[MKE Ankaragücü |MKE Ankaragücü (formerly Turan Sanatkaragücü)]] (1910) in [[Istanbul]]. Football clubs were formed in other provinces too, such as [[Karşıyaka S.K.|Karşıyaka Sports Club]] (1912), [[Altay S.K.|Altay Sports Club]] (1914) and [[Ülküspor|Turkish Fatherland Football Club]] (later [[Ülküspor]]) (1914) of [[İzmir]].
+
+== See also ==
+{{Portal|Ottoman Empire|Turkey|Mediterranean}}
+* [[16 Great Turkic Empires]]
+* [[Bibliography of the Ottoman Empire]]
+* [[Gaza Thesis]]
+* [[Gunpowder Empires]]
+* [[Historiography of the fall of the Ottoman Empire]]
+* [[History of the Turkic peoples|History of the Turks]]
+* [[Index of Ottoman Empire-related articles]]
+* [[List of sultans of the Ottoman Empire]]
+* [[List of Ottoman Grand Viziers]]
+* [[List of Ottoman conquests, sieges and landings]]
+* [[List of Turkic dynasties and countries]]
+* [[Outline of the Ottoman Empire]]
+* [[Ottoman Decline Thesis]]
+* [[Ottoman dynasty]]
+* [[Ottoman Caliphate]]
+* [[Ottoman Tunisia]]
+* [[Superpower#Superpowers of the past|Superpowers of the past]]
+
+== Notes ==
+{{reflist|30em|group=note}}
+
+== References ==
+{{Reflist|30em}}
+
+== Further reading ==
+{{Main|Bibliography of the Ottoman Empire}}
+{{Library resources box|onlinebooks=yes}}
+
+===General surveys===
+{{refbegin}}
+* ''The Cambridge History of Turkey''
+:* Volume 1: Kate Fleet ed., "Byzantium to Turkey 1071–1453." Cambridge University Press, 2009.
+:* Volume 2: Suraiya N. Faroqhi and Kate Fleet eds., "The Ottoman Empire as a World Power, 1453–1603." Cambridge University Press, 2012.
+:* Volume 3: Suraiya N. Faroqhi ed., "The Later Ottoman Empire, 1603–1839." Cambridge University Pres, 2006.
+:* Volume 4: Reşat Kasaba ed., "Turkey in the Modern World." Cambridge University Press, 2008.
+* {{Cite book|last=Finkel |first=Caroline |title=Osman's Dream: The Story of the Ottoman Empire, 1300–1923 |publisher=Basic Books |date=2005 |isbn=978-0-465-02396-7}}
+* {{cite book |last=Hathaway |first=Jane |title=The Arab Lands under Ottoman Rule, 1516–1800 |publisher=Pearson Education Ltd. |year=2008 |isbn=978-0-582-41899-8}}
+* {{cite book |last=Howard |first=Douglas A. |title=A History of the Ottoman Empire |publisher=Cambridge University Press |place=Cambridge |year=2017|isbn=978-0-521-72730-3}}
+* {{Cite book|last=Imber |first=Colin |title=The Ottoman Empire, 1300–1650: The Structure of Power |edition=2 |publisher=Palgrave Macmillan |place=New York |date=2009 |isbn=978-0-230-57451-9}}
+* {{cite book |editor-last=İnalcık |editor-first=Halil |editor2=Donald Quataert |title=An Economic and Social History of the Ottoman Empire, 1300–1914 |publisher=Cambridge University Press |date=1994 |isbn=0-521-57456-0}} Two volumes.
+* McCarthy, Justin. ''The Ottoman Turks: An Introductory History to 1923.'' 1997 [https://www.questia.com/read/58745078 Questia.com], online edition.
+* Quataert, Donald. ''The Ottoman Empire, 1700–1922.'' 2005. {{ISBN|0-521-54782-2}}.
+
+===Early Ottomans===
+* {{Cite book|last=Kafadar |first=Cemal |title=Between Two Worlds: The Construction of the Ottoman State |publisher=University of California Press |date=1995 |isbn=978-0-520-20600-7}}
+* {{Cite book|last=Lindner |first=Rudi P. |title=Nomads and Ottomans in Medieval Anatolia |publisher=Indiana University Press |place=Bloomington |date=1983 |isbn=0-933070-12-8}}
+* {{Cite book|last=Lowry |first=Heath |title=The Nature of the Early Ottoman State |publisher=SUNY Press |place=Albany |date=2003 |isbn=0-7914-5636-6}}
+
+===Military===
+* {{cite journal |last=Ágoston |first=Gábor |title=Firearms and Military Adaptation: The Ottomans and the European Military Revolution, 1450–1800 |journal=Journal of World History |volume=25 |date=2014 |pages=85–124}}
+* {{cite book |first=Virginia |last=Aksan |title=Ottoman Wars, 1700–1860: An Empire Besieged |publisher=Pearson Education Limited |date=2007 |isbn=978-0-582-30807-7}}
+* {{cite book |last=Rhoads |first=Murphey |title=Ottoman Warfare, 1500–1700 |publisher=Rutgers University Press |date=1999 |isbn=1-85728-389-9}}
+* {{cite book |last=Soucek |first=Svat |title=Ottoman Maritime Wars, 1416–1700 |publisher=The Isis Press |place=Istanbul |date=2015 |isbn=978-975-428-554-3}}
+
+===Miscellaneous===
+* Baram, Uzi and Lynda Carroll, editors. ''A Historical Archaeology of the Ottoman Empire: Breaking New Ground'' (Plenum/Kluwer Academic Press, 2000)
+* Barkey, Karen. ''Empire of Difference: The Ottomans in Comparative Perspective.'' (2008) 357pp [https://www.amazon.com/Empire-Difference-Ottomans-Comparative-Perspective/dp/0521715334/ref=sr_1_7?ie=UTF8&s=books&qid=1240307430&sr=1-7 Amazon.com], excerpt and text search
+* Davison, Roderic H. ''Reform in the Ottoman Empire, 1856–1876'' (New York: Gordian Press, 1973)
+* Deringil, Selim. ''The well-protected domains: ideology and the legitimation of power in the Ottoman Empire, 1876–1909'' (London: IB Tauris, 1998)
+* Findley, Carter V. ''Bureaucratic Reform in the Ottoman Empire: The Sublime Porte, 1789–1922'' (Princeton University Press, 1980)
+* [[Suraiya Faroqhi|Faroqhi, Suraiya]]. ''The Ottoman Empire: A Short History'' (2009) 196pp 
+* McMeekin, Sean. ''The Berlin-Baghdad Express: The Ottoman Empire and Germany's Bid for World Power'' (2010)
+* Nicolle, David. ''Armies of the Ottoman Turks 1300–1774'' (Osprey Publishing, 1983)
+* Palmer, Alan. ''The Decline and Fall of the Ottoman Empire''. (New York: Barnes and Noble, 1992) 306 p., maps. {{ISBN|0-87131-754-0}}
+* Pamuk, Sevket. ''A Monetary History of the Ottoman Empire'' (1999). pp.&nbsp;276
+* Somel, Selcuk Aksin. ''Historical Dictionary of the Ottoman Empire'' (2003). pp.&nbsp;399
+* Stone, Norman "Turkey in the Russian Mirror" pages 86–100 from ''Russia War, Peace and Diplomacy'' edited by Mark & Ljubica Erickson, Weidenfeld & Nicolson: London, 2004 {{ISBN|0-297-84913-1}}.
+* {{cite book |last1=Uyar |first1=Mesut |last2=Erickson |first2=Edward |title=A Military History of the Ottomans: From Osman to Atatürk |year=2009 |isbn=978-0-275-98876-0}}
+
+===Historiography===
+* Hartmann, Daniel Andreas. "Neo-Ottomanism: The Emergence and Utility of a New Narrative on Politics, Religion, Society, and History in Turkey" (PhD Dissertation, Central European University, 2013) [http://www.etd.ceu.hu/2013/hartmann_daniel.pdf online].
+* {{Cite journal|last=Kayalı|first=Hasan|date=December 2017|title=The Ottoman Experience of World War I: Historiographical Problems and Trends|url=https://www.journals.uchicago.edu/doi/10.1086/694391|journal=The Journal of Modern History|language=en|volume=89|issue=4|pages=875–907|doi=10.1086/694391|issn=0022-2801}}
+* Lieven, Dominic. ''Empire: The Russian empire and its rivals'' (Yale UP, 2002), comparisons with Russian, British, & Habsburg empires. [https://www.amazon.com/Empire-Russian-Its-Rivals/dp/0300097263/ excerpt]
+* Mikhail, Alan; Philliou, Christine M. "The Ottoman Empire and the Imperial Turn," ''Comparative Studies in Society & History'' (2012) 54#4 pp 721–745. Comparing the Ottomans to other empires opens new insights about the dynamics of imperial rule, periodization, and political transformation
+* Olson, Robert, "Ottoman Empire" in {{cite book|author=Kelly Boyd, ed|title=Encyclopedia of Historians and Historical Writing vol 2|url=https://books.google.com/books?id=0121vD9STIMC&pg=PA892|year=1999|publisher=Taylor & Francis|pages=892–6|isbn=9781884964336}}
+* Quataert, Donald. "Ottoman History Writing and Changing Attitudes towards the Notion of 'Decline.'" ''History Compass'' 1 (2003): 1–9.
+{{refend}}
+
+== External links ==
+{{Spoken Wikipedia-2|2008-03-29|Wikipedia - Ottoman Empire - Main History.ogg|Wikipedia - Ottoman Empire - Part 2.ogg}}
+{{Sister project links |wikt= |commons=Ottoman Empire |commonscat=yes|b=yes|voy=yes|v=yes|s=yes|d=yes|d-search=Q12560}}
+*[http://courses.washington.edu/otap/ Ottoman Text Archive Project – University of Washington]
+*[http://www.shapell.org/journeys.aspx?american-travelers-to-the-holy-land-in-the-19th-century American Travelers to the Holy Land in the 19th Century] Shapell Manuscript Foundation
+*[http://www.umich.edu/~turkish/ottemp.html The Ottoman Empire: Resources – University of Michigan]
+*[http://www.theottomans.org/ Information about Ottomans]
+*[http://www.wdl.org/en/item/11770/ Turkey in Asia], 1920
+
+{{Ottoman Empire topics}}
+{{Navboxes
+|list=
+{{Former Monarchies}}
+{{Turkic topics}}
+{{Turkey topics}}
+{{History of Anatolia}}
+{{Empires}}
+{{Medieval states in Anatolia}}
+{{History of Europe}}
+}}
+
+{{Authority control}}
+
+[[Category:Ottoman Empire| ]]
+[[Category:Historical Turkic states]]
+[[Category:1299 establishments in Asia]]
+[[Category:1923 disestablishments in Asia]]
+[[Category:1923 disestablishments in Europe]]
+[[Category:States and territories established in 1299]]
+[[Category:States and territories disestablished in 1922]]
+[[Category:States and territories disestablished in 1923]]
+
+{{Infobox military conflict
+| conflict   = Russo-Turkish War (1877–1878)
+| partof     = [[Great Eastern Crisis]]
+| image      = File:The defeat of Shipka Peak, Bulgarian War of Independence.JPG
+| caption    = The [[Battle of Shipka Pass]] in August 1877
+| date       = 24 April 1877 – 3 March 1878 (10 months, 1 week, 2 days)
+| place      = [[Balkans]], [[Caucasus]]
+| territory  = 
+* Reestablishment of the [[Principality of Bulgaria|Bulgarian state]]
+* ''[[De jure]]'' independence of [[United Principalities|Romania]], [[Principality of Serbia|Serbia]] and [[Principality of Montenegro|Montenegro]] from the [[Ottoman Empire]]
+* [[Kars Oblast|Kars]] and [[Batum Oblast]]s become part of the [[Russian Empire]]
+| result     = Russian coalition victory
+* [[Treaty of San Stefano]]
+* [[Treaty of Berlin (1878)|Treaty of Berlin]]
+| combatant1 = {{plainlist|
+*{{flagcountry|Russian Empire|1858}}
+*{{flagdeco|Serbia|civil}} [[Principality of Serbia|Serbia]]
+*{{flagdeco|Kingdom of Romania}} [[United Principalities|Romania]]
+*{{flagcountry|Principality of Montenegro}}
+*{{flagdeco|Kingdom of Bulgaria}} [[Opalchentsi|Bulgarian Legion]]}}
+| combatant2 = {{flag|Ottoman Empire}}
+*[[Chechen people|Chechen]] and [[Dagestan|Dagestani]] [[Insurgency|Insurgents]]
+*[[Abkhazians|Abkhazian]] [[Insurgency|Insurgents]]
+*[[Polish Legion in Turkey|Polish Legion]]
+| commander1 = {{plainlist|
+*{{flagicon|Russian Empire|1858}} [[Alexander II of Russia|Alexander II]]
+*{{flagicon|Russian Empire|1858}} [[Grand Duke Nicholas Nikolaevich of Russia (1831–1891)|Grand Duke Nicholas Nikolaevich]]
+*{{flagicon|Russian Empire|1858}} [[Grand Duke Michael Nikolaevich of Russia|Grand Duke Michael Nikolaevich]]
+*{{flagicon|Russian Empire|1858}} [[Dmitry Milyutin]]
+*{{flagicon|Russian Empire|1858}} [[Iosif Gurko]]
+*{{flagicon|Russian Empire|1858}} [[Mikhail Loris-Melikov]]
+*{{flagicon|Russian Empire|1858}} [[Grigol Dadiani (Kolkhideli)|Grigol Dadiani]]
+*{{flagicon|Russian Empire|1858}} [[Alexander III of Russia|Tsesarevich Alexander Alexandrovich]]
+*{{flagicon|Russian Empire|1858}} [[Pyotr Vannovsky]]
+*{{flagicon|Russian Empire|1858}} [[Mikhail Dragomirov]]
+*{{flagicon|Russian Empire|1858}} [[Mikhail Skobelev]]
+*{{flagicon|Russian Empire|1858}} [[Ivan Davidovich Lazarev|Ivan Lazarev]]
+*{{flagicon|Kingdom of Romania}} [[Carol I of Romania]]
+*{{flagicon|Principality of Montenegro}} [[Nicholas I of Montenegro]]
+*{{flagicon|Serbia|civil}} [[Milan I of Serbia]]
+*{{flagicon|Serbia|civil}} [[Kosta Protić]]}}
+| commander2 = {{plainlist|
+*{{flagicon|Ottoman Empire}} [[Abdul Hamid II]]
+*{{flagicon|Ottoman Empire}} [[Ahmed Muhtar Pasha|Ahmed Pasha]]
+*{{flagicon|Ottoman Empire}} [[Osman Nuri Pasha|Osman Pasha]]
+*{{flagicon|Ottoman Empire}} [[Süleyman Hüsnü Paşa|Suleiman Pasha]]
+*{{flagicon|Ottoman Empire}} [[Mehmed Ali Pasha (marshal)|Mehmed Pasha]]
+*{{flagicon|Ottoman Empire}} [[Abdülkerim Nadir Pasha|Abdülkerim Pasha]]
+*{{flagicon|Ottoman Empire}} [[Ahmed Eyüb Pasha]]
+*{{flagicon|Ottoman Empire}} [[Mehmed Riza Pasha]]}}
+| strength1  = {{plainlist|
+*'''Russian Empire''': 185,000 in the Army of the Danube, 75,000 in the Caucasian Army<ref>Timothy C. Dowling. Russia at War: From the Mongol Conquest to Afghanistan, Chechnya, and Beyond. 2 Volumes. ABC-CLIO, 2014. P. 748</ref><br>260,000 total
+*'''Finland''': 1,000
+*'''Serbia''': 81,500
+*'''Romania''': 66,000
+*'''Montenegro''': 45,000
+*'''Bulgarians''': 60,000}}
+*200 cannons
+| strength2   = '''Ottoman Empire''': 70,000 in the Caucasus<ref name="Clodfelter, p. 196">Clodfelter, p. 196</ref><br>281,000 total<ref>{{Citation |last=Мерников |first=АГ |script-title=ru:Спектор А. А. Всемирная история войн |place=Minsk |year=2005 |page=376 |language=Russian }}</ref>
+| casualties1 = {{plainlist|
+*'''Russian Empire'''
+**15,567<ref name="Урланис">{{cite book| author = [[Урланис Б. Ц.]] | chapter = Войны в период домонополистического капитализма (Ч. 2)| chapter-url = http://scepsis.net/library/id_2140.html#a161| format = | url =  | title = Войны и народонаселение Европы. Людские потери вооруженных сил европейских стран в войнах XVII—XX вв. (Историко-статистическое исследование) | orig-year = | agency =  | edition = | location = М.| year = 1960 | publisher = [[Соцэкгиз]]| at = | volume = | issue = | pages = 104–105, 129 § 4| page =  | series =  | isbn = | ref = }}</ref>–34,742<ref>Clodfelter, p. 196</ref> killed
+**81,166 died of disease
+**56,652 wounded
+**1,713 died from wounds<ref name="Урланис"/><ref name="Clodfelter, p. 196">Clodfelter, p. 196</ref>
+*'''Romania'''
+** 4,302 killed and missing
+** 3,316 wounded
+**19,904 sick<ref>Scafes, Cornel, et. al., ''Armata Romania in Razvoiul de Independenta 1877–1878'' (The Romanian Army in the War of Independence 1877–1878). Bucuresti, Editura Sigma, 2002, p. 149 (Romence)</ref>
+*'''Bulgaria'''
+**2,456 dead and wounded<ref name="scepsis.net">Борис Урланис, Войны и народонаселение Европы, Часть II, Глава II http://scepsis.net/library/id_2140.html</ref>
+*'''Serbia''' and '''Montenegro'''
+** 2,400 dead and wounded<ref name="scepsis.net"/>}}
+| casualties2 = {{plainlist|
+*~30,000 killed,<ref name="Мерников Спектор">{{cite book| author1 = Мерников А. Г.|author2= Спектор А. А.| title = Всемирная история войн| location = Мн.| year = 2005| publisher = Харвест| isbn = 985-13-2607-0}}</ref>
+*60,000<ref name="Clodfelter, p. 196">Clodfelter, p. 196</ref>–90,000<ref name="Мерников Спектор"/> died from wounds and diseases
+*Tens of thousands captured<ref name="Clodfelter, p. 196">Clodfelter, p. 196</ref>}}
+| campaignbox =
+{{Campaignbox Russo-Turkish War (1877–1878)}}
+{{Russo-Ottoman War Series}}
+}}
+
+The '''Russo-Turkish War of 1877–78''' ({{lang-tr|93 Harbi|lit=War of ’93}}, named for the year 1293 in the [[Islamic calendar]]; {{lang-bg|Руско-турска Освободителна война|Rusko-turska Osvoboditelna vojna}}, "Russian-Turkish Liberation war") was a conflict between the [[Ottoman Empire]] and the [[Eastern Orthodox Church|Eastern Orthodox]] coalition led by the [[Russian Empire]] and composed of [[Kingdom of Bulgaria|Bulgaria]], [[Kingdom of Romania|Romania]], [[Kingdom of Serbia|Serbia]], and [[Principality of Montenegro|Montenegro]].<ref>{{cite book |author=Crowe, John Henry Verrinder |author-link =  |chapter=Russo-Turkish Wars (1828-29 and 1877-1878 - The War of 1877-78) |title=The Encyclopaedia Britannica; A Dictionary of Arts, Sciences, Literature and General Information |pages= 931-936 |year=1911 |volume= XXIII (REFECTORY to SAINTE-BEUVE)|edition= 11th |publisher=At the University Press |place=Cambridge, England and New York|url=https://archive.org/stream/encyclopaediabri23chisrich#page/930 |accessdate= 19 July 2018 |via= Internet Archive}}</ref> Fought in the [[Balkans]] and in the [[Caucasus]], it originated in emerging [[19th-century]] Balkan [[nationalism]]. Additional factors combined Russian goals of recovering territorial losses endured during the [[Crimean War]], re-establishing itself in the [[Black Sea]] and supporting the political movement attempting to free Balkan nations from the Ottoman Empire.
+
+The Russian-led coalition won the war. As a result, Russia succeeded in claiming several provinces in the Caucasus, namely [[Kars Oblast|Kars]] and [[Batum Oblast|Batum]], and also annexed the [[Budjak]] region. The principalities of [[United Principalities|Romania]], [[Principality of Serbia|Serbia]], and [[Principality of Montenegro|Montenegro]], each of whom had ''de facto'' sovereignty for some time, formally proclaimed independence from the [[Ottoman Empire]]. After almost five centuries of Ottoman domination (1396–1878), the Bulgarian state was re-established as the [[Principality of Bulgaria]], covering the land between the [[Danube]] River and the [[Balkan Mountains]] (except Northern [[Dobrudja]] which was given to Romania), as well as the region of [[Sofia]], which became the new state's capital. The [[Congress of Berlin]] in 1878 also allowed [[Austria-Hungary]] to [[Austro-Hungarian rule in Bosnia and Herzegovina|occupy Bosnia and Herzegovina]] and [[Great Britain]] to take over [[Cyprus]].
+
+The initial Treaty of San Stefano, signed on 3 March, is today celebrated as [[Liberation Day]] in Bulgaria,<ref>{{cite book|title=Labour Law in Bulgaria|first=Vasil|last=Mrŭchkov|p=120|publisher=Kluwer Law International|year=2011|isbn=978-9-041-13616-9}}</ref> although it somewhat fell out of favour during years of Socialist rule.<ref>{{cite book|title=Nationalism from the Left: The Bulgarian Communist Party During the Second World War and the Early Post-War Years|first=Yannis|last=Sygkelos|p=220|publisher=Brill|year=2011|isbn=978-9-004-19208-9}}</ref>
+
+==Conflict pre-history==
+=== Treatment of Christians in the Ottoman Empire ===
+Article 9 of the [[Treaty of Paris (1856)|1856 Paris Peace Treaty]], concluded at the end of the [[Crimean War]], obliged the Ottoman Empire to grant Christians equal rights with Muslims. Before the treaty was signed, the Ottoman government issued an edict, the [[Edict of Gülhane]], which proclaimed the principle of the equality of Muslims and non-Muslims,<ref>{{Citation | url = http://www.anayasa.gen.tr/reform.htm | type = full text | title = Hatt-ı Hümayun | publisher = Anayasa | place = Turkey}}.</ref> and produced some specific reforms to this end. For example, the [[jizya]] tax was abolished and non-Muslims were allowed to join the army.<ref>{{Citation | last = Vatikiotis | first = PJ | title = The Middle East | place = London | publisher = Routledge | year = 1997 | page = 217 | ISBN = 0-415-15849-4}}.</ref>
+
+However, some key aspects of [[dhimmi]] status were retained, including that the testimony of Christians against Muslims was not accepted in courts, which granted Muslims effective immunity for offenses conducted against Christians. Although local level relations between communities were often good, this practice encouraged exploitation. Abuses were at their worst in regions with a predominantly Christian population, where local authorities often openly supported abuse as a means to keep Christians subjugated.{{Sfn | Argyll | 1879}}{{Rp | needed = yes|date=March 2013}}
+
+====Crisis in Lebanon, 1860====
+{{Main|1860 Druze–Maronite conflict}}
+In 1858, the [[Maronite]] peasants, stirred by the clergy, revolted against their [[Druze]] feudal overlords and established a peasant republic. In southern [[Lebanon]], where Maronite peasants worked for Druze overlords, Druze peasants sided with their overlords against the Maronites, transforming the conflict into a [[1860 Druze-Christian conflict in Lebanon|civil war]]. Although both sides suffered, about 10,000 Maronites were [[massacre]]d at the hands of the Druze.<ref name="countrystudies.us">{{Citation | url = http://countrystudies.us/lebanon/74.htm | title = Country Studies | contribution = Lebanon | place = US | publisher = Library of Congress | year = 1994}}.</ref><ref>{{Citation | url = http://dlxs2.library.cornell.edu/cgi/t/text/text-idx?c=cdl;idno=cdl324 | page = 219 | title = The Druzes and the Maronites under the Turkish rule from 1840 to 1860 | first = C | last = Churchill | place = London | publisher = B Quaritch | year = 1862}}.</ref>
+
+Under the threat of European intervention, Ottoman authorities restored order. Nevertheless, [[Règlement Organique (Mount Lebanon)|French and British intervention]] followed.{{Sfn | Shaw | Shaw | 1977 | pp = 142–43}} Under further European pressure, the Sultan agreed to appoint a Christian governor in Lebanon, whose candidacy was to be submitted by the Sultan and approved by the European powers.<ref name = "countrystudies.us" />
+
+On May 27, 1860 a group of Maronites raided a Druze village.{{Citation needed|date =March 2008}} Massacres and reprisal massacres followed, not only in the Lebanon but also in [[Syria]]. In the end, between 7,000 and 12,000 people of all religions{{Citation needed|date=March 2008}} had been killed, and over 300 villages, 500 churches, 40 monasteries, and 30 schools were destroyed. Christian attacks on Muslims in Beirut stirred the Muslim population of [[Damascus]] to attack the Christian minority with between 5,000 and 25,000 of the latter being killed,{{Citation needed|date=August 2009}} including the [[United States of America|American]] and [[Kingdom of the Netherlands|Dutch]] consuls, giving the event an international dimension.
+
+Ottoman foreign minister [[Mehmed Fuad Pasha]] came to Syria and solved the problems by seeking out and executing the culprits, including the governor and other officials. Order was restored, and preparations made to give Lebanon new autonomy to avoid European intervention. Nevertheless, in September 1860 France sent a fleet, and Britain joined to prevent a unilateral intervention that could help increase French influence in the area at Britain's expense.{{Sfn | Shaw | Shaw | 1977 | pp = 142–43}}
+
+====The revolt in Crete, 1866–1869====
+[[File:MoniArkadiou2.JPG|thumb|right|The [[Moni Arkadiou]] monastery]]
+The [[Cretan Revolt (1866–69)|Cretan Revolt]], which began in 1866, resulted from the failure of the Ottoman Empire to apply reforms for improving the life of the population and the Cretans' desire for [[enosis]] — union with [[Kingdom of Greece (Glücksburg)|Greece]].<ref>{{cite journal|last1=Robson|first1=Maureen M.|title=Lord Clarendon and the Cretan Question, 1868-9|journal=The Historical Journal|date=1960|volume=3|issue=1|pages=38–55}}</ref> The insurgents gained control over the whole island, except for five cities where the Muslims were fortified. The Greek press claimed that Muslims had massacred Greeks and the word was spread throughout Europe. Thousands of Greek volunteers were mobilized and sent to the island.
+
+The siege of [[Moni Arkadiou]] monastery became particularly well known. In November 1866, about 250 Cretan Greek combatants and around 600 women and children were besieged by about 23,000 mainly Cretan Muslims aided by Ottoman troops, and this became widely known in Europe. After a bloody battle with a large number of casualties on both sides, the Cretan Greeks finally surrendered when their ammunition ran out but were killed upon surrender.<ref>{{Citation | last = Stillman | first = William James | url = http://www.gutenberg.org/files/11594/11594.txt | title = The Autobiography of a Journalist | volume = II | publisher = The Project Gutenberg | format = ebook | date = March 15, 2004 | id = [[eBook#11594]]}}.</ref>
+
+By early 1869, the insurrection was suppressed, but [[Ottoman Porte|the Porte]] offered some concessions, introducing island self-rule and increasing Christian rights on the island. Although the Cretan crisis ended better for the Ottomans than almost any other diplomatic confrontation of the century, the insurrection, and especially the brutality with which it was suppressed, led to greater public attention in Europe to the oppression of Christians in the Ottoman Empire.
+
+{{Quote |Small as the amount of attention is which can be given by the people of England to the affairs of Turkey ... enough was transpiring from time to time to produce a vague but a settled and general impression that the Sultans were not fulfilling the "solemn promises" they had made to Europe; that the vices of the Turkish government were ineradicable; and that whenever another crisis might arise affecting the "independence" of the Ottoman Empire, it would be wholly impossible to afford to it again the support we had afforded in the [[Crimean war]].{{Sfn | Argyll | 1879 | p = 122}}}}
+
+===Changing balance of power in Europe===
+{{Refimprove section|date=March 2011}}
+Although on the winning side in the [[Crimean War]], the Ottoman Empire [[Decline of the Ottoman Empire|continued to decline]] in power and prestige. The financial strain on the treasury forced the Ottoman government to take a series of foreign loans at such steep interest rates that, despite all the fiscal reforms that followed, pushed it into unpayable debts and economic difficulties. This was further aggravated by the need to accommodate more than 600,000 Muslim [[Circassians]], expelled by the Russians from the Caucasus, to the Black Sea ports of north Anatolia and the Balkan ports of [[Constanţa]] and [[Varna]], which cost a great deal in money and in civil disorder to the Ottoman authorities.<ref>{{Citation | last = Finkel | first = Caroline | title = The History of the Ottoman Empire | place = New York | publisher = Basic Books | year = 2005 | page = 467}}.</ref>
+
+====The New European Concert====
+The [[Concert of Europe]] established in 1814 was shaken in 1859 when France and Austria [[Second Italian War of Independence|fought over Italy]]. It came apart completely as a result of the wars of [[German Unification]], when the [[Kingdom of Prussia]], led by Chancellor [[Otto von Bismarck]], defeated Austria in 1866 and France in 1870, replacing Austria-Hungary as the dominant power in Central Europe. Britain, worn out by its participation in the Crimean War and diverted by the [[Irish question]] and the social problems created by the [[Industrial Revolution]], chose not to intervene again to restore the European balance. Bismarck did not wish the breakup of the Ottoman Empire to create rivalries that might lead to war, so he took up the Tsar's earlier suggestion that arrangements be made in case the Ottoman Empire fell apart, creating the [[Three Emperors' League]] with Austria and Russia to keep France isolated on the continent.
+
+France responded by supporting self-determination movements, particularly if they concerned the three emperors and the Sultan. Thus revolts in Poland against Russia and national aspirations in the Balkans were encouraged by France. Russia worked to regain its right to maintain a fleet on the Black Sea and vied with the French in gaining influence in the Balkans by using the new [[Pan-Slavic]] idea that all Slavs should be united under Russian leadership. This could be done only by destroying the two empires where most non-Russian Slavs lived, the Habsburg and the Ottoman Empires. The ambitions and the rivalries of the Russians and French in the Balkans surfaced in Serbia, which was experiencing its own national revival and had ambitions that partly conflicted with those of the great powers.{{Sfn | Shaw | Shaw | 1977 | p = 146}}
+
+====Russia after the Crimean War====
+[[File:Alexander Mikhailovich Gorchakov.jpg|thumb|[[Alexander Gorchakov]]]]
+
+Russia ended the Crimean War with minimal territorial losses, but was forced to destroy its [[Black Sea Fleet]] and [[Sevastopol]] fortifications. Russian international prestige was damaged, and for many years revenge for the Crimean War became the main goal of Russian foreign policy. This was not easy though — the [[Treaty of Paris (1856)|Paris Peace Treaty]] included guarantees of Ottoman territorial integrity by Great Britain, France and Austria; only Prussia remained friendly to Russia.
+
+The newly appointed Russian chancellor, [[Alexander Mikhailovich Gorchakov|Alexander Gorchakov]] depended upon alliance with Prussia and its chancellor [[Otto von Bismarck|Bismarck]]. Russia consistently supported Prussia in her wars with [[Second Schleswig War|Denmark (1864)]], [[Austro-Prussian War|Austria (1866)]] and [[Franco-Prussian War|France (1870)]]. In March 1871, using the crushing French defeat and the support of a grateful Germany, Russia achieved [[Commissions of the Danube River#London Conference of 1871|international recognition]] of its earlier denouncement of Article 11 of the [[Treaty of Paris (1856)|Paris Peace Treaty]], thus enabling it to revive the [[Black Sea Fleet]].
+
+Other clauses of the Paris Peace Treaty, however, remained in force, specifically Article 8 with guarantees of Ottoman territorial integrity by Great Britain, France and Austria. Therefore, Russia was extremely cautious in its relations with the Ottoman Empire, coordinating all its actions with other European powers. A Russian war with Turkey would require at least the tacit support of all other Great Powers, and Russian diplomacy was waiting for a convenient moment.
+
+==Balkan crisis of 1875–1876==
+The state of Ottoman administration in the Balkans continued to deteriorate throughout the 19th century, with the central government occasionally losing control over whole provinces. Reforms imposed by European powers did little to improve the conditions of the Christian population, while managing to dissatisfy a sizable portion of the Muslim population. [[Bosnia and Herzegovina]] suffered at least two waves of rebellion by the local Muslim population, the most recent in 1850.
+
+Austria consolidated after the turmoil of the first half of the century and sought to reinvigorate its longstanding policy of expansion at the expense of the Ottoman Empire. Meanwhile, the nominally autonomous, de facto independent principalities of Serbia and Montenegro also sought to expand into regions inhabited by their compatriots. Nationalist and [[irredentism|irredentist]] sentiments were strong and were encouraged by Russia and her agents. At the same time, a severe drought in Anatolia in 1873 and flooding in 1874 caused famine and widespread discontent in the heart of the Empire. The agricultural shortages precluded the collection of necessary taxes, which forced the Ottoman government to declare bankruptcy in October, 1875 and increase taxes on outlying provinces including the Balkans.
+
+===Balkan uprisings===
+
+====Herzegovina Uprising====
+{{Main|Herzegovina Uprising (1875–78)}}
+An uprising against Ottoman rule began in Herzegovina in July 1875. By August almost all of Herzegovina had been seized and the revolt had spread into Bosnia. Supported by nationalist volunteers from Serbia and Montenegro, the uprising continued as the Ottomans committed more and more troops to suppress it.
+
+====Bulgarian Uprising====
+{{Main|April Uprising}}
+[[File:Basibozuk-1877.jpg|thumb|Bashi-bazouks' atrocities in [[Macedonia (region)|Macedonia]]]]
+The revolt of Bosnia and Herzegovina spurred Bucharest-based Bulgarian revolutionaries into action. In 1875, a Bulgarian uprising was hastily prepared to take advantage of Ottoman preoccupation, but it fizzled before it started. In the spring of 1876, another uprising erupted in the south-central Bulgarian lands despite the fact that there were numerous regular Turkish troops in those areas.
+
+A special Turkish military committee was established to quell the uprising. Regular troops (Nisam) and irregular ones (Redif or Bashi-bazouk) were directed to fight the Bulgarians (May 11 – June 9, 1876). The irregulars were mostly drawn from the Muslim inhabitants of the Bulgarian regions, many of whom were [[Circassians|Circassian]] Islamic population which migrated from the [[Caucasus]] or [[Crimean Tatars|Crimean Tatar]]s who were expelled during the [[Crimean War]] and even Islamized Bulgarians. The Turkish army suppressed the revolt, massacring up to 30,000{{Sfn | Hupchick | 2002 | p = 264}}{{Sfn | Jonassohn | 1999 | pp = 209–10}} people in the process.<ref>{{Citation | title = The Turkish empire from 1288 to 1914 | first = Baron George Shaw-Lefevre | last = Eversley | year = 1924 | page = 319}}.</ref>{{Sfn | Jonassohn | 1999 | p = 210}} Five thousand out of the seven thousand villagers of Batak were put to death.<ref>{{cite journal | last1 = (Editorial staff) | title = Massacre | journal = New Statesman | volume = 6 | issue = 139 | pages = 201–202 | date = 4 December 1915 | url = https://babel.hathitrust.org/cgi/pt?id=mdp.39015073107511;view=1up;seq=216}} ; see p. 202.</ref> Both Batak and Perushtitsa, where the majority of the population was also massacred, participated in the rebellion.{{Sfn | Jonassohn | 1999 | pp = 209–10}} Many of the perpetrators of those massacres were later decorated by the Ottoman high command.{{Sfn | Jonassohn | 1999 | pp = 209–10}} Modern historians have estimated the number of killed Bulgarian population is between 30,000 and 100,000. The Turkish military carried on horribly unjust acts upon the vast Bulgarian populations.<ref>{{Citation | title = The Establishment of the Balkan National States, 1804–1920 | first1 = Charles | last1 = Jelavich | first2 = Barbara | last2 = Jelavich | year = 1977 | publisher = University of Washington Press | location = Seattle, Washington, USA | url = https://books.google.com/books?id=LBYriPYyfUoC&pg=PA139&hl=en#v=onepage&q&f=false | page = 139}}.</ref>
+
+<gallery>
+File:Konstantin Makovsky - The Bulgarian martyresses.jpg|[[Konstantin Makovsky]], ''The Bulgarian Martyresses'', a painting depicting the atrocities of [[bashibazouk]]s in [[Macedonia (region)|Macedonia]].
+File:Два ястреба (Башибузуки).jpg|[[Bashibazouk]]s held captive by the Bulgarian and Russian army.
+File:Vsemirnaya Illyustratsia Russo-Turkish War (1877–1878) 05.jpg|Bashi-Bazouks, returning with the spoils from the Romanian shore of the [[Danube]].
+</gallery>
+
+===International reaction to atrocities in Bulgaria===
+Word of the bashi-bazouks' atrocities filtered to the outside world by way of American-run Robert College located in [[Constantinople]]. The majority of the students were Bulgarian, and many received news of the events from their families back home. Soon the Western diplomatic community in Constantinople was abuzz with rumours, which eventually found their way into newspapers in the West. While in Constantinople in 1879, Protestant missionary [[George Warren Wood]] reported Turkish authorities in [[Amasya|Amasia]] brutally persecuting Christian Armenian refugees from [[Soukoum Kaleh]]. He was able to coordinate with British diplomat [[Edward Malet]] to bring the matter to the attention of the [[Sublime Porte]], and then to the British foreign secretary [[Robert Gascoyne-Cecil, 3rd Marquess of Salisbury|Robert Gascoyne-Cecil]] (the [[Marquess of Salisbury]]).<ref>{{cite book|title=Parliamentary Papers, House of Commons and Command, Volume 80|date=1880|publisher=Great Britain. Parliament. House of Commons|location=Constantinople|pages=70–72|url=https://books.google.com/books?id=X1UTAAAAYAAJ&pg=RA3-PA70#v=onepage&q=%22Reverend%20George%20W.%20Wood%22%20%20|accessdate=3 January 2017}}</ref> In Britain, where [[Benjamin Disraeli|Disraeli]]'s government was committed to supporting the Ottomans in the ongoing Balkan crisis, the Liberal opposition newspaper ''Daily News'' hired American journalist [[Januarius MacGahan|Januarius A. MacGahan]] to report on the massacre stories firsthand.
+
+MacGahan toured the stricken regions of the Bulgarian uprising, and his report, splashed across the ''Daily News'''s front pages, galvanized British public opinion against Disraeli's pro-Ottoman policy.<ref>{{cite book |last=MacGahan |first=Januarius A. |date=1876 |title=Turkish Atrocities in Bulgaria, Letters of the Special Commissioner of the 'Daily News,' J.A. MacGahan, Esq., with An Introduction & Mr. Schuyler's Preliminary Report |publisher=Bradbury Agnew and Co. |location=London |url=https://archive.org/details/MacGahanTurkishAtrocitiesInBulgaria |accessdate=26 January 2016}}</ref> In September, opposition leader [[William Ewart Gladstone|William Gladstone]] published his ''Bulgarian Horrors and the Question of the East''{{Sfn | Gladstone | 1876}} calling upon Britain to withdraw its support for Turkey and proposing that Europe demand independence for Bulgaria and Bosnia and Herzegovina.{{Sfn | Gladstone | 1876 | p = 64}} As the details became known across Europe, many dignitaries, including [[Charles Darwin]], [[Oscar Wilde]], [[Victor Hugo]] and [[Giuseppe Garibaldi]], publicly condemned the Ottoman abuses in Bulgaria.<ref>{{Citation | url = http://www.bulgaria-embassy.org/History_of_Bulgaria.htm#THE%20BULGARIAN%20REVIVAL | title = History of Bulgaria | contribution = The liberation of Bulgaria | publisher = Bulgarian embassy | place = US | deadurl = yes | archiveurl = https://web.archive.org/web/20101011003946/http://www.bulgaria-embassy.org/History_of_Bulgaria.htm#THE%20BULGARIAN%20REVIVAL | archivedate = 2010-10-11 | df =  }}.</ref>
+
+The strongest reaction came from Russia. Widespread sympathy for the Bulgarian cause led to a nationwide surge in patriotism on a scale comparable with the one during the [[French invasion of Russia|Patriotic War of 1812]]. From autumn 1875, the movement to support the Bulgarian uprising involved all classes of Russian society. This was accompanied by sharp public discussions about Russian goals in this conflict: [[Slavophile]]s, including [[Fyodor Dostoevsky|Dostoevsky]], saw in the impending war the chance to unite all Orthodox nations under Russia's helm, thus fulfilling what they believed was the historic mission of Russia, while their opponents, [[westernizer]]s, inspired by [[Ivan Turgenev|Turgenev]], denied the importance of religion and believed that Russian goals should not be defense of Orthodoxy but liberation of Bulgaria.<ref>{{Citation|url=http://www.libfl.ru/win/nbc/books/bolgaria.html |first=ВМ |last=Хевролина |script-title=ru:Россия и Болгария: "Вопрос Славянский — Русский Вопрос" |publisher=Lib FL |place=[[Russia|RU]] |language=Russian |deadurl=yes |archiveurl=https://web.archive.org/web/20071028062618/http://www.libfl.ru/win/nbc/books/bolgaria.html |archivedate=October 28, 2007 }}.</ref>
+
+===Serbo-Turkish War and diplomatic manoeuvering===
+{{Main|Serbo-Turkish War (1876–78)|Constantinople Conference|Expulsion of the Albanians 1877–1878}}
+[[File:Serio-comic war map for 1877.jpg|thumb|upright= 1.25|Serio-comic war map for 1877. Anti-Russian cartoon depicting Russia as a vicious octopus.]]
+[[File:Punch - The Dogs of War.png|Russia preparing to release the Balkan dogs of war, while Britain warns him to take care. ''[[Punch (magazine)|Punch]]'' cartoon from June 17, 1876|thumb|right]]
+On June 30, 1876, Serbia, followed by [[Montenegro]], declared war on the Ottoman Empire. In July and August, the ill-prepared and poorly equipped Serbian army helped by Russian volunteers failed to achieve offensive objectives but did manage to repulse the Ottoman offensive into Serbia. Meanwhile, Russia's [[Alexander II of Russia|Alexander II]] and [[Alexander Gorchakov|Prince Gorchakov]] met [[Austria-Hungary]]'s [[Franz Joseph I of Austria|Franz Joseph I]] and [[Julius Andrassy|Count Andrássy]] in the [[Zákupy|Reichstadt]] castle in [[Bohemia]]. No written agreement was made, but during the discussions, Russia agreed to support Austrian occupation of Bosnia and Herzegovina, and [[Austria-Hungary]], in exchange, agreed to support the return of Southern [[Bessarabia]]—lost by Russia during the [[Crimean War]]—and Russian annexation of the port of [[Batumi|Batum]] on the east coast of the [[Black Sea]]. Bulgaria was to become autonomous (independent, according to the Russian records).<ref>{{Citation | url = http://www.diphis.ru/index.php?option=content&task=view&id=100#3 | title = History of world diplomacy 15th century BC – 1940 AD | last = Potemkin | first = VP | place = [[Russia|RU]] | publisher = Diphis}}.</ref>
+
+As the fighting in Bosnia and Herzegovina continued, Serbia suffered a string of setbacks and asked the European powers to mediate an end to the war. A joint ultimatum by the European powers forced the Porte to give Serbia a one-month truce and start peace negotiations. Turkish peace conditions however were refused by European powers as too harsh. In early October, after the truce expired, the Turkish army resumed its offensive and the Serbian position quickly became desperate. On October 31, Russia issued an ultimatum requiring the Ottoman Empire to stop the hostilities and sign a new truce with Serbia within 48 hours. This was supported by the partial mobilization of the Russian army (up to 20 divisions). The Sultan accepted the conditions of the ultimatum.
+
+To resolve the crisis, on December 11, 1876, the [[Constantinople Conference]] of the Great Powers was opened in Constantinople (to which the Turks were not invited). A compromise solution was negotiated, granting autonomy to [[Bulgaria]], Bosnia and Herzegovina under the joint control of European powers. The Ottomans, however, refused to sacrifice their independence by allowing international representatives to oversee the institution of reforms and sought to discredit the conference by announcing on December 23, the day the conference was closed, that a [[First Constitutional Era (Ottoman Empire)|constitution]] was adopted that declared equal rights for religious minorities within the Empire. The Ottomans attempted to use this manoeuver to get their objections and amendments to the agreement heard. When they were rejected by the Great Powers, the Ottoman Empire announced its decision to disregard the results of the conference.
+
+On January 15, 1877, Russia and Austria-Hungary signed a written agreement confirming the results of an earlier [[Reichstadt Agreement]] in July 1876. This assured Russia of the benevolent neutrality of Austria-Hungary in the impending war. These terms meant that in case of war Russia would do the fighting and Austria would derive most of the advantage. Russia therefore made a final effort for a peaceful settlement. After reaching an agreement with its main Balkan rival and with anti-Ottoman sympathies running high throughout Europe due to the Bulgarian atrocities and the rejection of the Constantinople agreements, Russia finally felt free to declare war.
+
+==Course of the war==
+{{See also|Romanian War of Independence}}
+
+===Opening manoeuvres===
+[[File:Нижегородские драгуны, преследующие турок по дороге к Карсу во время Аладжинского сражения 3 октября 1877 года.jpg|thumb|Dragoons of Nizhny Novgorod pursuing the Turks near [[Kars]], 1877, painting by [[Aleksey Kivshenko]]]]
+
+Russia declared war on the Ottomans on 24 April 1877 and its troops entered Romania through the newly built [[Eiffel Bridge, Ungheni|Eiffel Bridge]] near Ungheni, on the Prut river. On April 12, 1877, Romania gave permission to the Russian troops to pass through its territory to attack the Turks, resulting in Turkish bombardments of Romanian towns on the Danube. On May 10, 1877, the [[Principality of Romania]], which was under formal Turkish rule, declared its independence.<ref>{{Citation | url = http://www.cs.kent.edu/~amarcus/Mihai/english/cronologieen.html | title = Chronology of events from 1856 to 1997 period relating to the Romanian monarchy | publisher = Kent State University | place = Ohio | deadurl = yes | archiveurl = https://web.archive.org/web/20071230042922/http://www.cs.kent.edu/~amarcus/Mihai/english/cronologieen.html | archivedate = 2007-12-30 | df =  }}</ref>
+
+At the beginning of the war, the outcome was far from obvious. The Russians could send a larger army into the Balkans: about 300,000 troops were within reach. The Ottomans had about 200,000 troops on the Balkan peninsula, of which about 100,000 were assigned to fortified garrisons, leaving about 100,000 for the army of operation. The Ottomans had the advantage of being fortified, complete command of the Black Sea, and patrol boats along the [[Danube]] river.<ref>{{Citation | url = https://archive.org/details/warineastillustr00scheiala | title = The War in the East: An illustrated history of the Conflict between Russia and Turkey with a Review of the Eastern Question | year = 1878 | author-link = Alexander Jacob Schem | last = Schem | first = Alexander Jacob}}.</ref> They also possessed superior arms, including new British and American-made rifles and German-made artillery.
+
+[[File:Pereprava cherez Dunaj.jpg|thumb|left|Russian crossing of the Danube, June 1877, painting by [[Nikolai Dmitriev-Orenburgsky]], 1883]]
+
+In the event, however, the Ottomans usually resorted to passive defense, leaving the strategic initiative to the Russians, who, after making some mistakes, found a winning strategy for the war. The Ottoman military command in Constantinople made poor assumptions of Russian intentions. They decided that Russians would be too lazy to march along the Danube and cross it away from the delta, and would prefer the short way along the [[Black Sea]] coast. This would be ignoring the fact that the coast had the strongest, best supplied and garrisoned Turkish fortresses. There was only one well manned fortress along the inner part of the river Danube, [[Vidin]]. It was garrisoned only because the troops, led by Osman Pasha, had just taken part in defeating the Serbs in their recent war against the Ottoman Empire.
+
+The Russian campaign was better planned, but it relied heavily on Turkish passivity. A crucial Russian mistake was sending too few troops initially; an expeditionary force of about 185,000 crossed the Danube in June, slightly less than the combined Turkish forces in the Balkans (about 200,000). After setbacks in July (at [[Pleven]] and [[Stara Zagora]]), the Russian military command realized it did not have the reserves to keep the offensive going and switched to a defensive posture. The Russians did not even have enough forces to blockade Pleven properly until late August, which effectively delayed the whole campaign for about two months.
+
+===Balkan theatre===
+[[File:Russo-Turkish War (1877–1878).png|thumb|Map of the Balkan Theater]]
+At the start of the war, Russia and Romania destroyed all vessels along the Danube and [[Naval mine|mined]] the river, thus ensuring that Russian forces could cross the Danube at any point without resistance from the [[Ottoman Navy|Ottoman navy]]. The Ottoman command did not appreciate the significance of the Russians' actions. In June, a small Russian unit crossed the Danube close to the delta, at [[Galați]], and marched towards Ruschuk (today [[Rousse|Ruse]]). This made the Ottomans even more confident that the big Russian force would come right through the middle of the Ottoman stronghold.
+
+[[File:Kärtchen zur Schlacht bei Plewna (11. & 12.09.1877).jpg|thumb|left|Russian, Romanian and Ottoman troop movements at [[Pleven|Plevna]]]]
+
+On 25–26 May, a Romanian torpedo boat with a mixed Romanian-Russian crew [[Action off Măcin|attacked and sank]] an Ottoman monitor on the Danube.<ref>[http://www.navypedia.org/ships/turkey/tu_of_hizber.htm Navypedia.org: Ottoman navy: Hizber river monitors]</ref> Under the direct command of Major-General [[Mikhail Ivanovich Dragomirov]], on the night of 27/28 June 1877 ([[New Style|NS]]) the Russians constructed a pontoon bridge across the Danube at [[Svishtov]]. After a short battle in which the Russians suffered 812 killed and wounded,<ref>{{Citation | title = Bayonets before Bullets: The Imperial Russian Army, 1861–1914 | first = Bruce | last = Menning | publisher = Indiana University Press | year = 2000 | page = 57}}.</ref> the Russian secured the opposing bank and drove off the Ottoman infantry brigade defending Svishtov. At this point the Russian force was divided into three parts: the Eastern Detachment under the command of [[Tsarevich]] Alexander Alexandrovich, the future Tsar [[Alexander III of Russia]], assigned to capture the fortress of Ruschuk and cover the army's eastern flank; the Western Detachment, to capture the fortress of [[Nikopol, Bulgaria]] and cover the army's western flank; and the Advance Detachment under Count [[Joseph Vladimirovich Gourko]], which was assigned to quickly move via [[Veliko Tarnovo]] and penetrate the [[Balkan Mountains]], the most significant barrier between the Danube and Constantinople.
+
+[[File:Boj u Ivanovo-Chiflik.jpg|thumb|Fighting near Ivanovo-Chiflik]]
+
+Responding to the Russian crossing of the Danube, the Ottoman high command in Constantinople ordered [[Osman Nuri Paşa]] to advance east from [[Vidin]] occupy the fortress of [[Nikopol, Bulgaria|Nikopol]], just west of the Russian crossing. On his way to Nikopol, Osman Pasha learned that the Russians had already captured the fortress and so moved to the crossroads town of Plevna (now known as [[Pleven]]), which he occupied with a force of approximately 15,000 on 19 July (NS).{{Sfn | von Herbert | 1895 | p = 131}} The Russians, approximately 9,000 under the command of General Schilder-Schuldner, reached Plevna early in the morning. Thus began the [[Siege of Plevna]].
+
+Osman Pasha organized a defense and repelled two Russian attacks with colossal casualties on the Russian side. At that point, the sides were almost equal in numbers and the Russian army was very discouraged.<ref>{{Citation | title = Reminiscences of the King of Roumania | publisher = Harper & Brothers | year = 1899 | pages = 274–75 | url = https://archive.org/stream/reminiscencesofk00kremiala#page/274/mode/2up}}.</ref> Most analysts agree that a counter-attack would have allowed the Ottomans to gain control of, and destroy, the Russians' bridge.{{who|date=August 2009}} However, Osman Pasha had orders to stay fortified in Plevna, and so he did not leave that fortress.
+
+[[File:GhaziOsmanPasha.jpg|thumb|left|[[Osman Nuri Pasha|Gazi Osman Pasha]]]]
+[[File:Nikopol dmitriev.jpg|thumb|left|The Ottoman capitulation at [[Nikopol, Bulgaria|Niğbolu (Nicopolis, modern Nikopol)]] in 1877 was significant, as it was the site of an [[Battle of Nicopolis|important Ottoman victory in 1396]] which marked the expansion of the Ottoman Empire into the Balkans.]]
+
+Russia had no more troops to throw against Plevna, so the Russians besieged it, and subsequently asked<ref>{{Citation | title = Reminiscences of the King of Roumania | publisher = Harper & Brothers | year = 1899 | page = 275 | url = https://archive.org/stream/reminiscencesofk00kremiala#page/274/mode/2up}}.</ref> the Romanians to provide extra troops. On August 9, Suleiman Pasha made an attempt to help Osman Pasha with 30,000 troops, but he was stopped by Bulgarians at the [[Battle of Shipka Pass]]. After three days of fighting, the volunteers were relieved by a Russian force led by General Radezky, and the Turkish forces withdrew. Soon afterwards, Romanian forces crossed the Danube and joined the siege. On August 16, at Gorni-Studen, the armies (West Army group) around Plevna were placed under the command of the Romanian Prince [[Carol I]], aided by the Russian general Pavel Dmitrievich Zotov and the Romanian general [[Alexandru Cernat]].
+
+The Turks maintained several fortresses around Pleven which the Russian and Romanian forces gradually reduced.<ref>{{Citation | last = Furneaux | first = Rupert | title = The Siege of Pleven | year = 1958}}.</ref>{{Sfn|von Herbert|1895}}{{Rp | needed = yes|date=March 2013}} The Romanian 4th Division led by General [[Gheorghe Manu]] took the Grivitsa redoubt after four bloody assaults and managed to keep it until the very end of the siege. The [[siege of Plevna]] (July–December 1877) turned to victory only after Russian and Romanian forces cut off all supply routes to the fortified Ottomans. With supplies running low, Osman Pasha made an attempt to break the Russian siege in the direction of Opanets. On December 9, in the middle of the night the Ottomans threw bridges over the Vit River and crossed it, attacked on a {{convert |2|mi|km|adj =on}} front and broke through the first line of Russian trenches. Here they fought hand to hand and bayonet to bayonet, with little advantage to either side. Outnumbering the Ottomans almost 5 to 1, the Russians drove the Ottomans back across the Vit. Osman Pasha was wounded in the leg by a stray bullet, which killed his horse beneath him. Making a brief stand, the Ottomans eventually found themselves driven back into the city, losing 5,000 men to the Russians' 2,000. The next day, Osman surrendered the city, the garrison, and his sword to the Romanian colonel, [[Mihail Cerchez]]. He was treated honorably, but his troops perished in the snows by the thousand as they straggled off into captivity. The more seriously wounded were left behind in their camp hospitals, only to be murdered by the Bulgarians.<ref>{{Citation | author = Lord Kinross | title = The Ottoman Centuries | year = 1977 | page = 522 | publisher = Morrow Quill}}.</ref>{{dubious |date=January 2011}}
+
+[[File:Zahvat grivickogo reduta.jpg|thumb|Taking of the Grivitsa redoubt by the Russians – a few hours later the redoubt was recaptured by the Ottomans and fell to the Romanians on 30 August 1877 in what became known as the "Third Battle of Grivitsa".]]
+
+At this point Serbia, having finally secured monetary aid from Russia, declared war on the Ottoman Empire again. This time there were far fewer Russian officers in the Serbian army but this was more than offset by the experience gained from the 1876–77 war. Under nominal command of [[Milan I of Serbia|prince Milan Obrenović]] (effective command was in hands of general [[Kosta Protić]], the army chief of staff), the [[Serbian Army]] went on offensive in what is now eastern south Serbia. A planned offensive into the Ottoman [[Sanjak of Novi Pazar]] was called off due to strong diplomatic pressure from [[Austria-Hungary]], which wanted to prevent Serbia and Montenegro from coming into contact, and which had designs to spread Austria-Hungary's influence through the area. The Ottomans, outnumbered unlike two years before, mostly confined themselves to passive defence of fortified positions. By the end of hostilities the Serbs had captured Ak-Palanka (today [[Bela Palanka]]), [[Pirot]], [[Niš]] and [[Vranje]].
+
+[[File:Battle at river Skit 1877.jpg|thumb|left|Battle at bridge Skit, November 1877]]
+
+Russians under [[Field Marshal]] [[Joseph Vladimirovich Gourko]] succeeded in capturing the passes at the [[Stara Planina]] mountain, which were crucial for maneuvering. Next, both sides fought a series of [[Battle of Shipka Pass|battles for Shipka Pass]]. Gourko made several attacks on the [[Shipka Pass|Pass]] and eventually secured it. Ottoman troops spent much effort to recapture this important route, to use it to reinforce Osman Pasha in Pleven, but failed. Eventually Gourko led a final offensive that crushed the Ottomans around Shipka Pass. The Ottoman offensive against Shipka Pass is considered one of the major mistakes of the war, as other passes were virtually unguarded. At this time a huge number of Ottoman troops stayed fortified along the Black Sea coast and engaged in very few operations.
+
+A Russian army crossed the Stara Planina by a high snowy pass in winter, guided and helped by local Bulgarians, not expected by the Ottoman army, and defeated the Turks at the [[Battle of Tashkessen]] and [[Battle of Sofia|took Sofia]]. The way was now open for a quick advance through [[Plovdiv]] and [[Edirne]] to [[Constantinople]].
+
+Besides the [[Romanian Army]] (which mobilized 130,000 men, losing 10,000 of them to this war), a strong [[Grand Duchy of Finland|Finnish]] contingent and more than 12,000 volunteer Bulgarian troops (''Opalchenie'') from the local [[Bulgaria]]n population as well as many ''[[hajduk]]'' detachments fought in the war on the side of the Russians. To express his gratitude to the Finnish battalion, the Tsar elevated the battalion on their return home to the name ''[[Old Guards (Russia)|Old Guard]] Battalion''.
+
+===Caucasian theatre===
+[[File:DefenceOfBayazet.jpg|thumb|Russian troops repulsing a Turkish assault against the fortress of [[Doğubeyazıt|Beyazid]] on June 8, 1877, oil painting by Lev Feliksovich Lagorio, 1891]]
+
+The Russian Caucasus Corps was stationed in [[History of Georgia (country)|Georgia]] and [[Russian Armenia|Armenia]], composed of approximately 50,000 men and 202 guns under the overall command of [[Grand Duke Michael Nikolaevich of Russia|Grand Duke Michael Nikolaevich]], [[Caucasus Viceroyalty (1844–1881)|Governor General of the Caucasus]].<ref>Menning. ''Bayonets before Bullets'', p. 78.</ref> The Russian force stood opposed by an [[Ottoman Army]] of 100,000 men led by General [[Ahmed Muhtar Pasha]]. While the Russian army was better prepared for the fighting in the region, it lagged behind technologically in certain areas such as [[heavy artillery]] and was outgunned, for example, by the superior long-range [[Krupp]] artillery that Germany had supplied to the Ottomans.{{Sfn|Allen|Muratoff|1953|pp=113–114}}
+
+The Caucasus Corps was led by a quartet of [[Armenian people|Armenian]] commanders: Generals [[Mikhail Loris-Melikov]], [[Arshak Ter-Gukasov]] (Ter-Ghukasov/Ter-Ghukasyan), [[Ivan Davidovich Lazarev|Ivan Lazarev]] and [[Beybut Shelkovnikov]].{{Sfn|Allen|Muratoff|1953|p=546}} Forces under [[Lieutenant-General]] Ter-Gukasov, stationed near [[Yerevan]], commenced the first assault into Ottoman territory by capturing the town of [[Doğubeyazıt|Bayazid]] on April 27, 1877.<ref name="SovArm">{{Citation | language = Armenian | contribution = Ռուս-Թուրքական Պատերազմ, 1877–1878 |trans-title=The Russo-Turkish War, 1877–1878 | title = [[Armenian Soviet Encyclopedia]] | volume = 10 | place = Yerevan | publisher = Armenian Academy of Sciences | year = 1984 | pages = 93–94}}.</ref> Capitalizing on Ter-Gukasov's victory there, Russian forces advanced, taking the region of [[Ardahan]] on May 17; Russian units also besieged the city of [[Kars]] in the final week of May, although Ottoman reinforcements lifted the siege and drove them back. Bolstered by reinforcements, in November 1877 General Lazarev launched a new attack on Kars, suppressing the southern forts leading to the city and capturing Kars itself on November 18.<ref>{{cite book| last1 = Walker | first1= Christopher J. | chapter = Kars in the Russo-Turkish Wars of the Nineteenth Century | title = Armenian Kars and Ani | editor1-first = Richard G | editor1-last = Hovannisian | location = Costa Mesa, California, USA | publisher = Mazda Publishers | date = 2011 | pages = 217–220}}</ref> On February 19, 1878 the strategic fortress town of [[Erzurum]] was taken by the Russians after a lengthy siege. Although they relinquished control of Erzerum to the Ottomans at the end the war, the Russians acquired the regions of [[Batumi|Batum]], [[Ardahan]], [[Kars]], [[Oltu|Olti]], and [[Sarıkamış|Sarikamish]] and reconstituted them into the [[Kars Oblast]].<ref>{{cite book|last1=Melkonyan|first1=Ashot|editor1-last=Hovannisian|editor1-first=Richard G.|title=Armenian Kars and Ani|date=2011|publisher=Mazda Publishers|location=Costa Mesa, California, USA|pages=223–244|chapter=The Kars ''Oblast'', 1878–1918}}</ref>
+
+== Civilian government in Bulgaria during the war ==
+{{Main|Provisional Russian Administration in Bulgaria}}
+[[File:Plevna monument.jpg|300px|thumb|[[Plevna Chapel]] near the walls of [[Kitay-gorod]]]]
+After Bulgarian territories were liberated by the [[Imperial Russian Army]] during the war, they were governed initially by a [[Provisional Russian Administration in Bulgaria|provisional Russian administration]], which was established in April 1877. The [[Treaty of Berlin (1878)]] provided for the termination of this provisional Russian administration in May 1879, when the [[Principality of Bulgaria]] and [[Eastern Rumelia]] were established.<ref name="БДИ">{{cite book | year = 1987 | title = Българските държавни институции 1879–1986 | trans-title= Bulgarian State Institutions 1879–1986 | publisher = ДИ "Д-р Петър Берон" | location = София (Sofia, Bulgaria)| pages = 54–55}}</ref> The main objectives of the temporary Russian administration were to secure peace and order and to prepare for a revival of the Bulgarian state.
+
+==Aftermath==
+===Intervention by the Great Powers===
+Under pressure from the British, Russia accepted the truce offered by the Ottoman Empire on January 31, 1878, but continued to move towards [[Istanbul|Constantinople]].
+
+The British sent a fleet of battleships to intimidate Russia from entering the city, and Russian forces stopped at [[San Stefano]]. Eventually Russia entered into a settlement under the [[Treaty of San Stefano]] on March 3, by which the Ottoman Empire would recognize the independence of [[Principality of Romania|Romania]], Serbia, and Montenegro, and the autonomy of [[Principality of Bulgaria|Bulgaria]].
+
+Alarmed by the extension of Russian power into the Balkans, the [[Great Powers]] later forced modifications of the treaty in the [[Congress of Berlin]]. The main change here was that Bulgaria would be split, according to earlier agreements among the Great Powers that precluded the creation of a large new Slavic state: the northern and eastern parts to become principalities as before (Bulgaria and [[Eastern Rumelia]]), though with different governors; and the Macedonian region, originally part of Bulgaria under San Stefano, would return to direct Ottoman administration.<ref>L.S. Stavrianos, ''The Balkans Since 1453 ''  (1958) pp 408-12.</ref>
+
+===Effects on Bulgaria's Muslim and Christian population===
+[[File:Turkish refugees sumla1877 wiki.jpg|thumb|250px|Turkish refugees fleeing from [[Tarnovo]] towards [[Shumen]]]]
+[[File:Klane na Stara Zagora.JPG|thumb|250px|Bones of massacred Bulgarians at [[Stara Zagora]]]]
+[[File:Carol Popp de Szathmáry - Cerchez călare.jpg|thumb|250px|Circassian horseman, during the Russo-Turkish War]]
+Muslim civilian casualties during the war are often estimated in the tens of thousands.<ref>{{Citation | title = Genocide in the Age of the Nation State: The rise of the West and the coming of genocide | first = Mark | last = Levene | year = 2005 | url = https://books.google.com/books?id=3PsLXeDflfMC&pg=PA225&dq=muslims++1878+bulgaria+%22tens+of+thousands%22&hl=en&ei=tn89TdzJCY72sgaRttHzBg&sa=X&oi=book_result&ct=result&resnum=7&ved=0CD8Q6AEwBg#v=onepage&q=muslims%20%201878%20bulgaria%20%22tens%20of%20thousands%22&f=false | page = 225}}.</ref> The perpetrators of those massacres are also disputed, with American historian [[Justin McCarthy (American historian)|Justin McCarthy]], claiming that they were carried out by Russian soldiers, Cossacks as well as Bulgarian volunteers and villagers, though there were few civilian casualties in battle.<ref name="McCarthy, J. 2001, p. 48">{{Citation | last = McCarthy | first = J | title = The Ottoman Peoples and the end of Empire | year = 2001 | page = 48 | publisher = Oxford University Press}}.</ref> while [[James J. Reid]] claims that [[Circassians]] were significantly responsible for the refugee flow, that there were civilian casualties from battle and even that the Ottoman army was responsible for casualties among the Muslim population.{{Sfn | Reid | 2000 | pp = 42–43}} According to [[John Joseph (academic)|John Joseph]] the Russian troops made frequent massacres of Muslim peasants to prevent them from disrupting their supply and troop movements. During the [[Harmanli Massacre|Battle of Harmanli]] accompanying this retaliation on Muslim non-combatants, it was reported that a huge group of Muslim townspeople were attacked by the Russian army, which as a result thousands died and their goods confiscated.<ref>{{Citation | title = The Congress of Berlin and after | first = William Norton | last = Medlicott | page = 157}}</ref><ref>{{Citation | title = Muslim-Christian Relations and Inter-Christian Rivalries in the Middle East | first = John | last = Joseph | page = 84 | year = 1983}}.</ref> The correspondent of the ''Daily News'' describes as an eyewitness the burning of four or five Turkish villages by the Russian troops in response to the Turks firing at the Russians from the villages, instead of behind rocks or trees{{Sfn | Reid | 2000 | p = 324}}, which must have appeared to the Russian soldiers as guerrilla attempts by the local Muslim populace upon the Russian contingencies operating against the Ottoman forces embedded in the area.
+
+The number of Muslim refugees is estimated by [[RJ Crampton]] to be 130,000.<ref>{{Citation | last = Crampton | first = RJ | title = A Concise History of Bulgaria | year = 1997 | publisher = Cambridge University Press | ISBN = 0-521-56719-X | page = 426}}.</ref> [[Richard C. Frucht]] estimates that only half (700,000) of the prewar Muslim population remained after the war, 216,000 had died and the rest emigrated.<ref>{{Citation | title = Eastern Europe | first = Richard C | last = Frucht | page = 641 | year = 2005}}.</ref> [[Douglas Arthur Howard]] estimates that half the 1.5 million Muslims, for the most part Turks, in prewar Bulgaria had disappeared by 1879. 200,000 had died, the rest became permanently refugees in Ottoman territories.<ref>{{Citation | title = The history of Turkey | first = Douglas Arthur | last = Howard | page = 67 | year = 2001}}</ref> However, it should be noted that according to one estimate, the total population of Bulgaria in its postwar borders was about 2.8 million in 1871,<ref>{{Citation | url = http://www.populstat.info/Europe/bulgaric.htm | publisher = Popul stat | title = Europe | contribution = Bulgaric}}.</ref> while according to official censuses, the total population was 2.823 million in 1880/81.<ref>{{Citation | title = Bulgaria | first = RJ | last = Crampton | year = 2007 | page = 424}}.</ref> And as such would make the aforementioned claim of 216,000 - 2.8 millions of persons dead due to Russian engagement and the subsequent fleeing of the majority of the Muslim population totally dubious.
+
+During the conflict a number of Muslim buildings and cultural centres were destroyed. A large library of old Turkish books was destroyed when a mosque in Turnovo was burned in 1877.{{Sfn | Crampton | 2006 | p = 111}} Most mosques in Sofia perished, seven of them destroyed in one night in December 1878 when a thunderstorm masked the noise of the explosions arranged by Russian military engineers."{{Sfn | Crampton | 2006 | p = 114}}
+
+The Christian population, especially in the initial stages of the war, that found itself in the path of the Ottoman armies also suffered greatly.
+
+The most notable massacre of Bulgarian civilians took part after the July [[Battle of Stara Zagora|battle]] of [[Stara Zagora]] when Gurko's forces had to retreat back to the Shipka pass. In the aftermath of the battle [[Suleiman Pasha (Ottoman general)|Suleiman Pasha]]'s forces burned down and plundered the town of Stara Zagora which by that time was one of the largest towns in the Bulgarian lands. The number of massacred Christian civilians during the battle is estimated at 15,000. Suleiman Pasha's forces also established in the whole valley of the [[Maritsa]] river a system of terror taking form in the hanging at the street corners of every Bulgarian who had in any way assisted the Russians, but even villages that had not assisted the Russians were destroyed and their inhabitants massacred.{{Sfn | Argyll | 1879 | p = 49}} As a result, as many as 100,000 civilian Bulgarians fled north to the Russian occupied territories.<ref name="Report on the Russian Army">{{cite book | first =Francis Vinton | last = Greene | title = Report on the Russian Army and its Campaigns in Turkey in 1877–1878 | publisher = D Appleton & Co | year = 1879 | page = 204}}</ref> Later on in the campaign the Ottoman forces [[Scorched earth|planned to burn]] the town of [[Sofia]] after Gurko had managed to overcome their resistance in the passes of Western part of the [[Balkan Mountains]]. Only the refusal of the Italian Consul [[Vito Positano]], the French Vice Consul Léandre François René le Gay and the Austro–Hungarian Vice Consul to leave Sofia prevented that from happening. After the Ottoman retreat, Positano even organized armed detachments to protect the population from [[Outlaw|marauders]] (regular Ottoman Army [[deserter]]s, [[bashi-bazouk]]s and [[Circassians]]).<ref name="sega">{{cite news|url=http://www.segabg.com/online/article.asp?issueid=315&sectionid=4&id=00004|title=Позитано. "Души в окови"|last=Ivanov|first=Dmitri|date=2005-11-08|publisher=Sega|language=Bulgarian|accessdate=2009-04-30|archive-url=https://web.archive.org/web/20110719054301/http://www.segabg.com/online/article.asp?issueid=315&sectionid=4&id=00004|archive-date=2011-07-19|dead-url=yes|df=}}</ref>
+
+Bulgarian historians claim that 30,000 civilian Bulgarians were killed during the war, two thirds of which occurred in the Stara Zagora area.<ref>{{Citation | title = Russian-Turkish war 1877–1878 | first = Bozhidar | last = Dimitrov | year = 2002 | page = 75 | language = Bulgarian}}.</ref>
+
+===Effects on Bulgaria's Jewish population===
+Many Jewish communities in their entirety fled with the retreating Turks as their protectors. The ''Bulletins de l'[[Alliance Israélite Universelle]]'' reported that thousands of [[Bulgarian Jews]] found refuge at the Ottoman capital of [[Constantinople]].<ref>Tamir, V., ''Bulgaria and Her Jews: A dubious symbiosis'', 1979, p. 94–95, Yeshiva University Press</ref>
+
+===Internationalization of the Armenian Question===
+[[File:Emigration of Armenians into Georgia during the Russo-Turkish war of 1878-9 (A).jpg|thumb|Emigration of Armenians into Georgia during the Russo-Turkish war]]
+The conclusion of the Russo-Turkish war also led to the internationalization of the [[Armenian Question]]. Many [[Armenians]] in the eastern provinces ([[Turkish Armenia]]) of the Ottoman Empire greeted the advancing Russians as liberators. Violence and instability directed at Armenians during the war by Kurd and Circassian bands had left many Armenians looking toward the invading Russians as the ultimate guarantors of their security. In January 1878, [[Armenian Patriarch of Constantinople]] [[Nerses II Varzhapetian]] approached the Russian leadership with the view of receiving assurances that the Russians would introduce provisions in the prospective peace treaty for self-administration in the Armenian provinces. Though not as explicit, Article 16 of the Treaty of San Stefano read:
+{{quotation |As the evacuation of the Russian troops of the territory they occupy in Armenia, and which is to be restored to Turkey, might give rise to conflicts and complications detrimental to the maintenance of good relations between the two countries, the Sublime Porte engaged to carry into effect, without further delay, the improvements and reforms demanded by local requirements in the provinces inhabited by Armenians and to guarantee their security from Kurds and Circassians.<ref>{{Citation | last = Hertslet | first = Edward | authorlink = Edward Hertslet | title = The Map of Europe by Treaty | volume = 4 | place = London | publisher = Butterworths | year = 1891 | page = 2686}}.</ref>}}
+
+Great Britain, however, took objection to Russia holding on to so much Ottoman territory and forced it to enter into new negotiations by convening the Congress of Berlin in June 1878. An Armenian delegation led by prelate [[Mkrtich Khrimian]] traveled to Berlin to present the case of the Armenians but, much to its chagrin, was left out of the negotiations. Article 16 was modified and watered down, and all mention of the Russian forces remaining in the provinces was removed. In the final text of the Treaty of Berlin, it was transformed into Article 61, which read:
+{{quotation |The Sublime Porte undertakes to carry out, without further delay, the improvements and reforms demanded by local requirements in the provinces inhabited by Armenians, and to guarantee their security against the Circassians and Kurds. It will periodically make known the steps taken to this effect to the powers, who will superintend their application.<ref>{{Citation | last = Hurewitz | first = Jacob C | title = Diplomacy in the Near and Middle East: A Documentary Record 1535–1956 | volume = I | place = Princeton, NJ | publisher = Van Nostrand | year = 1956 | page = 190}}.</ref>}}
+
+As it turned out, the reforms were not forthcoming. Khrimian returned to Constantinople and delivered a famous speech in which he likened the peace conference to a {{"'}}big cauldron of Liberty Stew' into which the big nations dipped their 'iron ladles' for real results, while the Armenian delegation had only a 'Paper Ladle'. 'Ah dear Armenian people,' Khrimian said, 'could I have dipped my Paper Ladle in the cauldron it would sog and remain there! Where guns talk and sabers shine, what significance do appeals and petitions have?{{'"}}<ref>[[Peter Balakian|Balkian, Peter]]. ''The Burning Tigris: The Armenian Genocide and America's Response''. New York: HarperCollins, 2003, p. 44.</ref> Given the absence of tangible improvements in the plight of the Armenian community, a number of Armenian intellectuals living in Europe and Russia in the 1880s and 1890s formed political parties and revolutionary societies to secure better conditions for their compatriots in Anatolia and other parts of the Ottoman Empire.<ref>{{Citation | first = Richard G | last = Hovannisian | contribution = The Armenian Question in the Ottoman Empire, 1876–1914 | title = The Armenian People From Ancient to Modern Times | volume = ''Volume II: Foreign Dominion to Statehood: The Fifteenth Century to the Twentieth Century'' | editor-first = Richard G | editor-last = Hovannisian | place = New York | publisher = St Martin's Press |year =1997| pages = 206–12 | ISBN = 0-312-10168-6}}.</ref>
+
+==Lasting effects==
+
+===International Red Cross and Red Crescent Movement===
+[[File:Croixrouge logos.jpg|thumb|right|The [[Red Cross]] and the [[Red Crescent]] emblems]]
+This war caused a division in the [[Emblems of the International Red Cross and Red Crescent Movement|emblems]] of the [[International Red Cross and Red Crescent Movement]] which continues to this day. Both Russia and the Ottoman Empire had signed the [[First Geneva Convention]] (1864), which made the [[Emblems of the International Red Cross and Red Crescent Movement#Red Cross|Red Cross]], a color reversal of the [[Flag of Switzerland|flag]] of neutral [[Switzerland]], the sole emblem of protection for military medical personnel and facilities. However, during this war the cross instead reminded the Ottomans of the [[Crusades]]; so they elected to replace the cross with the [[Emblems of the International Red Cross and Red Crescent Movement#Red Crescent|Red Crescent]] instead. This ultimately became the symbol of the Movement's national societies in most [[Muslim]] countries, and was ratified as an emblem of protection by later [[Geneva Conventions]] in 1929 and again in 1949 (the current version).
+
+[[Iran]], which neighbored both the Russian Empire and Ottoman Empire, considered them to be rivals, and probably considered the Red Crescent in particular to be an Ottoman symbol; except for the Red Crescent being centered and without a star, it is a color reversal of the [[Ottoman flag]] (and the modern [[Flag of Turkey|Turkish flag]]). This appears to have led to their national society in the Movement being initially known as the [[Red Lion and Sun Society]], using a [[Emblems of the International Red Cross and Red Crescent Movement#The Red Lion and Sun|red version]] of the [[Lion and Sun]], a traditional Iranian symbol. After the [[Iranian Revolution]] of 1979, Iran switched to the Red Crescent, but the Geneva Conventions continue to recognize the Red Lion and Sun as an emblem of protection.
+
+==In popular culture==
+The novel ''[[The Doll (novel)|The Doll]]'' (Polish title: ''Lalka''), written in 1887–1889 by [[Bolesław Prus]], describes consequences of the Russo-Turkish war for merchants living in Russia and partitioned Poland. The main protagonist helped his Russian friend, a multi-millionaire, and made a fortune supplying the Russian Army in 1877–1878. The novel describes trading during political instability, and its ambiguous results for Russian and Polish societies.
+
+The 1912 silent film ''[[Independența României]]'' depicted the war in [[Romania]].
+
+== See also ==
+* [[Battles of the Russo-Turkish War (1877–78)]]
+* [[Ottoman fleet organisation during the Russo-Turkish War (1877–78)]]
+* [[Batak massacre]]
+* [[Romanian War of Independence]]
+* [[Harmanli massacre]]
+* [[History of the Balkans]]
+* [[Provisional Russian Administration in Bulgaria]]
+* ''[[The Turkish Gambit]]''
+* ''[[Marche slave]]''
+
+==Notes==
+{{Reflist | group = "lower-alpha"}}
+
+==References==
+{{reflist |colwidth=30em}}
+
+==Bibliography==
+* {{Citation | last1 = Allen | first1 = William ED | first2 = Paul | last2 = Muratoff | title = Caucasian Battlefields | publisher = Cambridge University Press | location = Cambridge | year = 1953}}.
+* {{Citation | url = https://archive.org/details/easternquestionf01argyuoft | title = The Eastern question from the Treaty of Paris 1836 to the Treaty of Berlin 1878 and to the Second Afghan War | volume = 2 | last = Argyll | first = George Douglas Campbell | place = London | publisher = Strahan | year = 1879}}.
+* {{cite book |last=Clodfelter |first=M. |title=Warfare and Armed Conflicts: A Statistical Encyclopedia of Casualty and Other Figures, 1492-2015 |publisher=McFarland |location=Jefferson, North Carolina |year=2017 |edition=4th |isbn=978-0786474707 |ref=harv }}
+* {{Citation | last = Crampton | first = RJ | title = A Concise History of Bulgaria | place = Cambridge | publisher = [[Cambridge University Press]] | year = 2006 | origyear = 1997 | ISBN = 0-521-85085-1}}.
+* {{Citation | author-link = William Ewart Gladstone | last = Gladstone | first = William Ewart | title = Bulgarian Horrors and the Question of the East | url = http://openlibrary.org/b/OL7083313M/Bulgarian-horrors-and-the-question-of-the-east | place = London | publisher = William Clowes & Sons | year = 1876}}.
+* {{cite book |last=Greene |first= F.V.|author-link = Francis Vinton Greene|title= The Russian Army and its Campaigns in Turkey |publisher= D.Appleton and Company |place=New York |year=1879 |pages= |url= https://archive.org/stream/russianarmyitsca00greeuoft#page/n3/mode/2up|accessdate= July 19, 2018|via= Internet Archive}}
+* {{Citation |last=von Herbert |first=Frederick William |year=1895 |title=The Defence of Plevna 1877 |url= https://archive.org/stream/defenceofplevna100harluoft#page/n7 |publisher=Longmans, Green & Co |place=London |via=Internet Archive |accessdate= 26 July 2018}}.
+* {{cite book |title= The War Correspondence of the "Daily News" 1877 with a Connecting Narrative Forming a Continuous History of the War Between Russia and Turkey to the Fall of Kars Including the Letters of Mr. Archibald Forbes, Mr. J. A. MacGahan and Many Other Special Correspondents in Europe and Asia |place= London |publisher= Macmillan and Co. |year= 1878 |accessdate= 26 July 2018 |url= https://archive.org/stream/warcorrespondenc00forbrich#page/n3/mode/1up |via= Internet Archive}}
+*{{cite book |title= The War Correspondence of the "Daily News" 1877-1878 continued from the Fall of Kars to the Signature of the Preliminaries of Peace |place= London |publisher= Macmillan and Co. |year= 1878 |accessdate= 26 July 2018 |url= https://archive.org/stream/warcorrespondenc00londrich#page/n3 |via= Internet Archive}}
+* {{cite book |last=Maurice |first= Major F.|author-link= Frederick Barton Maurice |title = The Russo-Turkish War 1877; A Strategical Sketch |place= London |publisher= Swan Sonneschein |year= 1905 |url=https://archive.org/stream/russoturkishwar100mauruoft#page/n7 |accessdate= August 8, 2018 |via= Internet Archive  }}
+* {{Citation | title = Genocide and gross human rights violations: in comparative perspective | first = Kurt | last = Jonassohn | year = 1999 | url = https://books.google.com/books?id=jIxCUXI38zcC&pg=PA210&dq=batak+church+bulgaria&hl=en&ei=rkefTfaiDobKtAa_ofDiAQ&sa=X&oi=book_result&ct=result&resnum=8&ved=0CFkQ6AEwBw#v=onepage&q=batak%20church%20bulgaria&f=false}}.* {{Citation | last = Reid | first = James J | url = https://books.google.com/books?id=Zgg6c_Ndtu4C&pg=PA42&dq=%22muslim+casualties%22+1878&hl=en&ei=Oqc8TfeiKsKUswbmoLTzBg&sa=X&oi=book_result&ct=result&resnum=1&ved=0CCIQ6AEwAA#v=onepage&q=%22muslim%20casualties%22%201878&f=false | title = Crisis of the Ottoman Empire: Prelude to Collapse 1839–1878 | place = Stuttgart | publisher = Steiner | year = 2000}}.
+* {{Citation | author1-link = Stanford J. Shaw| last1 = Shaw | first1 = Stanford J | first2 = Ezel Kural | last2 = Shaw | title = History of the Ottoman Empire and Modern Turkey | volume = 2, Reform, Revolution, and Republic: The Rise of Modern Turkey 1808–1975 | place = Cambridge | publisher = Cambridge University Press | year = 1977 |URL=https://books.google.com/books/about/History_of_the_Ottoman_Empire_and_Modern.html?id=E9-YfgVZDBkC}}.
+* Stavrianos, L.S. ''The Balkans Since 1453 ''  (1958) pp 393-412. [https://archive.org/details/balkanssince145300lsst online free to borrow]
+==Further reading==
+* {{cite journal | last = Acar | first = Keziban |date=March 2004 | title = An examination of Russian Imperialism: Russian Military and intellectual descriptions of the Caucasians during the Russo-Turkish War of 1877–1878 | journal = [[Nationalities Papers]] | volume = 32 | issue = 1 | pages = 7–21 | doi = 10.1080/0090599042000186151}}
+* Drury, Ian. ''The Russo-Turkish War 1877'' (Bloomsbury Publishing, 2012).
+* {{Citation | last = Glenny | first = Misha | title = The Balkans: Nationalism, War, and the Great Powers, 1804–2011 | place = New York | publisher = Penguin | year = 2012}}.
+* {{ru icon}} Kishmishev, Stepan I. (1884), ''Войнa вь Tурецкой Арменіи'', Saint Petersburg: Voen Publication.
+* Norman, Charles B. (1878), ''Armenia, and the Campaign of 1877'', London: Cassell Petter & Galpin.
+* {{Citation | editor1-last = Yavuz | editor1-first = M Hakan | editor2-first = Peter | editor2-last = Sluglett | title = War and Diplomacy: The Russo-Turkish War of 1877–1878 and the Treaty of Berlin | place = Salt Lake City | publisher = University of Utah Press | year = 2012}}.
+
+==External links==
+{{Commons category|Russo-Turkish War (1877–1878)}}
+{{EB1911 Poster|Russo-Turkish Wars|Russo-Turkish War (1877–78)}}
+* {{Citation | url = http://sparky.harvard.edu/kokkalis/GSW4/SeegelPAPER.PDF | format = [[PDF]] | title = Virtual War, Virtual Journalism?: Russian Media Responses to 'Balkan' Entanglements in Historical Perspective, 1877–2001 | first = Steven J | last = Seegel | publisher = Brown University | place = USA}}.
+* {{Citation | url = http://www.digitalbookindex.com/_search/search010hstmilitaryrussoturkishwara.asp | title = Military History: Russo-Turkish War (1877–1878) | publisher = Digital book index}}.
+* {{Citation|url=http://www.lib.msu.edu/sowards/balkan/ |title=Twenty Five Lectures on Modern Balkan History |first=Steven W |last=Sowards |publisher=MSU |deadurl=yes |archiveurl=https://web.archive.org/web/20071015050852/http://www.lib.msu.edu/sowards/balkan/ |archivedate=October 15, 2007 }}.
+* {{Citation | language = Russian | url = http://grandwar.kulichki.net/turkwar/ | title = Grand war | contribution = Russo-Turkish War of 1877–1878 and the Exploits of Liberators | publisher = Kulichki}}.
+* {{Citation | url = http://www.balkanhistory.com/romanian_army_1878.htm | title = The Romanian Army of the Russo-Turkish War 1877–1878 | publisher = AOL}}.
+* {{Citation|language=Bulgarian |url=http://erastimes.8m.net/gambit_b3.htm |type=image gallery |publisher=8M |title=Erastimes |deadurl=yes |archiveurl=https://web.archive.org/web/20061013190221/http://erastimes.8m.net/gambit_b3.htm |archivedate=October 13, 2006 }}
+* [http://diaryrh.ru/historical-photos/russo-turkish-war-of-1877-1878 Russo-Turkish War (1877–1878). Historical photos.]
+
+=== Video links ===
+'''130 years Liberation of Pleven (Plevna)'''
+* {{Citation | url = http://video.google.com/videoplay?docid=2277670243812622513 | type = speech | date = 3 March 2007 | title = Mayor of Pleven | first = Najden | last = Zelenogorsky | format = video | publisher = Google | access-date = 30 April 2007 | archive-url = https://web.archive.org/web/20071025032014/http://video.google.com/videoplay?docid=2277670243812622513 | archive-date = 25 October 2007 | dead-url = yes | df = dmy-all }}.
+* {{Citation | url = http://video.google.com/videoplay?docid=-2590633937611339870 | type = speech | date = 3 March 2007 | title = Bulgarian Prime Minister | first = Sergej | last = Stanishev | format = video | publisher = Google | access-date = 30 April 2007 | archive-url = https://web.archive.org/web/20071025032004/http://video.google.com/videoplay?docid=-2590633937611339870 | archive-date = 25 October 2007 | dead-url = yes | df = dmy-all }}.
+* {{Citation | url = http://video.google.com/videoplay?docid=-8057139363203914069 | type = speech | date = 3 March 2007 | last = Potapov | title = Ambassador of Russia in Bulgaria | format = video | publisher = Google | access-date = 30 April 2007 | archive-url = https://web.archive.org/web/20071024111430/http://video.google.com/videoplay?docid=-8057139363203914069 | archive-date = 24 October 2007 | dead-url = yes | df = dmy-all }}.
+
+{{Great power diplomacy}}
+{{Russian Conflicts}}
+{{Great Eastern Crisis}}
+{{Abdul Hamid II}}
+
+{{DEFAULTSORT:Russo-Turkish War (1877-78)}}
+[[Category:Russo-Turkish War (1877–1878)|*]]
+[[Category:Conflicts in 1877]]
+[[Category:Conflicts in 1878]]
+[[Category:Modern history of Bulgaria]]
+[[Category:Wars involving Chechnya]]
+[[Category:Wars involving Romania]]
+[[Category:Wars involving Serbia]]
+[[Category:Wars involving Montenegro]]
+[[Category:Wars involving Bulgaria]]
+[[Category:Russo-Turkish wars]]
+[[Category:1877 in Bulgaria]]
+[[Category:1878 in Bulgaria]]
+[[Category:1870s in the Ottoman Empire]]
+[[Category:Modern history of Armenia]]
+[[Category:Modern history of Georgia (country)]]
+
+{{refimprove|date=March 2018}}
+[[File:Treaty of San Stefano.jpg|thumb|300px|The signing of the treaty of San Stefano]]
+The 1878 '''Preliminary Treaty of San Stefano''' ([[Russian language|Russian]]: Сан-Стефанский мир; Peace of San-Stefano, Сан-Стефанский мирный договор; Peace treaty of San-Stefano, [[Turkish language|Turkish]]: ''Ayastefanos Muahedesi'' or ''Ayastefanos Antlaşması'') was a treaty between [[Russian Empire|Russia]] and the [[Ottoman Empire]] signed at [[Yeşilköy|San Stefano]], then a village west of [[Istanbul|Constantinople]], on {{OldStyleDate|3 March |1878|19 February}} by Count [[Nicholas Pavlovich Ignatiev]] and [[Aleksandr Nelidov]] on behalf of the Russian Empire and Foreign Minister [[Mehmed Esad Saffet Paşa|Safvet Pasha]] and Ambassador to Germany [[Sadullah Pasha|Sadullah Bey]] on behalf of the Ottoman Empire.<ref>{{Citation |last= Hertslet |first= Edward |author-link=Edward Hertslet |year=1891 |editor-last=  |editor-first= |contribution= Preliminary Treaty of Peace between Russia and Turkey. Signed at San Stefano 19 February/3 March 1878 (Translation)|title= The Map of Europe by Treaty; which have taken place since the general peace of 1814. With numerous maps and notes  |volume= IV  (1875-1891) |edition=First |publisher=  Her Majesty's Stationery Office |publication-date=1891|publication-place= London |pages= 2672–2696 |url=https://archive.org/stream/mapofeuropebytre04hert#page/2672/mode/2up|accessdate=2013-01-04 }}</ref><ref>{{Citation |last= Holland|first= Thomas Erskine |author-link= Thomas Erskine Holland |year=1885 |editor-last=  |editor-first= |title= The European Concert in the Eastern Question and Other Public Acts |contribution= The Preliminary Treaty of Peace, signed at San Stefano, 17 March 1878 |volume=  |edition= |publisher=  Clarendon Press |publication-date= |publication-place= Oxford |pages= 335–348 |url= https://archive.org/stream/europeanconcerti00holluoft#page/334/mode/2up  |accessdate=2013-03-04 }}</ref> The treaty ended the [[Russo-Turkish War, 1877–78]].<ref>{{cite book |author=J. D. B. |author-link = James Bourchier |chapter= Bulgaria (Treaties of San Stefano and Berlin)|title=The Encyclopaedia Britannica; A Dictionary of Arts, Sciences, Literature and General Information |page= 782 |year=1910 |volume=IV (BISHARIN to CALGARY)|edition= 11th |publisher=At the University Press |place=Cambridge, England |url= https://archive.org/stream/encyclopaediabri04chisrich#page/782/mode/2up |accessdate= 16 July 2018 |via= Internet Archive}}</ref>
+
+According to the official Russian position, by signing the treaty, Russia had never intended anything more than a temporary rough draft, so as to enable a final settlement with the other Great Powers.<ref>{{Citation |last= Holland|first= Thomas Erskine |author-link= Thomas Erskine Holland |year=1898 |editor-last=  |editor-first= |contribution= The Execution of the Treaty of Berlin |title= Studies in International Law |volume=  |edition= |publisher=  Clarendon Press |publication-date= |publication-place= Oxford |pages= 227 |url= https://archive.org/stream/cu31924007461654#page/n237/mode/2up |accessdate=2013-02-02 }}</ref><ref>Although it was inconsistent with the [[Treaty of Paris (1856)|Treaty of Paris of 1856]] and with the London Convention of 1871, and for that reason was justly protested by Great Britain, the Preliminary Treaty of Peace of San Stefano was, according to [[International law|general international law]], valid. See {{Citation |last=Kelsen |first=Hans  |author-link= Hans Kelsen|year= 1952 |editor-last=  |editor-first= |contribution=  |title=Principles of International Law |volume=  |edition= |publisher= Rinehart & Company Inc.  |publication-date= 1952 |publication-place= New York |pages=365  |url=  |accessdate= }}</ref>
+
+The treaty provided for the creation of an autonomous [[Principality of Bulgaria]] following almost 500 years of Ottoman domination. The day the treaty was signed,  {{OldStyleDate|3 March |1878|19 February}}, is celebrated as Liberation Day in Bulgaria. However, the enlarged Bulgaria envisioned by the treaty alarmed neighboring states as well as France and Great Britain.  As a result, it was never implemented, being superseded by the [[Treaty of Berlin (1878)|Treaty of Berlin]] following the [[Congress of Berlin|Congress]] of the same name that took place three months later.<ref>{{Cite EB1911|wstitle=Bulgaria/History}}</ref>
+
+==Effects==
+
+===On Bulgaria===
+[[File:Bulgaria-SanStefano -(1878)-byTodorBozhinov.png|right|thumb|300px|Borders of Bulgaria according to the Preliminary Treaty of San Stefano and the Treaty of Berlin.]] The treaty established  the autonomous self-governing [[Principality of Bulgaria]], with a Christian government and the right to keep an army. Though still ''[[de jure]]'' tributary to Turkey, the Principality ''[[de facto]]'' functioned as independent nation. Its territory included the plain between the [[Danube]] and the Balkan mountain range ([[Stara Planina]]), the region of [[Sofia]], [[Pirot]] and [[Vranje]] in the [[Morava rivers, Serbia|Morava]] valley, Northern [[Thrace]], parts of [[Eastern Thrace]] and nearly all of [[Macedonia (region)|Macedonia]] (Article 6).
+
+Bulgaria would thus have had direct access to the [[Mediterranean]]. This carried the potential of [[Russia]]n ships eventually using Bulgarian Mediterranean ports as naval bases - which the other Great Powers greatly disliked.   
+
+A prince elected by the people, approved by Turkey, and recognized by the [[Great Powers]] was to take the helm of the country (Article 7). A council of Bulgarian noblemen was to draft a constitution (also Article 7). (They produced the [[Tarnovo Constitution]].) Ottoman troops were to withdraw from Bulgaria, while Russian troops would remain for two more years (Article 8).
+
+===Montenegro, Serbia, and Romania===
+Under the treaty, [[Principality of Montenegro|Montenegro]] more than doubled its territory, acquiring formerly Ottoman-controlled areas including the cities of [[Nikšić]], [[Podgorica]], and [[Bar, Montenegro|Bar]] (Article 1), and the Ottoman Empire recognized its independence (Article 2).
+
+[[Principality of Serbia|Serbia]] gained the cities of [[Niš]] and [[Leskovac]] in [[Moravian Serbia]] and became independent (Article 3).
+
+Turkey recognized the independence of [[Romanian Principalities|Romania]] (Article 5). Romania gained [[Northern Dobruja]] from Russia (to which it was transferred from the Ottoman Empire) and ceded [[Southern Bessarabia]] in a forced exchange.
+
+===On Russia and the Ottoman Empire===
+[[Image:HouseOfSanStefanoTreaty.jpg|right|250px|thumb|The Treaty was signed in this house of the Simeonoglou family in [[Yeşilköy]].]]
+In exchange for the [[war reparations]], the Porte ceded [[Armenia]]n and [[Georgia (country)|Georgian]] territories in the [[Caucasus]] to Russia, including [[Ardahan]], [[Artvin]], [[Batumi|Batum]], [[Kars]], [[Oltu|Olti]], [[Doğubeyazıt|Beyazit]], and [[Eleşkirt|Alashkert]]. Additionally, it ceded [[Northern Dobruja]], which Russia handed to Romania in exchange for [[Southern Bessarabia]] (Article 19).
+
+===On other regions===
+The [[Vilayet of Bosnia]] ([[Bosnia and Herzegovina]]) was supposed to become an autonomous province (Article 14) like Serbia was; [[Crete]], [[Epirus]] and [[Thessaly]] were to receive a limited form of local self-government (Article 15), while the Ottomans vouched for their earlier-given promises to handle reforms in [[Armenia]] in order to protect the Armenians from abuse (Article 16).
+
+The Straits — the [[Bosporus]] and the [[Dardanelles]] — were declared open to all neutral ships in war and peacetime (Article 24).
+
+==Reaction==
+[[File:Karti od Sanstefan i Berlinski kongres 1878.jpg|thumb|400px|Maps of the region after the Treaty of San Stefano and the Congress of Berlin of 1878]]
+The Great Powers, especially British Prime Minister [[Benjamin Disraeli]], were unhappy with this extension of Russian power, and Serbia feared the establishment of [[Greater Bulgaria]] would harm its interests in former and remaining Ottoman territories. These reasons prompted the Great Powers to obtain a revision of the treaty at the [[Congress of Berlin]], and substitute the [[Treaty of Berlin (1878)|Treaty of Berlin]].
+
+Romania, which had contributed significantly to the Russian victory in the war, was extremely disappointed by the treaty, and the Romanian public perceived some of its stipulations as Russia breaking the Russo-Romanian pre-war treaties that guaranteed the integrity of Romanian territory.
+
+[[Austria-Hungary]] was disappointed with the treaty as it failed to expand its influence in Bosnia-Herzegovina.
+
+The [[Albania]]ns, dwelling in provinces controlled by the Ottoman Empire, objected to what they considered a significant loss of their territory to Serbia, Bulgaria, and Montenegro and realized they would have to organize nationally to attract the assistance of foreign powers seeking to neutralize Russia's influence in the region. The implications of the treaty led to the formation of the [[League of Prizren]].<ref>Gawrych, George. ''The Crescent and the Eagle''. London: I.B. Tauris, 2006, pp. 44-49.</ref>
+
+It is important to note that in the "Salisbury Circular" of 1 April 1878, the British Foreign Secretary, [[Robert Cecil, 3rd Marquess of Salisbury|Salisbury]], made clear his and his government's objections to the Treaty of San Stefano and the favorable position in which it left Russia.
+
+According to British historian [[A. J. P. Taylor]], writing in 1954, "If the treaty of San Stefano had been maintained, both the Ottoman Empire and Austria-Hungary might have survived to the present day. The British, except for <nowiki>[</nowiki>Disraeli<nowiki>]</nowiki> in his wilder moments, had expected less and were therefore less disappointed. Salisbury wrote at the end of 1878 'We shall set up a rickety sort of Turkish rule again south of the Balkans. But it is a mere respite. There is no vitality left in them.'"<ref>[[A. J. P. Taylor|Taylor, A. J. P.]] (1954) ''The Struggle for Mastery in Europe 1914-1918''. Oxford University Press, p. 253.</ref>
+
+==Gallery==
+<gallery class="center">
+File:0630 При подписании мирного договора Сан-Стефано, 3 марта 1878.jpg|Signing of peace treaty, San Stefano
+Image:SanStefano2.jpg|Annex to the Treaty of San Stefano, showing the change of Serbia's borders.
+Image:SanStefano3.jpg|Annex to the Treaty of San Stefano, showing the change of Montenegro's borders.
+Image:SanStefano1.jpg|Annex to the Treaty of San Stefano, showing the borders of the new Principality of Bulgaria.
+Image:SanStefano4.jpg|Annex to the Treaty of San Stefano, showing the change of the border between the Russian and the Ottoman Empire in the Caucasus.
+</gallery>
+
+==See also==
+{{Commons category}}
+* [[History of Bulgaria]]
+
+==References==
+{{Reflist}}
+
+==External links==
+*[http://pages.uoregon.edu/kimball/1878mr17.SanStef.trt.htm The Preliminary Treaty of Peace, signed at San Stefano] - Full text, in English.
+*[http://www.hist.msu.ru/ER/Etext/FOREIGN/stefano.htm Full text of the San Stefano Preliminary Treaty] (in Russian)
+
+===Maps===
+*[https://www.archives.government.bg/images/karta.jpg Bulgaria in the borders after the Treaties of Constantinople, San-Stephano, Berlin, London, Bucharest and Neuilly.] Scale 1:1600000 map. (in German)
+
+{{Ottoman treaties}}
+{{Great Eastern Crisis}}
+
+{{DEFAULTSORT:Treaty Of San Stefano}}
+[[Category:1878 in Bulgaria]]
+[[Category:1878 in the Ottoman Empire]]
+[[Category:1878 treaties]]
+[[Category:Russo-Turkish wars]]
+[[Category:Russo-Turkish War (1877–1878)]]
+[[Category:Peace treaties of the Ottoman Empire|San Stefano]]
+[[Category:Macedonia under the Ottoman Empire]]
+[[Category:19th century in Armenia]]
+[[Category:19th century in Georgia (country)]]
+[[Category:Peace treaties of Russia|San Stefano, Treaty of]]
+[[Category:Ottoman Empire–Russia treaties]]
+[[Category:History of Istanbul Province]]
+[[Category:History of Adjara]]
+[[Category:Ottoman period in Georgia (country)]]
+[[Category:March 1878 events]]
+[[Category:History of Montenegro]]
+
+{{for|similar international conferences in Berlin|Berlin Conference (disambiguation)}}
+{{Use dmy dates|date=February 2011}}
+[[File:Congress of Berlin, 13 July 1878, by Anton von Werner.jpg|400px|thumb|[[Anton von Werner]], ''Congress of Berlin'' (1881): Final meeting at the [[Reich Chancellery]] on 13 July 1878, [[Otto von Bismarck|Bismarck]] between [[Gyula Andrássy]] and [[Pyotr Andreyevich Shuvalov|Pyotr Shuvalov]], on the left [[Alajos Károlyi]], [[Alexander Gorchakov]] (seated) and [[Benjamin Disraeli]]]]
+
+The '''Congress of Berlin''' (13 June – 13 July 1878) was a meeting of the representatives of six [[great powers]] of the time (Russia, Great Britain, France, Austria-Hungary, Italy and Germany),<ref>{{Cite book|url=https://books.google.sk/books?id=EhqpAgAAQBAJ&pg=PA12&dq=congress+of+Berlin++1878++six++great+powers&hl=cs&sa=X&ved=0ahUKEwiInOfXtqvTAhXGEiwKHTNCAGEQ6AEIITAA#v=onepage&q=congress%20of%20Berlin%20%201878%20%20six%20%20great%20powers&f=false|title=Iran-Turkey Relations, 1979-2011: Conceptualising the Dynamics of Politics, Religion and Security in Middle-Power States– Google Knihy |publisher=Books.google.cz |date= March 1, 2013|accessdate=2017-04-17|isbn=978-0-415-68087-5}}</ref> the Ottoman Empire and four Balkan states (Greece, Serbia, Romania and Montenegro). It aimed at determining the territories of the states in the [[Balkan peninsula]] following the [[Russo-Turkish War (1877–1878)|Russo-Turkish War of 1877–78]] and came to an end with the signing of the [[Treaty of Berlin (1878)|Treaty of Berlin]], which replaced the preliminary [[Treaty of San Stefano]], signed three months earlier between [[Russian Empire|Russia]] and the [[Ottoman Empire]].
+
+[[File:Balkans 1878.png|thumb|Borders in the Balkan peninsula after the [[Treaty of Berlin (1878)]]]]
+
+German Chancellor [[Otto von Bismarck]], who led the Congress, undertook to stabilise the Balkans, recognise the reduced power of the Ottoman Empire and balance the distinct interests of Britain, [[Russian Empire|Russia]] and [[Austria-Hungary]]. At the same time, he tried to diminish Russian gains in the region and to prevent the rise of a [[Greater Bulgaria]]. As a result, Ottoman lands in Europe declined sharply, Bulgaria was established as an independent principality inside the Ottoman Empire, [[Eastern Rumelia]] was restored to the Turks under a special administration and the [[Macedonia (region)|region of Macedonia]] was returned outright to the Turks, who promised reform.
+
+[[Romania]] achieved full independence; forced to turn over part of [[Bessarabia]] to Russia, it gained [[Northern Dobruja]]. [[Serbia]] and [[Montenegro]] finally gained complete independence but with smaller territories, with Austria-Hungary occupying the [[Sandzak|Sandžak (Raška) region]].<ref>[http://www.mtholyoke.edu/acad/intrel/boshtml/bos128.htm Vincent Ferraro. The Austrian Occupation of Novibazar, 1878–1909 (based on: Anderson, Frank Maloy and Amos Shartle Hershey, Handbook for the Diplomatic History of Europe, Asia, and Africa 1870–1914. National Board for Historical Service. Government Printing Office, Washington, 1918.]</ref> Austria-Hungary also took over [[Bosnia and Herzegovina]], and Britain took over [[Cyprus]].
+
+The results were first hailed as a great achievement in peacemaking and stabilisation. However, most of the participants were not fully satisfied, and grievances on the results festered until they exploded in the [[First Balkan War|First]] and the [[Second Balkan War|Second]] Balkan wars in 1912–1913 and eventually [[World War I]] in 1914. Serbia, Bulgaria and Greece made gains, but all received far less than they thought that they deserved.
+
+The Ottoman Empire, then called the "sick man of Europe", was humiliated and significantly weakened, which made it more liable to domestic unrest and more vulnerable to attack.
+
+Although Russia had been victorious in the war that occasioned the conference, it was humiliated there and resented its treatment. Austria gained a great deal of territory, which angered the South Slavs, and led to decades of tensions in Bosnia and Herzegovina.
+
+Bismarck became the target of hatred by Russian nationalists and Pan-Slavists, and he would find that he had tied Germany too closely to Austria-Hungary in the Balkans.<ref>Jerome L. Blum, et al. ''The European World: A History'' (1970) p. 841</ref>
+
+In the long run, tensions between Russia and Austria-Hungary intensified, as did the nationality question in the Balkans. The congress was aimed at revising the [[Treaty of San Stefano]] and at keeping [[Constantinople]] within Ottoman hands. It effectively disavowed Russia's victory over the decaying Ottoman Empire in the Russo-Turkish War. The congress returned territories to the Ottoman Empire that the previous treaty had given to the [[Principality of Bulgaria]], most notably [[Macedonia (region)|Macedonia]], thus setting up a strong revanchist demand in Bulgaria, leading in 1912 to the First Balkan War.
+
+==Background==
+[[Image:Edward Stanford 1877.jpg|left|thumb|Pro-Greek ethnic map of the [[Balkans]] by Ioannis Gennadius,<ref>{{cite web|url=https://books.google.com/books?id=kEyinJwjWIgC&pg=PA169 |first=I. William |last=Zartman|authorlink=I. William Zartman|title=Understanding Life in the Borderlands|page=169}}</ref> published by the English cartographer E. Stanford in 1877]]
+
+In the decades leading up to the congress, Russia and the Balkans had been gripped by [[Pan-Slavism]], a movement to unite all the Balkan Slavs under one rule. That desire, which evolved similarly to the [[Pan-Germanism|Pan-Germanism]] and [[Italian Unification|Pan-Italianism]], which had resulted in two unifications, took different forms in the various Slavic nations. In Imperial Russia, Pan-Slavism meant the creation of a unified Slavic state, under Russian direction, and essentially a byword for Russian conquest of the Balkan peninsula.<ref>Ragsdale, Hugh, and V. N. Ponomarev. ''Imperial Russian Foreign Policy''. Woodrow Wilson Center Press, 1993, p. 228.</ref> The realisation of the goal would have Russian control of the [[Dardanelles]] and the [[Bosphorus]], thus giving Russia economic control of the [[Black Sea]] and substantially increasing its geopolitical power.   In the Balkans, Pan-Slavism meant unifying the Balkan Slavs under the rule of a particular Balkan state, but the state that was meant to serve as the locus for unification was not always clear, as initiative wafted between Serbia and Bulgaria.  The creation of a Bulgarian exarch by the Ottomans in 1870 had been intended to separate the Bulgarians religiously from the Greek patriarch and politically from Serbia.<ref>{{cite book|last=Taylor|first=Alan J. P.|title=Struggle for the Mastery of Europe 1848–1918|year=1954|publisher=Oxford University Press|location=UK|isbn=0198812701|pages=241}}</ref> From the Balkan point of view, unification of the peninsula needed both a [[Kingdom of Sardinia#Italian unification|Piedmont]] as a base and a corresponding France as a sponsor.{{sfn|Glenny|2000|pp=120–127}}
+
+Though the views of how Balkan politics should proceed differed, both began with the deposition of the sultan as ruler of the Balkans and the ousting of the Ottomans from Europe.  How and even whether that was to proceed would be the major question to be answered at the Congress of Berlin.
+
+==Great powers in the Balkans==
+The Balkans were a major stage for competition between the European [[great powers]] in the second half of the 19th century. Britain and Russia both had interests in the fate of the Balkans. Russia was interested in the region, both ideologically, as a pan-Slavist unifier, and practically, to secure greater control of the Mediterranean; Britain was interested in preventing Russia from accomplishing its goals. Furthermore, the Unifications of Italy and Germany had stymied the ability of a third European power, Austria-Hungary, to further expand its domain to the southwest. Germany, as the most powerful continental nation after the 1871 [[Franco-Prussian War]] had little direct interest in the settlement and so was the only power that could mediate the Balkan question.{{sfn|Glenny|2000|pp=135–137}}
+
+Russia and Austria-Hungary, the two powers that were most invested in the fate of the Balkans, were allied with Germany in the conservative [[League of Three Emperors]], founded to preserve the monarchies of [[Continental Europe]]. The Congress of Berlin was thus mainly a dispute among supposed Bismarck and his German Empire, the arbiter of the discussion, would thus have to choose before the end of the congress one of their allies to support. That decision was to have direct consequences on the future of European geopolitics.<ref>{{cite book|author=William Norton Medlicott|title=Congress of Berlin and After|url=https://books.google.com/books?id=jU7YAQAAQBAJ|year=1963|publisher=Routledge|isbn=978-1-136-24317-2|pages=14–}}</ref>{{sfn|Glenny|2000|pp=135–137}}
+
+Ottoman brutality in the [[Serbian–Ottoman War (1876–78)|Serbian–Ottoman War]] and the violent suppression of the [[Herzegovina Uprising (1875–77)|Herzegovina Uprising]] formented political pressure within Russia, which saw itself as the protector of the Serbs, to act against the Ottoman Empire. David MacKenzie wrote that 'sympathy for the Serbian Christians existed in Court circles, among nationalist diplomats, and in the lower classes, and was actively expressed through the Slav committees'.<ref name="MacKenzie1967">{{cite book|author=David MacKenzie|title=The Serbs and Russian Pan-Slavism, 1875-1878|url=https://books.google.com/books?id=7bQMAAAAIAAJ|year=1967|publisher=Cornell University Press|page=7}}</ref>
+
+Eventually, Russia sought and obtained Austria-Hungary's pledge of benevolent neutrality in the coming war, in return for ceding Bosnia Herzegovina to Austria-Hungary in the [[Budapest Convention of 1877]].
+
+==Treaty of San Stefano==
+[[File:Ethnic map of Balkans Kiepert.1878.png|thumb|Ethnographic map by German geographer [[Heinrich Kiepert]], 1878. This map received a good reception in contemporary Europe and was used as a reference at the Congress of Berlin.<ref>{{cite book|title=Understanding Life in the Borderlands|page=174|url=https://books.google.gr/books?id=Mnc6pguW220C&dq=|quote=In the map shown in figure 7.2,... used as a reference at the Congress of Berlin - clear praise for its perceived objectivity.}}</ref>]]
+After the Bulgarian [[April Uprising]] in 1876 and the Russian victory in the [[Russo-Turkish War, 1877-1878|Russo-Turkish War of 1877–1878]], Russia had liberated almost all of the Ottoman European possessions.  The Ottomans recognized Montenegro, Romania and Serbia as independent, and the territories of all three were expanded. Russia created a large Principality of Bulgaria as an autonomous vassal of the sultan.  This expanded Russia's sphere of influence to encompass the entire Balkans, which alarmed other powers in Europe. Britain, which had threatened war with Russia if it occupied [[Constantinople]],<ref>Ragsdale, Hugh, and V. N. Ponomarev. ''Imperial Russian Foreign Policy''. Woodrow Wilson Center Press, 1993, pp. 239–40.</ref> and France both did not want another power meddling in either the Mediterranean or the Middle East, where both powers were prepared to make large [[Scramble for Africa|colonial gains]].  Austria-Hungary desired Habsburg control over the Balkans, and Germany wanted to prevent its ally from going to war. German Chancellor Otto von Bismarck thus called the Congress of Berlin to discuss the partition of the Ottoman Balkans among the European powers and to preserve the League of Three Emperors in the face of the spread of European [[Liberalism#Spread of liberalism|liberalism]].{{sfn|Glenny|2000|pp=135–138}}
+
+The Congress was attended by Britain, Austria-Hungary, France, Germany, [[Kingdom of Italy (1861–1946)|Italy]], Russia and the [[Ottoman Empire]]. Delegates from [[Kingdom of Greece (Glücksburg)|Greece]], [[Kingdom of Romania|Romania]], [[Serbia]] and [[Montenegro]] attended the sessions that concerned their states, but they were not members of the Congress. The Congress was solicited by Russia's rivals, particularly Austria-Hungary and Britain, and it was hosted in 1878 by [[Otto von Bismarck]]. It proposed and ratified the [[Treaty of Berlin, 1878|Treaty of Berlin]]. The meetings were held at Bismarck's [[Reich Chancellery]], the former [[Radziwill]] Palace, from 13 June 1878 to 13 July 1878.  The congress revised or eliminated 18 of the 29 articles in the [[Treaty of San Stefano]]. Furthermore, by using as a foundation the Treaties of [[Treaty of Paris (1856)|Paris (1856)]] and [[Treaty of Washington (1871)|Washington]] (1871), the treaty rearranged the East.
+
+==Other powers' fear of Russian influence==
+[[File:Ernst-Ravenstein-Balkans-Ethnic-Map-1880.jpg|thumb|Ethnic composition map of the [[Balkans]] by the German-English cartographer [[Ernst Georg Ravenstein]] of 1870]]
+
+The principal mission of the participants at the congress was to deal a fatal blow to the burgeoning movement of [[pan-Slavism]]. The movement caused serious concern in Berlin and even more so in Vienna, which was afraid that the repressed Slavic nationalities would revolt against the [[Habsburgs]]. The [[British government|British]] and the [[France|French]] governments were nervous about both the diminishing influence of the Ottoman Empire and the cultural expansion of Russian to the south, where both Britain and France were poised to colonise [[Egypt]] and [[Palestine (region)|Palestine]]. By the Treaty of San Stefano, the Russians, led by Chancellor [[Alexander Gorchakov]], had managed to create in a [[Bulgaria]] an autonomous principality, under the nominal rule of the [[Ottoman Empire]]. That sparked the [[Great Game]], the massive British fear of the growing Russian influence in the [[Middle East]]. The new principality, including a very large portion of [[Macedonia (region)|Macedonia]] and with access to the [[Aegean Sea]], could easily threaten the [[Dardanelle Straits]], which separate the [[Black Sea]] from the [[Mediterranean Sea]]. The arrangement was not acceptable to the British, which considered the entire Mediterranean to be a British [[sphere of influence]] and saw any Russian attempt to gain access there as a grave threat to British power. On 4 June, before the Congress opened on 13 June, Prime Minister [[Benjamin Disraeli|Lord Beaconsfield]] had already concluded the [[Cyprus Convention]], a secret alliance with the Ottomans against Russia in which Britain was allowed to occupy the strategically-placed island of [[Cyprus]]. The agreement predetermined Beaconsfield's position during the Congress and led him to issue threats to unleash a war against Russia if it did not comply with Ottoman demands. Negotiations between Austro-Hungarian Foreign Minister [[Gyula Andrássy]] and British Foreign Secretary [[Robert Cecil, 3rd Marquess of Salisbury|Marquess of Salisbury]] had already 'ended on 6 June by Britain agreeing to all the Austrian proposals relative to Bosnia-Herzegovina about to come before the congress while Austria would support British demands'.{{sfn|Albertini|1952|p=20}}
+
+==Bismarck as host==
+The Congress of Berlin is frequently viewed as the culmination of the battle between Chancellors [[Alexander Gorchakov]] of Russia and [[Otto von Bismarck]] of Germany. They were able to persuade other European leaders that a free and independent [[Bulgaria]] would greatly improve the security risks posed by a disintegrating Ottoman Empire. According to historian [[Erich Eyck]], Bismarck supported Russia's position that "Turkish rule over a Christian community (Bulgaria) was an anachronism which undoubtedly gave rise to insurrection and bloodshed and should therefore be ended".<ref name="Eyck">Erich Eyck, ''Bismarck and the German Empire'' (New York: W.W. Norton, 1964), pp. 245–46.</ref> He used the [[Great Eastern Crisis]] of 1875 as proof of growing animosity in the region.
+
+[[File:Bulgaria San Stefano Berlin 1878 TB.png|left|thumb|Borders of Bulgaria according to the preliminary [[Treaty of San Stefano]] (red stripes) and the superseding [[Treaty of Berlin (1878)|Treaty of Berlin]] (solid red)]]
+
+Bismarck's ultimate goal during the Congress of Berlin was not to upset Germany's status on the international platform. He did not wish to disrupt the [[League of the Three Emperors]] by choosing between Russia and Austria as an ally.<ref name="Eyck"/> To maintain peace in Europe, Bismarck sought to convince other European diplomats on dividing up the [[Balkans]] to foster greater stability. During the division, Russia began to feel cheated even though it eventually gained independence for Bulgaria. Problems in the alliances in Europe before the [[First World War]] were thus noticeable.
+
+One reason that Bismarck was able to mediate the various tensions at the Congress of Berlin was his diplomatic persona. He sought peace and stability when international affairs did not pertain to Germany directly. Since he viewed the current situation in Europe as favourable for Germany, any conflicts between the major European powers that were threatening the status quo was against German interests. Also, at the Congress of Berlin, "Germany could not look for any advantage from the crisis" that had occurred in the Balkans in 1875.<ref name="Eyck"/> As a result, Bismarck claimed impartiality on behalf of Germany at the Congress. That claim enabled him to preside over the negotiations with a keen eye for foul play.
+
+Though most of Europe went into the Congress expecting a diplomatic show, much like the [[Congress of Vienna]], they were to be sadly disappointed. Bismarck, unhappy to be conducting the Congress in the heat of the summer, had a short temper and a low tolerance for malarky. Thus, any grandstanding was cut short by the testy German chancellor. The ambassadors from the small Balkan territories whose fate was being decided were barely even allowed to attend the diplomatic meetings, which were between mainly the representatives of the great powers.{{sfn|Glenny|2000|pp=138–140}}
+
+According to [[Henry Kissinger]],<ref>{{Cite book
+| publisher = Simon & Schuster
+| isbn = 0-671-51099-1
+| pages = 139–143
+| last = Kissinger
+| first = Henry
+| title = Diplomacy
+| date = 1995-04-04
+}}</ref> the congress saw a shift in Bismarck's [[Realpolitik]]. Until then, as Germany had become too powerful for isolation, his policy was to maintain the League of the Three Emperors. Now that he could no longer rely on Russia's alliance, he began to form relations with as many potential enemies as possible.
+
+== Legacy ==
+[[Image:A Synvet 1877.jpg|thumb|Ethnic composition map of the [[Balkans]] in 1877 by A. Synvet, a known French professor of the Ottoman Lyceum of Constantinople]]
+
+Bowing to Russia's pressure, Romania, Serbia and Montenegro were declared independent principalities.  Russia kept [[Bessarabia|South Bessarabia]], which it had annexed in the Russo-Turkish War, but the Bulgarian state that it had created was first bisected and then split further into the Principality of Bulgaria and Eastern Rumelia, both of which were given nominal autonomy, under the control of the Ottoman Empire.<ref>Oakes, Augustus, and R. B. Mowat. ''The Great European Treaties of the Nineteenth Century''. Clarendon Press, 1918, pp. 332–60.</ref> Bulgaria was promised autonomy, and guarantees were made against Turkish interference, but they were largely ignored. Romania received [[Dobruja]]. Montenegro obtained [[Nikšić]], along with the primary Albanian regions of [[Podgorica]], [[Bar, Montenegro|Bar]] and [[Plav-Gusinje]]. The Turkish government, or [[Ottoman Porte|Porte]], agreed to obey the specifications contained in the Organic Law of 1868 and to guarantee the civil rights of non-Muslim subjects. The region of Bosnia-Herzegovina was given over to the administration of Austria-Hungary, which also obtained the right to garrison the [[Sanjak of Novi Pazar]], a small border region between Montenegro and Serbia. Bosnia and Herzegovina were put on the fast track to eventual annexation. Russia agreed that [[Macedonia region|Macedonia]], the most important strategic section of the Balkans, was too multinational to be part of Bulgaria and permitted it to remain under the [[Ottoman Empire]]. [[Eastern Rumelia]], which had its own large Turkish and Greek minorities, became an autonomous province under a Christian ruler, with its capital at [[Plovdiv|Philippopolis]]. The remaining portions of the original "Greater Bulgaria" became the new state of Bulgaria.
+[[Image:Litografia.jpg|thumb|Allegorical depiction of Bulgarian autonomy after the [[Treaty of Berlin (1878)|Treaty of Berlin]].<br /> Lithograph by [[Nikolai Pavlovich]]]]
+
+In Russia, the Congress of Berlin was considered a dismal failure. After finally defeating the Turks despite many past inconclusive Russo-Turkish wars, many Russians had expected "something colossal", a redrawing of the Balkan borders in support of Russian territorial ambitions. Instead, the victory resulted in an Austro-Hungarian gain on the Balkan front that was brought about by the rest of the European powers' preference for a powerful Austria-Hungarian Empire, which threatened basically no one, to a powerful Russia, which had been locked in competition with Britain in the so-called [[Great Game]] for most of the century. Gorchakov said, "I consider the Berlin Treaty the darkest page in my life". The Russian people were by and large furious over the European repudiation of their political gains, and though there was some thought that it represented only a minor stumble on the road to Russian hegemony in the Balkans, it actually gave Bosnia-Herzegovina and Serbia over to Austria-Hungary's sphere of influence and essentially removed all Russian influence from the area.<ref>Ragsdale, Hugh, and V. N. Ponomarev. ''Imperial Russian Foreign Policy''. Woodrow Wilson Center Press, 1993, pp. 244–46.</ref>
+
+The Serbs were upset with "Russia... consenting to the cession of Bosnia to Austria."{{sfn|Albertini|1952|p=32}}
+
+<blockquote>
+[[Jovan Ristić|Ristić]] who was Serbia’s first plenipotentiary at Berlin tells how he asked Jomini, one of the Russian delegates, what consolation remained to the Serbs. Jomini replied that it would have to be the thought that 'the situation was only temporary because within fifteen years at the latest we shall be forced to fight Austria.' 'Vain consolation!' comments Ristić.{{sfn|Albertini|1952|p=32}}
+</blockquote>
+[[File:Greek-Delegation-Berlin-Congress.jpg|thumb|Greek Delegation in the Berlin Congress]]
+Italy was dissatisfied with the results of the Congress, and the tensions between Greece and the Ottoman Empire were left unresolved. Bosnia-Herzegovina would also prove to be problematic for the Austro-Hungarian Empire in later decades. The [[League of the Three Emperors]], established in 1873, was destroyed, as Russia saw lack of German support on the issue of Bulgaria's full independence as a breach of loyalty and of the alliance. The border between Greece and Turkey was not resolved. In 1881, after protracted negotiations, a compromise border [[Convention of Constantinople (1881)|was accepted]], occurring after a naval demonstration of the great powers, resulting in the cession of [[Thessaly]] and the [[Arta Prefecture]] to Greece.
+
+Thus, the Berlin Congress sowed the seeds of further conflicts, including the Balkan Wars and (ultimately) the [[First World War]]. In the 'Salisbury Circular' of 1 April 1878, the British Foreign Secretary, the [[Robert Cecil, 3rd Marquess of Salisbury|Marquess of Salisbury]], made clear the objections of him and the government to the Treaty of San Stefano because of the favorable position in which it left Russia.<ref>Walker, Christopher J. (1980), ''Armenia: The Survival of A Nation'', London: Croom Helm, p. 112</ref>
+
+In 1954, British historian [[AJP Taylor]] wrote: "If the treaty of San Stefano had been maintained, both the Ottoman Empire and Austria-Hungary might have survived to the present day. The British, except for [[Disraeli|Beaconsfield]] in his wilder moments, had expected less and were therefore less disappointed. Salisbury wrote at the end of 1878: ''We shall set up a rickety sort of Turkish rule again south of the Balkans. But it is a mere respite. There is no vitality left in them.''"<ref>AJP Taylor, ''The Struggle for Mastery in Europe 1914–1918,'' [[Oxford University Press]] (1954) p. 253</ref>
+
+Though the Congress of Berlin constituted a harsh blow to [[Pan-Slavism]], it by no means solved the question of the area. The Slavs in the Balkans were still mostlty under non-Slavic rule, split between the rule of Austria-Hungary and the ailing Ottoman Empire. The Slavic states of the Balkans had learned that banding together as Slavs benefited them less than playing to the desires of a neighboring great power. That damaged the unity of the Balkan Slavs and encouraged competition between the fledgling Slav states.{{sfn|Glenny|2000|pp=133–134}}
+
+The underlying tensions of the region would continue to simmer for 30 years until they again exploded in the [[Balkan Wars]] of 1912–1913. In 1914, the [[assassination of Franz Ferdinand]] the Austro-Hungarian heir, led to the [[First World War]]. In hindsight, the stated goal of maintaining peace and balance of powers in the Balkans obviously failed, as the region would remain a source of conflict between the great powers well into the 20th century.{{sfn|Glenny|2000|p=151}}
+
+==Internal opposition to Andrássy's objectives==
+
+Austro-Hungarian Foreign Minister [[Gyula Andrássy]] and [[Austro-Hungarian occupation of Bosnia and Herzegovina|the occupation and administration of Bosnia-Herzegovina]] also obtained the right to station garrisons in the [[Sanjak of Novi Pazar]], which remained under Ottoman administration. The Sanjak preserved the separation of Serbia and Montenegro, and the Austro-Hungarian garrisons there would open the way for a dash to [[Thessaloniki|Salonika]] that "would bring the western half of the Balkans under permanent Austrian influence".{{sfn|Albertini|1952|p=19}} "High [Austro-Hungarian] military authorities desired... [an] immediate major expedition with Salonika as its objective".{{sfn|Albertini|1952|p=33}}
+
+<blockquote>
+On 28 September 1878 the Finance Minister, Koloman von Zell, threatened to resign if the army, behind which stood the [[Archduke Albrecht, Duke of Teschen|Archduke Albert]], were allowed to advance to Salonika. In the session of the Hungarian Parliament of 5 November 1878 the Opposition proposed that the Foreign Minister should be impeached for violating the constitution by his policy during the Near East Crisis and by the occupation of Bosnia-Herzegovina. The motion was lost by 179 to 95. By the Opposition rank and file the gravest accusations were raised against Andrassy.{{sfn|Albertini|1952|p=33}}
+</blockquote>
+
+On 10 October 1878, French diplomat [[Melchior de Vogüé]] described the situation as follows:
+
+<blockquote>
+Particularly in Hungary the dissatisfaction caused by this 'adventure' has reached the gravest proportions, prompted by that strong conservative instinct which animates the Magyar race and is the secret of its destinies. This vigorous and exclusive instinct explains the historical phenomenon of an isolated group, small in numbers yet dominating a country inhabited by a majority of peoples of different races and conflicting aspirations, and playing a role in European affairs out of all proportions to its numerical importance or intellectual culture. This instinct is today awakened and gives warning that it feels the occupation of Bosnia-Herzegovina to be a menace which, by introducing fresh Slav elements into the Hungarian political organism and providing a wider field and further recruitment of the Croat opposition, would upset the unstable equilibrium in which the Magyar domination is poised.{{sfn|Albertini|1952|pp=33–34}}
+</blockquote>
+
+==Delegates==
+{{col-begin}}
+| width="50%" align="left" valign="top" style="border:0"|
+[[United Kingdom]] {{flagicon|United Kingdom}}
+*  [[Benjamin Disraeli]] Earl of Beaconsfield  (Prime Minister)
+*  [[Robert Gascoyne-Cecil, 3rd Marquess of Salisbury|Marquess of Salisbury]] (Foreign Secretary)
+*  [[Odo Russell, 1st Baron Ampthill|Baron Ampthill]] (Ambassador to Germany)
+
+[[Russian Empire]] {{flagicon|Russian Empire}}
+*  [[Alexander Gorchakov|Prince Gorchakov]] (Foreign Minister)
+*  [[Pyotr Andreyevich Shuvalov|Count Shuvalov]] (Ambassador to Great Britain)
+*  [[Pavel Ubri|Baron d'Oubril]] (Ambassador to Germany)
+
+[[German Empire]] {{flagicon|German Empire}}
+*  [[Otto von Bismarck]] (Chancellor)
+*  [[Chlodwig, Prince of Hohenlohe-Schillingsfürst|Prince Hohenlohe]] (Ambassador to France)
+*  [[Bernhard Ernst von Bülow]] (State Secretary for Foreign Affairs)
+
+[[Austria-Hungary]] {{flagicon|Austria-Hungary}}
+*  [[Gyula Andrássy|Count Andrássy]] (Foreign Minister)
+*  [[Alajos Károlyi|Count Károlyi]] (Ambassador to Germany)
+*  [[Baron Heinrich Karl von Haymerle]] (Ambassador to Italy)
+
+[[French Third Republic|French Republic]] {{flagicon|France}}
+*  [[William Henry Waddington|Monsieur Waddington]] (Foreign Minister)
+*  Comte de Saint-Vallier
+*  Monsieur Desprey
+| width="50%" align="left" valign="top" style="border:0"|
+[[Kingdom of Italy (1861–1946)|Kingdom of Italy]] {{flagicon|Kingdom of Italy}}
+*  [[Lodovico, Count Corti|Count Corti]] (Foreign Minister)
+*  Count De Launay
+
+[[Ottoman Empire]] {{flagicon|Ottoman Empire}}
+*  [[Alexander Karatheodori Pasha|Karatheodori Pasha]]
+*  [[Sadullah Pasha]]
+*  [[Mehmed Ali Pasha (marshal)|Mehmed Ali Pasha]]
+*  [[Catholicos]] [[Mkrtich Khrimian]] (representing Armenian population)
+
+[[United Principalities|Romania]] {{flagicon|Romania}}
+* [[Ion Brătianu|Ion C. Brătianu]]
+* [[Mihail Kogălniceanu]]
+
+[[Kingdom of Greece|Greece]] {{flagicon|Kingdom of Greece}}
+* [[Theodoros Deligiannis]]
+
+[[Principality of Serbia|Serbia]] {{flagicon|Serbia|civil}}
+* [[Jovan Ristić]]
+
+[[Principality of Montenegro|Montenegro]] {{flagicon|Principality of Montenegro}}
+* Božo Petrović
+* Stanko Radonjić
+
+[[Albanian people|Albanians in the Ottoman Empire]] {{flagicon|Albania}}
+* [[Abdyl Frasheri]] 
+* [[Jani Vreto]]
+
+{{col-end}}
+
+==References==
+{{reflist|3}}
+
+==Sources==
+*{{cite book|last=Glenny|first=Misha|authorlink=Misha Glenny|title=The Balkans, 1804-1999: Nationalism, War and the Great Powers|url=https://books.google.com/books?id=96G-Ofq2iNMC|year=2000|publisher=Granta Books|isbn=978-1-86207-073-8|ref=harv}}
+*{{cite book|last=Albertini|first=Luigi|authorlink=Luigi Albertini|title=The Origins of the War of 1914: European relations from the Congress of Berlin to the eve of the Sarajevo murder|url=https://books.google.com/books?id=0kUOAQAAIAAJ|year=1952|publisher=Oxford University Press|ref=harv}}
+* Langer, William L. ''European Alliances and Alignments 1871–1890'' (1950)  ch 5–6
+* [https://web.archive.org/web/20080621140434/http://isanet.ccit.arizona.edu/noarchive/berlincongress.html Mikulas Fabry. THE IDEA OF NATIONAL SELF-DETERMINATION AND THE RECOGNITION OF NEW STATES AT THE CONGRESS OF BERLIN (1878). ISA Annual Convention, New Orleans, March 24–27, 2002]
+* [[W. N. Medlicott|Medlicott, William Norton]]. ''Congress of Berlin and After'' (1963)
+* Millman, Richard. ''Britain and the Eastern Question, 1875–78'' (1979)
+* Taylor, A.J.P. ''The Struggle for Mastery in Europe: 1848–1918'' (1954) pp.&nbsp;228–54
+
+==External links==
+* {{Commons category-inline|Congress of Berlin}}
+
+{{Great power diplomacy}}
+{{Great Eastern Crisis}}
+{{coord|52|30|42|N|13|22|55|E|display=title}}
+
+{{DEFAULTSORT:Congress Of Berlin}}
+[[Category:Diplomatic conferences in Germany]]
+[[Category:History of the Balkans]]
+[[Category:Modern Europe]]
+[[Category:19th-century diplomatic conferences]]
+[[Category:1878 in international relations]]
+[[Category:1878 in Germany]]
+[[Category:1878 conferences]]
+[[Category:19th century in Berlin]]
+[[Category:June 1878 events]]
+[[Category:July 1878 events]]
+
+{{Infobox military conflict
+| conflict   = Great Eastern Crisis (1875–78)
+| partof     = 
+| image      = Clash with Cherkessians.jpg
+| image_size = 300
+| caption    = Serbian soldiers attacking the Ottoman army at [[Mramor (Niš)|Mramor]], 1877
+| date       = 9 July 1875 – 13 July 1878<br />({{Age in years, months, weeks and days|month1=07|day1=09|year1=1875|month2=07|day2=13|year2=1878}})
+| place      = [[Balkans]], [[Caucasus]]
+| territory  = 
+* Reestablishment of the [[Principality of Bulgaria|Bulgarian state]]
+* ''[[De jure]]'' independence of [[United Principalities|Romania]], [[Principality of Serbia|Serbia]] and [[Principality of Montenegro|Montenegro]] from the [[Ottoman Empire]]
+* [[Kars Oblast|Kars]] and [[Batum Oblast]]s become part of the [[Russian Empire]]
+| result     = [[Treaty of Berlin (1878)|Treaty of Berlin]]
+| combatant1 = {{flagcountry|Russian Empire|1858}}<br />
+:* [[Grand Duchy of Finland]]<br />
+{{flagdeco|Kingdom of Romania}} [[United Principalities|Romania]]<br />{{flagdeco|Kingdom of Bulgaria}} [[Principality of Bulgaria|Bulgaria]]<br />{{flagcountry|Principality of Montenegro}}<br/>{{flagdeco|Serbia|civil}} [[Principality of Serbia|Serbia]]<br>
+'''Supported by''':<br>
+{{flag|Austria-Hungary}}<br />{{flagcountry|German Empire}}<br />{{flagcountry|French Third Republic}}
+| combatant2 = {{flag|Ottoman Empire}}
+'''Supported by''':<br>{{flagcountry|UKGBI}}
+| commander1 = {{flagicon |Russian Empire|1858}} [[Alexander II of Russia|Alexander II]]<br />{{flagicon |Russian Empire|1858}} [[Grand Duke Nicholas Nikolaevich of Russia (1831–1891)|Grand Duke Nicholas Nikolaevich]]<br />{{flagicon |Russian Empire|1858}}  [[Grand Duke Michael Nikolaevich of Russia|Grand Duke Michael Nikolaevich]]<br />{{flagicon |Russian Empire|1858}} [[Mikhail Loris-Melikov]]<br />{{flagicon|Russian Empire|1858}} [[Mikhail Skobelev]]<br />{{flagicon |Russian Empire|1858}} [[Iosif Gurko]]<br />  {{flagicon|Russian Empire|1858}} [[Ivan Davidovich Lazarev|Ivan Lazarev]]<br />{{flagicon|Romania}} [[Carol I of Romania]]<br />{{flagicon|Kingdom of Bulgaria}} [[Alexander of Battenberg]]<br />{{flagicon|Principality of Montenegro}} [[Nicholas I of Montenegro|Prince Nikola]] <br />{{flagicon |Serbia|civil}} [[Kosta Protić]]
+| commander2 = {{flagicon|Ottoman Empire}} [[Abdul Hamid II]]<br />{{flagicon|Ottoman Empire}} [[Ahmed Muhtar Pasha|Ahmed Pasha]]<br />{{flagicon |Ottoman Empire}} [[Osman Nuri Pasha|Osman Pasha]]<br />{{flagicon|Ottoman Empire}} [[Süleyman Hüsnü Paşa|Suleiman Pasha]]<br />{{flagicon|Ottoman Empire}} [[Mehmed Ali Pasha (marshal)|Mehmed Pasha]]<br /> {{flagicon|Ottoman Empire}} [[Abdülkerim Nadir Pasha]]<br /> {{flagicon|Ottoman Empire}} [[Ahmed Eyüb Pasha]]<br /> {{flagicon|Ottoman Empire}} [[Mehmed Riza Pasha]]
+| strength1  = '''Russian Empire''' – 185,000 in the Army of the Danube, 75,000 in the Caucasian Army<ref>Timothy C. Dowling. Russia at War: From the Mongol Conquest to Afghanistan, Chechnya, and Beyond. 2 Volumes. ABC-CLIO, 2014. P. 748</ref><br />
+'''Finland''' - 1,000<br />
+'''Romania''' – 66,000<br />
+'''Montenegro''' – 45,000<br />
+'''Bulgaria''' – 12,000<br />
+190 cannons<br />
+'''Serbia''' – 81,500<br />
+| strength2   = '''Ottoman Empire''' – 281,000<ref>{{Citation | last = Мерников | first = АГ | script-title=ru:Спектор А. А. Всемирная история войн | place = Минск | year = 2005. – c. 376| language = Russian }}.</ref>
+| casualties1 = '''Russian Empire''' – 15,567 killed, <br /> 56,652 wounded, <br /> 6,824 died from wounds<ref name="Урланис">{{cite book| author = [[Урланис Б. Ц.]] | chapter = Войны в период домонополистического капитализма (Ч. 2)| chapter-url = http://scepsis.net/library/id_2140.html#a161| format = | url =  | title = Войны и народонаселение Европы. Людские потери вооруженных сил европейских стран в войнах XVII—XX вв. (Историко-статистическое исследование) | orig-year = | agency =  | edition = | location = М.| year = 1960 | publisher = [[Соцэкгиз]]| at = | volume = | issue = | pages = 104–105, 129 § 4| page =  | series =  | isbn = | ref = }}</ref><br />
+'''Romania''' — 4,302 killed and missing, <br /> 3,316 wounded, <br /> 19,904 sick <ref>Scafes, Cornel, et. al., ''Armata Romania in Razvoiul de Independenta 1877–1878'' (The Romanian Army in the War of Independence 1877–1878). Bucuresti, Editura Sigma, 2002, p. 149 (Romence)</ref>
+
+'''Bulgaria''' – 2,456 dead and wounded<ref name="scepsis.net">Борис Урланис, Войны и народонаселение Европы, Часть II, Глава II http://scepsis.net/library/id_2140.html</ref><br />
+'''Serbia''' and '''Montenegro''' – 2,400 dead and wounded<ref name="scepsis.net"/>
+
+| casualties2 = 30,000 killed,<ref name="Мерников Спектор">{{cite book| author1 = Мерников А. Г.|author2= Спектор А. А.| title = Всемирная история войн| location = Мн.| year = 2005| publisher = Харвест| isbn = 985-13-2607-0}}</ref><br/>90,000 died from wounds and diseases<ref name="Мерников Спектор"/>
+
+| campaignbox =
+{{Campaignbox Russo-Turkish War (1877–1878)}}
+{{Russo-Ottoman War Series}}
+}}
+
+The '''Great Eastern Crisis''' of 1875–78 began in the [[Ottoman Empire]]'s [[Rumelia|territories on the Balkan peninsula]] in 1875, with the outbreak of several uprisings and wars that resulted in the meddling of international powers, and was ended with the [[Treaty of Berlin (1878)|Treaty of Berlin]] in July 1878.
+
+It is also called {{lang-sh|Velika istočna kriza}}; [[Turkish language|Turkish]]: ''Şark Buhranı'' ("Eastern Crisis", for the crisis in general), ''Ramazan Kararnamesi'' ("Decree of Ramadan", for the [[sovereign default]] declared on 30 October 1875) and ''93 Harbi'' ("War of 93", for the wars on the [[Balkans|Balkan peninsula]] between 1877–78, referring in particular to the [[Russo-Turkish War (1877–78)|Russo-Turkish War]], the year 1293 on the Islamic [[Rumi calendar]] corresponding to the year 1877 on the [[Gregorian calendar]])
+
+==Background==
+{{further|Eastern Question}}
+[[File:Fred. W. Rose The Avenger An Allegorical War Map for 1877 1877 Cornell CUL PJM 1080 01.jpg|thumb|The Avenger: An Allegorical War Map for 1877 by Fred. W. Rose, 1872: This map reflects the "Great Eastern Crisis" and the subsequent Russo-Turkish War of 1877–78.]]
+The state of Ottoman administration in the Balkans continued to deteriorate throughout the 19th century, with the central government occasionally losing control over whole provinces. Reforms imposed by European powers did little to improve the conditions of the Christian population, while at the same time managing to dissatisfy a sizable portion of the Muslim population. [[Bosnia Vilayet|Bosnia]] suffered at least two waves of rebellion by the local Muslim population, the most recent in 1850.{{cn|date=November 2017}} Austria consolidated after the turmoil of the first half of the century and sought to reinvigorate its longstanding policy of expansion at the expense of the Ottoman Empire. Meanwhile, the nominally autonomous, de facto independent principalities of [[Principality of Serbia|Serbia]] and [[Principality of Montenegro|Montenegro]] also sought to expand into regions inhabited by their compatriots. Nationalist and [[irredentism|irredentist]] sentiments were strong and were encouraged by Russia and her agents.
+
+===Ottoman economic crisis and default===
+On 24 August 1854,<ref>[http://www.dunyabulteni.net/haberler/223872/osmanli-devleti-ilk-kez-dis-borc-aldi Dünya Bülteni: "Osmanlı Devleti ilk kez dış borç aldı"]</ref><ref name=derinstrateji>[http://derinstrateji.wordpress.com/2014/02/24/tarih-osmanli-borclari-ve-duyun-u-umumiye-idaresi/ Derin Strateji: "Osmanlı Borçları ve Düyun-u Umumiye İdaresi"]</ref><ref>[http://www.yazarport.com/Yazi/Oku/385 Yazarport: "Kırım Savaşı ve İlk Dış Borçlanma (1854-1855)"]</ref><ref name=Ottomandebthistory>[http://gberis.e-monsite.com/categorie,osmanli-borclanma-tarihi-ottoman-debt-history,3219214.html History of the Ottoman public debt]</ref> during the [[Crimean War]], the Ottoman Empire took its first [[Ottoman public debt|foreign loans]].<ref>Douglas Arthur Howard: "The History of Turkey", page 71.</ref><ref name=mevzuat>[http://www.mevzuatdergisi.com/2006/04a/03.htm Mevzuat Dergisi, Yıl: 9, Sayı: 100, Nisan 2006: "Osmanlı İmparatorluğu'nda ve Türkiye Cumhuriyeti'nde Borçlanma Politikaları ve Sonuçları"]</ref> The empire entered into subsequent loans, partly to finance the construction of railways and telegraph lines, and partly to finance deficits between revenues and the lavish expenditures of the imperial court, such as the construction of new palaces on the [[Bosphorus]] [[strait]] in [[Constantinople]].<ref name=Ferguson>{{cite web|url=http://www.ft.com/cms/s/0/6667a18a-b888-11dc-893b-0000779fd2ac.html|title=An Ottoman warning for indebted America|author=[[Niall Ferguson]]|publisher=[[Financial Times]]|date=2 January 2008|accessdate=4 February 2016}}</ref> Some financial commentators have noted that the terms of these loans were exceptionally favourable to the [[United Kingdom of Great Britain and Ireland|British]] and [[Second French Empire|French]] banks (owned by the [[Rothschild family]]) which facilitated them, whereas others have noted that the terms reflected the imperial administration's willingness to constantly refinance its debts.<ref name=Ferguson/><ref>''Gold for the Sultan: Western Bankers and Ottoman Finance, 1856–1881'', by Christopher Clay, London, 2001, p. 30.</ref> A large amount of money was also spent for building new ships for the [[Ottoman Navy]] during the reign of Sultan [[Abdülaziz]] (r. 1861–1876). In 1875, the Ottoman Navy had 21 [[battleship]]s and 173 warships of other types, which formed the third largest naval fleet in the world after those of the British and French navies. All of these expenditures, however, put a huge strain on the Ottoman treasury. In the meantime, a severe drought in [[Anatolia]] in 1873 and flooding in 1874 caused famine and widespread discontent in the heart of the empire. The agricultural shortages precluded the collection of necessary taxes, which forced the Ottoman government to declare a [[sovereign default]] on its foreign loan repayments on 30 October 1875 and increase taxes in all of its provinces, including the Balkans.<ref name=mevzuat/><ref name=Ferguson/>
+
+===Uprisings and wars in the Balkans===
+The decision to increase taxes for paying the Ottoman Empire's [[Ottoman public debt|debts to foreign creditors]] sparked an [[#Chronology of the Great Eastern Crisis and its aftermath|outrage in the Balkan provinces]], which culminated in the Great Eastern Crisis and ultimately the [[Russo-Turkish War (1877–78)]] that provided independence or autonomy for the Christian nations in the empire's Balkan territories, with the subsequent [[Treaty of Berlin (1878)|Treaty of Berlin]] in 1878. The war, however, was disastrous for the already struggling Ottoman economy and the [[Ottoman Public Debt Administration]] was established in 1881, which gave the control of the Ottoman state revenues to foreign creditors.<ref name=Ferguson/><ref name="Sovereignty">{{cite web|last1=Krasner|first1=Stephen D.|title=Sovereignty: Organized Hypocrisy |url={{Google books |plainurl=yes |id=tHJ5m56sBX4C |page=135 }} |accessdate=26 August 2014 }}</ref> This made the European creditors bondholders, and assigned special rights to the [[Ottoman Public Debt Administration|OPDA]] for collecting various types of tax and customs revenues.<ref name=Ferguson/> During and after the Serbian–Ottoman War of 1876–78, between 30,000 and 70,000 Muslims, mostly Albanians, were expelled by the [[Armed forces of the Principality of Serbia|Serb army]] from the [[Sanjak of Niš|Sanjak of Niș]] and fled to the [[Kosovo Vilayet]].<ref>Pllana, Emin (1985). "Les raisons de la manière de l'exode des refugies albanais du territoire du sandjak de Nish a Kosove (1878–1878) [The reasons for the manner of the exodus of Albanian refugees from the territory of the Sanjak of Niš to Kosovo (1878–1878)] ". ''Studia Albanica''. '''1''': 189–190.</ref><ref>Rizaj, Skënder (1981). "Nënte Dokumente angleze mbi Lidhjen Shqiptare të Prizrenit (1878–1880) [Nine English documents about the League of Prizren (1878–1880)]". ''Gjurmine Albanologjike (Seria e Shkencave Historike)''. '''10''': 198.</ref><ref>Şimşir, Bilal N, (1968). ''Rumeli’den Türk göçleri. Emigrations turques des Balkans [Turkish emigrations from the Balkans]''. Vol I. Belgeler-Documents. p. 737.</ref><ref name=Batakovic1992>{{cite book|last=Bataković|first=Dušan|title=The Kosovo Chronicles|year=1992|publisher=Plato|url=http://www.rastko.rs/kosovo/istorija/kosovo_chronicles/kc_part2b.html}}</ref><ref name=Elsie2010>{{cite book|last=Elsie|first=Robert|title=Historical Dictionary of Kosovo|year=2010|publisher=Scarecrow Press|isbn=9780333666128|page=XXXII}}</ref><ref>Stefanović, Djordje (2005). "Seeing the Albanians through Serbian eyes: The Inventors of the Tradition of Intolerance and their Critics, 1804–1939." ''European History Quarterly''. '''35'''. (3): 470.</ref>
+
+==Aftermath==
+After the [[Treaty of Berlin (1878)|Treaty of Berlin]] in 1878, [[Austria-Hungary]] stationed military garrisons in the [[Bosnia Vilayet|Ottoman Vilayet of Bosnia]] and [[Sanjak of Novi Pazar|Ottoman Sanjak of Novi Pazar]], which formally ([[de jure]]) continued to be Ottoman territories. Taking advantage of the chaos that occurred during the [[Young Turk Revolution]] in 1908, [[Bulgarian Declaration of Independence|Bulgaria declared its formal independence]] on 5 October 1908. The following day, [[Bosnian crisis|Austria-Hungary unilaterally annexed Bosnia]] on 6 October 1908, but pulled its military forces out of Novi Pazar in order to reach a compromise with the Ottoman government and avoid a war (the Ottoman Empire lost the Sanjak of Novi Pazar with the [[Balkan Wars]] of 1912–1913.)
+
+In 1881, [[France]] [[Beylik of Tunis|occupied the Ottoman Beylik of Tunisia]], with the excuse that Tunisian troops had crossed the border into [[French Algeria|their colony of Algeria]], which also [[Ottoman Algeria|formerly belonged to the Ottoman Empire]] until 1830. A year later, in 1882, the [[British Empire]] [[Khedivate of Egypt|occupied the Ottoman Khedivate of Egypt]], with the pretext of giving military assistance to the Ottomans for putting down the [[Urabi Revolt]] (Britain later declared Egypt [[Sultanate of Egypt|a British protectorate]] on 5 November 1914, in response to the Ottoman government's decision to join [[World War I]] on the side of the [[Central Powers]].<ref>[http://wwi.lib.byu.edu/index.php/Treaty_of_Lausanne Articles 17, 18 and 19 of the Treaty of Lausanne (1923)]</ref>) It is worth noting that the Ottoman government had frequently declared the tax revenues from Egypt as a [[surety]] for borrowing loans from British and French banks.<ref name=derinstrateji/><ref name=mevzuat/> The Ottoman government had earlier [[Cyprus Convention|leased Cyprus to Britain]] in 1878, in exchange for British support at the [[Congress of Berlin]] in the same year (Cyprus was later annexed by Britain on 5 November 1914, for the same aforementioned reason regarding the Ottoman participation in World War I.<ref>[http://wwi.lib.byu.edu/index.php/Treaty_of_Lausanne Articles 20 and 21 of the Treaty of Lausanne (1923)]</ref>) By obtaining Cyprus and Egypt, Britain gained an important foothold in the East Mediterranean and control over the [[Suez Canal]]; while France increased its lands in the West Mediterranean coast of [[North Africa]] by adding Tunisia to its empire [[French protectorate of Tunisia|as a French protectorate]].
+
+==Chronology of the Great Eastern Crisis and its aftermath==
+{{commons category}}
+*[[Herzegovina uprising (1875–77)]]
+*[[April Uprising]] (1876)
+*[[Razlovtsi insurrection]] (1876)
+*On June 28, 1876, Montenegro and Serbia declared war on the Ottoman Empire.
+*[[Serbian–Ottoman War (1876–1878)]]
+*[[Montenegrin–Ottoman War (1876–78)]]
+*[[First Constitutional Era]] (1876-1878)
+*[[Constantinople Conference]] (1876–77)
+*[[Russo-Turkish War (1877–1878)]]
+**[[Romanian War of Independence]]
+**[[Provisional Russian Administration in Bulgaria]]
+**[[Treaty of San Stefano]] (1878)
+*[[Expulsion of the Albanians 1877–1878]]
+*[[Congress of Berlin]] (1878)
+*[[Kumanovo Uprising]] (1878)
+*[[1878 Greek Macedonian rebellion]]
+*[[Epirus Revolt of 1878]]
+*[[Cretan Revolt (1878)]]
+*[[Austro-Hungarian campaign in Bosnia and Herzegovina in 1878]]
+*[[Kresna–Razlog uprising]] (1878)
+
+===Treaties===
+*[[Reichstadt Agreement]]
+*[[Budapest Convention of 1877]]
+*[[Treaty of San Stefano]]
+*[[Cyprus Convention]]
+*[[Treaty of Berlin (1878)]]
+
+===Aftermath===
+*[[Armenian Question]]
+*[[League of Prizren]] (1878)
+**[[Battles for Plav and Gusinje]] (1879–1880)
+*[[Pact of Halepa]] (1878)
+*[[Dual Alliance (1879)]]
+*[['Urabi revolt]] (1879–1882)
+*[[Brsjak revolt]] (1880–1881)
+*[[French conquest of Tunisia]] (1881)
+*[[Austro–Serbian Alliance of 1881]]
+*[[Convention of Constantinople (1881)]]
+*[[Herzegovina Uprising (1882)]]
+*[[British Occupation of Egypt]] (1882)
+*[[Austro-Hungarian–German–Romanian alliance]] (1883)
+*[[Timok Rebellion]] (1883)
+*[[Bulgarian Crisis (1885–88)]]
+
+==References==
+{{reflist}}
+
+== Further reading ==
+* {{cite journal|title=Unprinted documents: Russo-British relations during the Eastern Crisis (VIII. The eve of the armistice)|url=https://archive.org/stream/in.ernet.dli.2015.185585/2015.185585.The-Slavonic-Reviewvol64#page/n215/mode/2up|journal=The Slavonic and East European Review|date=November 1946|volume=25|issue=64}}
+* {{cite journal|title=Unprinted documents: Russo-British relations during the Eastern Crisis (VIII. On the edge of war)|url=https://archive.org/stream/in.ernet.dli.2015.185585/2015.185585.The-Slavonic-Reviewvol64#page/n539/mode/2up|journal=The Slavonic and East European Review|date=April 1947|volume=25|issue=65}}
+* Anderson, M.S. ''The Eastern Question, 1774–1923: A Study in International Relations'' (1966) [https://www.questia.com/library/7391310/the-eastern-question-1774-1923-a-study-in-international online]
+*{{cite book|last=Branković|first=Slobodan|title=Great eastern crisis and Serbia, 1875-1878|url={{Google books |plainurl=yes |id=cmjVPgAACAAJ }} |year=1998|publisher=Svetska srpska zajednica, Institut srpskog naroda}}
+* {{cite encyclopedia |first=David M. |last=Goldfrank |title=Berlin, Congress of |encyclopedia=Encyclopedia of Russian History |year=2003 |isbn=978-0028656939 |editor-last=Millar |editor-first=James R. |publisher=Macmillan Reference USA }}
+*{{cite book|last1=Király|first1=Béla K.|last2=Rothenberg|first2=Gunther Erich|title=War and Society in East Central Europe: Insurrections wars and the eastern crisis in the 1870s|url={{Google books |plainurl=yes |id=M2HfAAAAMAAJ }} |year=1985|publisher=Brooklyn College Press|isbn=978-0-88033-090-9}}
+* Langer, William L. ''European Alliances and Alignments: 1871-1890'' (1950) pp 151-70. [https://archive.org/details/in.ernet.dli.2015.237096 Online]
+* {{cite book |last=Millman |first=Richard|title=Britain and the Eastern question, 1875–1878 |url=https://books.google.com/books?id=70aaAAAAIAAJ |year=1979 |publisher=Clarendon Press |isbn=978-0-19-822379-5 }}
+* {{cite book |last=Medlicott |first=W. N. |authorlink=W. N. Medlicott|year=1963 |title=The Congress of Berlin and After: A Diplomatic History of the Near East Settlement, 1878–1880 |edition=Second |location=London |publisher=Frank Cass }}, Focus on the aftermath.
+* Munro, Henry F. ''The Berlin congress'' (1918) [https://archive.org/details/cu31924027836869 online free], 41pp of text, 600 pp of documents
+* {{cite book |last=Taylor |first=A. J. P. |authorlink=A. J. P. Taylor |title=The struggle for mastery in Europe: 1848–1918|url=https://books.google.com/books?id=lw0UKQEACAAJ |year=1954 |publisher=Oxford University Press }}
+* {{cite book |editor-last1=Yavuz |editor-first1=M. Hakan |editor-first2=Peter |editor-last2=Sluglett |title=War and Diplomacy: The Russo-Turkish War of 1877–1878 and the Treaty of Berlin |publisher=University of Utah Press |year=2012 |isbn=978-1-60781-150-3 }}
+
+{{Great Eastern Crisis}}
+
+[[Category:Great Eastern Crisis| ]]
+[[Category:1870s in the Ottoman Empire]]
+[[Category:Rebellions against the Ottoman Empire]]
+[[Category:Ottoman period in the history of Bosnia and Herzegovina]]
+[[Category:Politics of the Ottoman Empire]]
+[[Category:Diplomacy]]
+[[Category:History of the Balkans]]
+[[Category:History of international relations]]
+[[Category:Ottoman Empire–Russian Empire relations]]
+[[Category:Austria–Turkey relations]]
+[[Category:National questions]]
+[[Category:1870s conflicts]]
+
diff --git a/2018/history-words.txt b/2018/history-words.txt
new file mode 100644 (file)
index 0000000..ea0ee44
--- /dev/null
@@ -0,0 +1,8197 @@
+conditions
+qadis
+georges
+closing
+mamluk
+prousis
+bismarck
+schilder
+notables
+neo
+obey
+wounded
+drop
+document
+bisharin
+watered
+meter
+defend
+kate
+prompted
+emigrations
+stylized
+petrograd
+tory
+superiority
+oeqc
+illustrate
+currents
+devotion
+sustains
+burke
+jewish
+impartiality
+substantial
+evlenmesi
+divisions
+indemnity
+influenced
+enterance
+suited
+minutes
+metrical
+straits
+movement
+decisions
+representative
+nemesis
+son
+fifteen
+styles
+conflagration
+mubic
+pera
+composer
+pp
+shefketil
+guardian
+produced
+turques
+resorted
+resnum
+upswing
+diplomacy
+gallipoli
+org
+overseas
+bureaucratic
+van
+participation
+heroic
+padishah
+invincibility
+museum
+creating
+crnojevici
+abdulmejid
+artillery
+visible
+legion
+education
+refimprove
+modifications
+politikalar
+poland
+publicly
+offered
+walter
+avner
+empirerussia
+zealot
+westman
+agreed
+homosexuality
+choose
+ankaragucu
+author
+armistice
+conducted
+cathie
+wide
+newspaper
+distortion
+allowing
+dictated
+seton
+victorious
+allen
+unpayable
+connotes
+f
+contrary
+southward
+basis
+associated
+systematic
+greeuoft
+maximum
+deal
+indian
+unseat
+sky
+segregated
+sans
+nbsp
+armorial
+uu
+townspeople
+subjugated
+verses
+nearly
+hatred
+neighbouring
+hold
+surge
+banknote
+reminded
+exception
+serb
+guaranteed
+lsst
+stronghold
+fl
+similarities
+tradition
+shared
+maintenance
+manufactures
+ginzburg
+bayazid
+emigrnonm
+pllana
+maghreb
+castlereagh
+tezcan
+yyqc
+reality
+sultanvahideddin
+ashot
+documentary
+cannon
+nedim
+marauders
+swimming
+owner
+descriptions
+citizen
+detail
+up
+doctrine
+men
+default
+petain
+orenburgsky
+introduce
+guards
+restore
+cihan
+violent
+takeover
+khanate
+igc
+andrew
+sevket
+seafaring
+loris
+hist
+commonly
+recovering
+benefit
+languages
+due
+amos
+size
+yes
+brill
+verlag
+intended
+christians
+gorkachov
+recruitment
+oslxybdgc
+suggestion
+wwi
+claims
+taille
+itself
+genetic
+laborious
+semiprotected
+update
+ybori
+entente
+caroline
+events
+revised
+breakup
+allowed
+reasoning
+suggested
+available
+games
+knihy
+knights
+poverty
+friday
+chechen
+intrel
+patterns
+clio
+prague
+conservatism
+took
+cases
+determined
+shah
+epidemics
+tombs
+conference
+research
+auspicious
+metropolitan
+monasteries
+mcmeekin
+onepage
+establishment
+progress
+transferred
+schumacher
+tu
+bertold
+running
+respite
+kerensky
+output
+spain
+bolshevik
+virtu
+girolamo
+produce
+ac
+pattern
+answered
+macedonia
+vatikiotis
+victors
+basibozuk
+nationality
+reigning
+lorenzo
+unsettling
+concert
+privileges
+accordingly
+quotations
+waddington
+krupp
+unjust
+sk
+clout
+flags
+disestablished
+engagement
+engels
+pumping
+saffet
+better
+gusinje
+ultimately
+zeal
+actual
+armenian
+crusades
+muteferrika
+reinforce
+rugs
+next
+loans
+constant
+sowed
+news
+greco
+frustrated
+butterworths
+alevi
+foreign
+threatening
+guard
+greeted
+underlying
+counted
+skierniewice
+petition
+apogee
+anachronism
+cox
+predestination
+columbus
+americas
+zahvat
+bought
+eventual
+aim
+academia
+safety
+heaviest
+mob
+adherent
+domain
+toc
+decisively
+imber
+investors
+sister
+dodwell
+principalities
+accessdate
+orders
+adhere
+fronts
+crimean
+trans
+alarmed
+byzantines
+barou
+furious
+restive
+ottomans
+abazi
+of
+rely
+competitors
+suppressed
+index
+tariffs
+persuaded
+group
+property
+plovdiv
+unlike
+ethno
+ion
+john
+diversion
+grivickogo
+done
+magyar
+serio
+jgfnbkhg
+colossal
+refused
+moreover
+favour
+mesopotamia
+szathmary
+amila
+editions
+navboxes
+naroda
+shift
+ottomanism
+despotate
+econ
+communist
+educated
+cromwell
+pitting
+vassilika
+results
+lead
+capital
+passes
+educational
+decadence
+centered
+alimony
+falconet
+ferraro
+deaths
+vvympvtsc
+captives
+practiced
+lacking
+consensus
+noblemen
+formalized
+pasha
+psychoanalysis
+recruited
+railroads
+iraq
+immediately
+responsibility
+solid
+raids
+radezky
+regulation
+wp
+samtskhe
+crime
+rapidly
+fell
+wahhabis
+reminiscences
+tulp
+statistical
+qur
+supporter
+shadowplay
+barely
+atlantik
+journalism
+set
+millionaire
+conceded
+noarchive
+service
+matsuki
+stalin
+sympathy
+levha
+welsh
+express
+purposes
+bozhidar
+presence
+assaults
+venetians
+tales
+dedicated
+mostly
+direction
+armenia
+sounds
+attitude
+liman
+asia
+contemporary
+equivalents
+rizaj
+osvoboditelna
+safvet
+hellenic
+elections
+partitioning
+vasilika
+secession
+caption
+households
+september
+complains
+berna
+questia
+appointed
+profited
+macmillan
+melting
+motion
+honour
+decades
+commerce
+ic
+hanging
+wrote
+specifically
+order
+sofia
+substitute
+parlements
+widely
+ruined
+koprulu
+pernicious
+battles
+information
+loc
+categories
+pass
+mudros
+inmc
+lybyer
+protestants
+accomplishing
+encouraged
+confluence
+mainly
+mod
+kosovo
+prince
+creator
+clustering
+agnew
+incapable
+mimar
+yeshiva
+wahhabi
+complied
+keen
+thj
+eventually
+sanstef
+acquisition
+defiling
+statistics
+writing
+mss
+kara
+resurfaced
+viable
+mirror
+expecting
+backed
+speakers
+swept
+boj
+fountains
+deported
+rococo
+patrol
+vladimir
+vaughn
+legislative
+abuzz
+der
+club
+obvious
+goodman
+catalan
+pan
+monarchy
+upon
+accurate
+elevated
+enacted
+formented
+dominate
+melodic
+experiment
+permitted
+yi
+declarations
+important
+lik
+sean
+latest
+defied
+utrecht
+bureaucracy
+conflicted
+mesa
+major
+ghi
+combined
+similarly
+economy
+asylum
+list
+translated
+functions
+erupted
+above
+andrassy
+ornamented
+appropriate
+called
+intrusion
+auto
+slaves
+contraction
+attempts
+citizens
+terrall
+vii
+circa
+post
+withdrawal
+imperialism
+specifications
+jan
+flagdeco
+operated
+und
+overlook
+tsarist
+govern
+tambourine
+compatriots
+complications
+calculated
+official
+prevalent
+ochistit
+jurisprudence
+politician
+vartanyan
+extend
+chronicles
+razvoiul
+pursued
+justinian
+efendi
+banning
+address
+srpska
+otmkanun
+close
+abdication
+ajp
+edge
+populations
+katib
+file
+confiscated
+desprey
+foreclosed
+celebrated
+oud
+stage
+demanded
+eizo
+goston
+macfie
+es
+beginnings
+argues
+pogrom
+insecurity
+censuses
+serf
+presidency
+diphis
+proletariat
+asp
+allies
+alba
+bradbury
+ivory
+nikolai
+disparaging
+sociology
+track
+nicknamed
+morava
+disaster
+bursa
+purge
+carbonari
+reaching
+goresutan
+nor
+advanced
+nordic
+creditors
+u
+discarded
+prus
+adopt
+mathematics
+muqarnas
+hungariangermanromanian
+readily
+mills
+antagonize
+secondary
+havadis
+pointing
+members
+undue
+mundy
+sure
+closely
+entirety
+thoroughbred
+novibazar
+byu
+detachment
+ahmet
+stillman
+qualities
+hastened
+bei
+competences
+similar
+opposing
+explorations
+ignoring
+commonscat
+muahedesi
+ukrainian
+yazbak
+bid
+hypothetical
+barnes
+league
+davidson
+fought
+hostage
+forceful
+longstanding
+derinstrateji
+calvinism
+trade
+doja
+hadith
+build
+latin
+besiktas
+gr
+demand
+blow
+neurocirugia
+publishers
+reasserting
+aknc
+historian
+years
+accused
+crossroads
+chancery
+oakes
+becker
+scourge
+austrian
+mere
+cavaliers
+pjm
+immense
+dear
+draft
+fatally
+o
+organizing
+speeches
+machine
+fernand
+romaniei
+event
+greeks
+average
+variety
+science
+alone
+keziban
+trial
+densities
+fair
+boshtml
+noise
+appreciate
+archives
+liva
+heinrich
+british
+served
+krasner
+cleanse
+somewhat
+dissatisfaction
+topic
+pot
+casualty
+horror
+dq
+granted
+txt
+handbook
+persecuting
+objects
+loss
+undertaken
+walker
+horton
+pleven
+managing
+really
+denouncement
+concordat
+exodus
+encyclopdia
+squadrons
+bazouk
+oku
+colony
+prizrenit
+battalion
+minimum
+firsthand
+middleeast
+jovan
+opportunity
+ends
+cooperation
+bryan
+kulichki
+briefly
+historiography
+fuzuli
+public
+aldi
+second
+image
+dobruja
+mountains
+gheorghe
+hookah
+truth
+resist
+grigol
+shumen
+delegated
+citizenship
+liege
+dutch
+formally
+danube
+slovenes
+posed
+suleyman
+place
+revisions
+ox
+folk
+presented
+dunya
+presided
+emergence
+relative
+probably
+mid
+trained
+postal
+anglo
+deist
+amended
+exposing
+detrez
+libraries
+justification
+hess
+intercultural
+void
+gukasov
+ever
+czar
+murder
+pure
+life
+eucharist
+hospitals
+epirus
+katalog
+dwelling
+explain
+manuscript
+good
+traits
+wadysaw
+pres
+granta
+doleances
+paramilitary
+railway
+outside
+form
+retaking
+repressed
+zurich
+maritsa
+newspapers
+tanjimato
+normal
+conscripted
+diet
+urabi
+newly
+chancellery
+optimism
+deterred
+decembrist
+india
+unifying
+lambton
+instrumental
+combination
+sheikhdom
+p
+wnsfaaaamaaj
+overlords
+usually
+pavlovich
+belge
+propaganda
+demonstrably
+backing
+sedivy
+finland
+origin
+ukqeacaaj
+because
+human
+bowing
+neville
+mandatory
+symbiosis
+russoturkishwar
+fifteenth
+ney
+uthman
+solicited
+abated
+technical
+vassal
+tusan
+heretic
+edqaaqbaj
+rousse
+dagestan
+rztjr
+animates
+levee
+mussolini
+enabled
+previous
+crusade
+acad
+manner
+konstantin
+keftes
+kinross
+sketch
+carroll
+ones
+possibly
+daughter
+replaces
+referees
+here
+obtained
+zuhab
+westernmost
+imagining
+decorative
+castle
+nizam
+seegel
+descendant
+ved
+coordinating
+train
+addition
+realism
+fuad
+brief
+adventure
+purpose
+through
+institut
+dates
+unbroken
+edmund
+germans
+reform
+expected
+run
+google
+nantes
+others
+grounds
+unkyaru
+ellesmereportstandard
+height
+extension
+digitalbookindex
+pontoon
+led
+heat
+found
+advancing
+banner
+mowat
+double
+hayes
+eyes
+banding
+plaintiffs
+refgildea
+cossacks
+tarihi
+t
+ideologically
+adrianople
+plain
+btng
+adaptation
+concluding
+expeditions
+turkicism
+formidable
+sultan
+never
+ofq
+senate
+staff
+excluded
+wounds
+prut
+pressures
+locale
+khrimian
+patent
+interchangeably
+perspective
+enjoy
+efficiency
+children
+ju
+lynda
+matrakc
+deteriorate
+corresponding
+godolphin
+rudimentary
+mtholyoke
+ea
+assured
+committed
+georgia
+somaliland
+precluded
+avant
+resign
+description
+oversee
+comintern
+tb
+ethnic
+bein
+squadron
+concerned
+karakoy
+nizhny
+ivanovo
+pleaded
+age
+resentment
+profit
+city
+furst
+revenue
+waves
+sayfa
+chicago
+liberties
+success
+ibrahim
+start
+fisher
+latter
+flexible
+marking
+location
+disestablishments
+sides
+governments
+cleansing
+ota
+flourishing
+older
+handled
+defeated
+jarre
+orbit
+rise
+azov
+hasan
+censure
+revolutions
+amounted
+gunther
+dominance
+stages
+illuminating
+makovsky
+request
+egitim
+margin
+organised
+artists
+practices
+menning
+surname
+monitor
+einstein
+centrifugal
+cheka
+kind
+kings
+serbia
+bucharest
+zotov
+dignitaries
+comparable
+leadership
+symbolist
+organic
+lyric
+unlimited
+hisarian
+curtain
+command
+suppression
+methods
+bands
+cn
+nowrap
+rastko
+sergej
+fatat
+brsjak
+khotyn
+rare
+present
+flourished
+regarding
+islam
+syrie
+geographic
+stake
+session
+banking
+strengthen
+superseding
+notion
+scholar
+disregard
+erzerum
+weakened
+won
+obviously
+convenient
+heritage
+advances
+tarihimiras
+bairoch
+observations
+fledgling
+ref
+chiflik
+universally
+closure
+vain
+skobelev
+resolved
+mein
+exclusive
+discuss
+engendered
+opened
+leonardo
+pressure
+ruth
+ineffective
+andreas
+aristocracy
+km
+created
+schleswig
+civilis
+praise
+wall
+rice
+jp
+hypocrisy
+schem
+delegates
+successful
+continuing
+bones
+bolesaw
+i
+rakia
+nevertheless
+claimed
+novelist
+inventor
+directly
+reduta
+compromised
+side
+dolmabahce
+abdulhamid
+hus
+nizamiye
+manchurian
+battenberg
+tamu
+roma
+diplomat
+personal
+ambassadors
+concessions
+mesut
+name
+link
+depicting
+ol
+mention
+persisted
+contracts
+pertain
+marxism
+certainly
+universiteit
+stefano
+patrilineal
+originating
+marquess
+unrest
+spiritual
+painting
+xiixvii
+undermine
+passed
+abandoned
+rontgen
+sega
+alignments
+herzegovinian
+per
+manti
+importance
+conquer
+sule
+failures
+redrawing
+cauldron
+settlers
+mixing
+necla
+both
+blockade
+molotov
+florentine
+dubious
+nazir
+manual
+despite
+fenerbahce
+seq
+extent
+ulkuspor
+giritli
+piedmont
+pilsen
+schlieffen
+pagan
+staging
+protectors
+turmoil
+tatars
+reflist
+woodrow
+macgahan
+unlikely
+participated
+alvarez
+higher
+grandstanding
+assisted
+conquering
+st
+few
+populist
+likely
+rationalism
+planned
+excessive
+lang
+assessed
+webtech
+persians
+esad
+xxxii
+oliver
+inserted
+tsk
+taylor
+geoffrey
+extols
+decembrists
+madh
+beirut
+martin
+kennedy
+bernhard
+living
+andrea
+exaggeration
+informed
+discouraged
+coffeehouses
+change
+courts
+resurrect
+ayastefanos
+stopped
+pavel
+industries
+hand
+intervention
+hunkar
+stipulated
+hours
+reconciled
+norman
+always
+communistic
+trt
+remain
+month
+among
+kurdistan
+aaaaaaiaaj
+illumination
+say
+thirds
+algeciras
+seas
+penal
+albanais
+capita
+argue
+muhayyelat
+imparatorlugu
+turk
+locality
+occupying
+expansionism
+outcome
+initiating
+separation
+ending
+controversy
+create
+concept
+balancing
+terminology
+policy
+distribution
+vladimirovich
+become
+eleskirt
+amounting
+stream
+pamuk
+coffee
+tacit
+braque
+reparations
+nearby
+incunabula
+masked
+mansel
+convening
+arise
+leg
+principal
+bukhara
+grandwar
+broker
+ability
+report
+zgg
+leyli
+span
+postwar
+properly
+longmans
+murat
+provide
+writings
+ports
+status
+jacques
+alam
+mbi
+merchants
+qushji
+niccolo
+verification
+lowry
+conquest
+voortrekkers
+opium
+disambiguation
+grew
+kofte
+volume
+face
+mobilization
+suit
+unilaterally
+promise
+argument
+millett
+culminating
+anschluss
+liunion
+sec
+chartism
+course
+web
+corporative
+turcs
+dash
+wikipedia
+inaccurate
+english
+couder
+winning
+narrative
+plenum
+races
+jure
+geography
+dede
+candide
+schuster
+difficulty
+remove
+involvement
+affirmed
+csmhit
+husain
+tried
+illuminated
+indicative
+my
+need
+palmerston
+gocleri
+eli
+enlightenment
+perpetrators
+eliminated
+plans
+slavism
+scientist
+lowering
+herzegovinians
+defeating
+astrology
+bath
+fields
+quarter
+joffre
+enika
+bazaar
+performing
+must
+reconquering
+beylik
+kitab
+positions
+retreating
+pain
+vito
+desire
+correspondents
+austro
+desperation
+settled
+drury
+ellesmere
+bey
+political
+will
+contast
+inspired
+involving
+bring
+behavioral
+bohemian
+predicted
+sources
+stephano
+summary
+may
+benjamin
+learnt
+poj
+decriminalization
+prefer
+dogubeyazt
+mediterranean
+fashion
+utah
+statement
+census
+ayran
+myriad
+rifles
+brings
+participants
+administrative
+neurosurgeons
+pacific
+istocna
+preceded
+seized
+valuing
+ucl
+shiraz
+kemal
+totally
+tezad
+zonaro
+characterized
+ubri
+damat
+ethnicity
+lauren
+tide
+structural
+have
+founded
+occasions
+individually
+interfere
+borclanma
+extremely
+degrading
+stressing
+habits
+recorded
+process
+toured
+alpha
+applied
+seeking
+turchin
+effects
+maloy
+accepting
+divan
+nerses
+albrecht
+undoubtedly
+enable
+further
+scottish
+hereditary
+te
+hijra
+galvanized
+calamitous
+systematically
+notably
+mustafa
+miroslav
+coord
+william
+horseman
+coming
+rivals
+enderun
+sgartthzbg
+concise
+yusuf
+scholars
+msu
+xm
+roman
+haidamaka
+wave
+linked
+looking
+chronos
+effectively
+steps
+vucinich
+romania
+personally
+presumed
+imported
+illustrated
+goering
+bloodless
+sarma
+symbol
+baklava
+destruction
+mecca
+ignatius
+kararnamesi
+advantage
+confrontation
+return
+effective
+nascent
+monsieur
+breeches
+ensuing
+skender
+pers
+buturovic
+le
+mani
+austriahungary
+sexual
+valign
+transliterated
+frucht
+invaded
+kunt
+lewis
+selected
+roads
+disappointed
+exceptions
+dokumente
+plainurl
+stepan
+forward
+suitable
+epidemic
+suggestions
+scorched
+needs
+kitchens
+fascism
+ems
+usa
+establishing
+punch
+constitutional
+acts
+crushed
+telekomhistory
+svishtov
+responses
+ways
+weather
+reynolds
+muslims
+interpretation
+outnumbered
+easily
+transport
+favoring
+violating
+where
+divided
+permanently
+wikt
+saudiaramcoworld
+irredentism
+her
+whole
+pte
+feels
+circular
+style
+bas
+alphabet
+tsesarevich
+goldfrank
+align
+contest
+deputy
+taking
+reformist
+argonne
+prolonged
+kitay
+driven
+competing
+raphael
+underground
+retain
+leslie
+renegades
+supported
+clear
+year
+cemal
+raid
+safawid
+emerged
+tripoli
+autumn
+tells
+manor
+berlinski
+far
+timepieces
+bibliographies
+fund
+palanka
+palaces
+corn
+losses
+islands
+kill
+without
+emblem
+enclosure
+tripolitania
+commanders
+manifesto
+feudalism
+banned
+parted
+mahumd
+diminish
+endorsed
+fall
+show
+suraiya
+melody
+word
+dimension
+smaller
+mobilier
+al
+saj
+company
+ebru
+dominion
+munro
+mehmet
+designs
+sustain
+equality
+specialized
+kolkhideli
+xiv
+missile
+lack
+bilgi
+gulag
+reforms
+hero
+cumhuriyeti
+encompass
+incident
+raise
+overarching
+cause
+constituency
+reformers
+karsyaka
+zone
+launay
+existence
+fojnica
+uncensored
+yz
+pope
+telekom
+vannovsky
+rational
+persianate
+roumania
+gatesofconst
+int
+objections
+upset
+distinctively
+sovarm
+are
+urged
+motto
+islamized
+declaring
+first
+architecture
+frank
+elected
+wood
+artvin
+hired
+corners
+money
+twilight
+webarchive
+animosity
+monderusse
+beuve
+renaissance
+threatened
+managed
+oxfordislamicstudies
+antony
+scenario
+inalcik
+collar
+judicial
+borclar
+muzaffar
+syrian
+influxes
+saliha
+japanese
+uphold
+manoeuvres
+repulsed
+independenta
+khanates
+nkvd
+fr
+meant
+insistence
+founding
+york
+dli
+eyck
+revealed
+priest
+completed
+additional
+contexts
+challenges
+louvain
+mellah
+recapture
+university
+sog
+kriza
+schlo
+aksin
+vicious
+surrendered
+institutional
+inhabitant
+speech
+resolving
+bjaaaamaaj
+endured
+middle
+guerrilla
+peninsular
+sardinia
+jacob
+influential
+christine
+dante
+shaken
+replaced
+placed
+afroeurasia
+campbell
+advance
+begin
+savas
+resources
+frary
+companies
+marched
+barbara
+turktelekom
+gunduz
+marriages
+traditionalists
+wilder
+institutions
+prizren
+impacted
+huguenots
+il
+nationally
+fighting
+culture
+outsiders
+ailing
+q
+stephen
+storming
+unequaled
+ornately
+is
+elaborated
+choosing
+procedures
+sword
+decaying
+saatabago
+overland
+explains
+gibbon
+absolute
+madrasas
+miniature
+vartan
+paul
+before
+cahiers
+suspicion
+considerably
+occupation
+architect
+bard
+transforming
+convert
+associations
+angles
+nisan
+newton
+intermittent
+abqzaqaaiaaj
+jixcuxi
+glorious
+magyars
+kiraly
+lines
+forgotten
+playing
+staatspolizei
+old
+infirm
+vehement
+favoured
+esrar
+conventional
+consumer
+isanet
+stimc
+chose
+awakened
+themselves
+kuchuk
+rumi
+idealistic
+women
+unrestrained
+clarendon
+salisbury
+alexander
+improvements
+franz
+neighborhoods
+buildings
+orest
+amjad
+predecessors
+ensured
+tanzimat
+mke
+sort
+vizierate
+brown
+athos
+diseases
+willingness
+tayyare
+hardships
+convulsed
+expenditures
+basin
+attract
+liable
+borc
+zell
+radziwill
+efficient
+nobel
+dreikaiserbund
+nasional
+galib
+rivalry
+threaten
+manpower
+yale
+ds
+ott
+pg
+reconstructing
+clarify
+praised
+generation
+gathered
+sentiments
+test
+or
+burgeoning
+centre
+tasrif
+parts
+principality
+walls
+developments
+clad
+ethnographic
+initiative
+enosis
+britain
+powers
+attitudes
+health
+cooperative
+reign
+jvmqgaacaaj
+conflicting
+lokman
+purchaseform
+sh
+cfkq
+innocent
+occurred
+mcculloch
+each
+atlas
+festered
+peter
+vocabulary
+arta
+payable
+geza
+injury
+elicited
+ochakov
+letters
+purdue
+largest
+mw
+podilskyi
+rum
+servants
+context
+constructed
+intermittently
+calligraphic
+independently
+earliest
+beylerbeylik
+theological
+threw
+enhanced
+klemens
+banat
+meze
+klincksieck
+net
+riding
+practically
+id
+territory
+quickly
+benito
+karta
+oppose
+freiherr
+ii
+method
+controversial
+kasides
+sarcastic
+lejeune
+buhran
+most
+continuous
+astronomical
+occupy
+sold
+examples
+drought
+geared
+kissinger
+government
+classes
+subjects
+heirs
+idaresi
+machiavellian
+censors
+barkey
+prior
+why
+ikmqrtp
+southwest
+stew
+stationery
+prussiamet
+cross
+fort
+working
+sacrament
+ruf
+limitations
+announced
+nl
+servile
+accomplished
+maritime
+gratitude
+followed
+thyme
+wilde
+exarch
+batou
+ehst
+cmjvpgaacaaj
+resat
+creations
+see
+timurid
+impeached
+stripes
+nice
+manchuria
+politburo
+muhacir
+proclamation
+land
+yazarport
+balkanhistory
+rothenberg
+until
+submission
+shore
+medlicott
+nizami
+rene
+house
+lasted
+anatolia
+heir
+fixed
+stabilisation
+leon
+debt
+phillips
+records
+impending
+moni
+theses
+northern
+contained
+reviews
+observing
+openlibrary
+gravest
+usak
+correspondent
+own
+rembrandt
+safavids
+magistrate
+exclusion
+sudetenland
+redraw
+exit
+suggesting
+dadiani
+boys
+keskek
+bc
+instead
+iui
+sanction
+proposed
+floors
+protect
+hans
+day
+laid
+dating
+validation
+leave
+leidenuniv
+sipahi
+football
+building
+believed
+sick
+vojna
+toronto
+democrat
+harsh
+schlacht
+half
+expeditionary
+g
+hamish
+crush
+conclusion
+send
+da
+ferdinand
+abrogation
+raising
+desperate
+alawites
+complaints
+solved
+travels
+deserved
+abdulcelil
+zcc
+field
+provided
+planina
+assumptions
+promulgated
+termination
+corruption
+authenticity
+spencer
+forbes
+annually
+tauris
+relatively
+patchwork
+sztandar
+reduced
+segaert
+simmer
+strategical
+eastern
+moravian
+built
+leur
+w
+hjd
+baten
+knox
+lens
+para
+primarily
+stand
+surviving
+frasheri
+defenceofplevna
+simulate
+heliocentric
+tutor
+income
+counter
+task
+used
+autonomy
+calvin
+fqrrbumojcc
+economist
+globalism
+capitals
+southeast
+numa
+act
+work
+look
+former
+inventors
+advisors
+several
+octopus
+hosted
+toynbee
+distracted
+qanun
+alan
+thinking
+poorly
+fmt
+lacked
+hoping
+embassy
+conversely
+silent
+radonjic
+redoubt
+kokkalis
+warriors
+foroqhi
+invasion
+resented
+trees
+docs
+policies
+erich
+cerchez
+gregorian
+relate
+ud
+utf
+fuat
+format
+numbers
+seattle
+support
+credit
+move
+taken
+thracian
+wholesale
+precedents
+passive
+continental
+novel
+survived
+use
+happen
+search
+together
+warcorrespondenc
+archaeology
+baki
+texts
+define
+besides
+himmler
+traditions
+finance
+gascoyne
+signature
+boundary
+vulnerable
+sarajevo
+djvu
+rotten
+cdl
+loyalty
+seljuk
+role
+monetary
+concluded
+host
+europeanhistorytoc
+wafted
+unfit
+culinary
+hu
+seen
+suffered
+jstor
+abs
+movable
+revision
+croom
+hacivat
+ra
+relations
+save
+sehnaz
+nj
+lords
+absolutist
+differently
+partition
+istambul
+dependency
+differing
+powerless
+regardless
+effect
+plav
+reorganized
+detrimental
+decision
+unable
+popolo
+worship
+emancipate
+dying
+tie
+bore
+garrisoned
+genocides
+siege
+unguarded
+july
+compete
+flying
+hust
+forthcoming
+moravia
+francesco
+guarantees
+protection
+gardens
+ground
+dream
+correctness
+refugees
+dynastic
+michaelangelo
+periods
+yavuz
+cyprus
+spuler
+noting
+galileo
+integral
+femmes
+manoeuvering
+world
+hulling
+kut
+every
+gurko
+details
+domination
+stationed
+kez
+turkiye
+submitted
+dardanelles
+yazi
+vs
+crete
+discovery
+istorijat
+halsall
+seci
+loan
+englishman
+begun
+approached
+rates
+abolished
+fabry
+centred
+coast
+ill
+traditionwestern
+attacks
+legal
+ie
+monarchists
+midohato
+truly
+izzqc
+give
+ukraine
+sadullah
+ride
+overthrew
+battleship
+suzerain
+omission
+gif
+steppe
+stremma
+medieval
+understanding
+gnat
+dogma
+isma
+roots
+rule
+farmers
+nep
+arriving
+bosporus
+thin
+purely
+vilayets
+machiavelli
+successive
+establishments
+slavophile
+bastille
+preferable
+radical
+speed
+astrological
+sun
+defeats
+united
+ghukasyan
+promises
+reviewvol
+reflects
+those
+carpet
+kumanovo
+bedford
+industrial
+defenceofbayazet
+nuclear
+likes
+attractive
+serfs
+outgunned
+retreat
+kingdoms
+gymnastics
+sachedina
+gain
+unconscious
+comedy
+afghanistan
+dual
+meantime
+having
+ratified
+watt
+monarch
+engraver
+intervened
+current
+observed
+standard
+deemed
+granting
+ch
+identities
+larger
+strategically
+agreeing
+social
+entire
+has
+timothy
+sweden
+ottmani
+revolved
+widths
+foch
+arrangement
+series
+dynasties
+featured
+goriainov
+gunpowder
+shrank
+want
+sunni
+rlhd
+podgorica
+bavaria
+fancies
+hussites
+firing
+musahedat
+adapt
+meanings
+provoke
+troop
+sevres
+rhoads
+dergisi
+consisted
+images
+mothers
+high
+qjzydcxumfcc
+as
+introductory
+neighboring
+portuguese
+responsible
+conventions
+monasticism
+admirals
+vij
+famous
+consuls
+cholera
+druzemaronite
+emirate
+five
+inhabited
+soup
+flag
+pius
+facts
+sanjaks
+states
+bloody
+svat
+availability
+esztergom
+adj
+testimony
+steadily
+iia
+essays
+atkbmn
+caucasians
+ponomarev
+cul
+centuries
+originally
+constance
+kristallnacht
+dominated
+accusations
+gone
+kaiser
+receiving
+accompanying
+achieve
+impact
+holder
+careers
+levels
+its
+bible
+watchmaker
+distinguished
+abolition
+assembly
+strange
+turbine
+dividing
+sectionid
+informal
+possible
+masse
+wilson
+gavrilis
+principle
+energy
+greene
+biological
+drafted
+reconquista
+aiding
+controls
+appellate
+percent
+transoxiana
+reducing
+incorruptible
+communicate
+resurrection
+interregnum
+ranke
+western
+restored
+mount
+analogical
+pre
+counting
+fred
+szigetvar
+maurice
+advocating
+learned
+hungarian
+match
+room
+oghuz
+usury
+union
+adolf
+drina
+moral
+hapsburg
+reference
+faced
+generated
+protocol
+wrestling
+fatma
+burned
+behind
+chechnya
+fm
+zimbabwe
+who
+color
+turks
+were
+rothschild
+promulgation
+claude
+encyclopaediabri
+limited
+gyoruhane
+caliphs
+europeanconcerti
+lawrence
+karti
+inhibited
+terms
+naturally
+cement
+society
+nations
+descartes
+covers
+strongest
+enforce
+unification
+ussr
+undertakes
+xvi
+design
+maronites
+leila
+puritan
+cronologieen
+rolling
+sixth
+levni
+equilibrium
+wqgaacaaj
+crampton
+sapping
+artisans
+doria
+dominican
+hurewitz
+muhtar
+upload
+manoeuver
+inquiry
+bot
+territorial
+egyptian
+paving
+shameful
+moved
+accepted
+zajednica
+cu
+destroyed
+undone
+remaining
+refugies
+sea
+evolution
+harvest
+hindered
+acknowledged
+modernization
+storm
+ogg
+jettisoned
+mistake
+babylonian
+declared
+force
+development
+muskets
+battle
+turhan
+aef
+rallying
+nationalist
+yaynlar
+suzerainty
+eerdmans
+diminishing
+twentieth
+cubism
+went
+magazine
+laz
+prevented
+adjara
+it
+qhs
+boureki
+declined
+alternatively
+wc
+chisrich
+londrich
+matters
+focusing
+orlando
+bureau
+slave
+reverend
+tourism
+cannons
+pursuing
+assume
+macedonian
+nie
+gay
+replace
+reluctant
+worlds
+ships
+subsequently
+professor
+growth
+correspondence
+politics
+pita
+abkhazian
+devastated
+royalists
+engineer
+reopened
+fundamentalist
+persophone
+risks
+putting
+library
+reformer
+monarchies
+battleships
+iran
+psychology
+el
+honest
+matrix
+more
+non
+mark
+slow
+operation
+qizilbash
+quaritch
+augustus
+syria
+romence
+diminished
+grp
+millions
+alliance
+realistic
+instinct
+demographics
+uses
+lukas
+services
+navies
+boarding
+indicate
+again
+cwv
+syed
+peninsula
+chirot
+insolvency
+knightly
+perished
+furthermore
+might
+yesilkoy
+achilles
+incl
+findley
+contribute
+upper
+olti
+suez
+knee
+relied
+column
+fearing
+spread
+belatedly
+beybut
+hungaryrussia
+approach
+still
+beer
+impressionism
+constanta
+diversity
+tolerance
+shuttle
+metin
+true
+mistakes
+combatants
+milletts
+airlifts
+manned
+verrinder
+progenitors
+speros
+muratoff
+catherine
+fiscal
+book
+shkencave
+savoy
+annexation
+zubov
+rationalist
+feliksovich
+investiture
+zibik
+leuven
+traveled
+coat
+vinci
+golden
+end
+albania
+what
+truman
+philosophers
+odo
+plato
+persona
+desires
+display
+doctrines
+ishak
+arose
+eighteenth
+ludendorff
+lbyripyyfuoc
+rank
+flourish
+scale
+erder
+civilian
+convention
+falloden
+medical
+confined
+nadir
+minister
+deism
+zeta
+easternmost
+serbianottoman
+finally
+add
+co
+edelenyi
+characteristics
+arming
+cl
+rijn
+forming
+serafeddin
+port
+assigned
+melkonyan
+voyage
+georgian
+milosevic
+modernized
+after
+maronite
+modern
+studies
+murderous
+units
+trebizond
+edition
+nephew
+vienna
+broke
+dominic
+peacetime
+ragsdale
+sheep
+according
+currently
+villagers
+improving
+shores
+from
+bakanlg
+vernacular
+seriously
+seeing
+institute
+how
+gildea
+elite
+gorchakov
+milli
+prevention
+abdulhussein
+militarily
+th
+douglas
+bondholders
+wilhelm
+anti
+highly
+than
+senseless
+space
+mill
+tn
+read
+sent
+akabi
+noel
+awakening
+costs
+autarky
+provisions
+plainlist
+capitalist
+transactions
+strategy
+baks
+dominik
+prospered
+aceh
+masters
+halepa
+revanchist
+turn
+jesuits
+commune
+into
+akce
+mikhailovich
+williams
+mramor
+etd
+accord
+hejaz
+tangible
+sepoy
+potemkin
+hghho
+railways
+morning
+talents
+republics
+colmar
+societies
+yasnda
+humanitarianism
+suffering
+dennis
+antlasmas
+dardanelle
+tsardom
+circumscribe
+owen
+nowiki
+single
+mc
+gyula
+written
+stanko
+bulgarian
+setting
+oppression
+independent
+hamit
+monopoly
+ozoglu
+culturally
+sobieski
+did
+frederick
+bolstered
+alashkert
+tr
+initially
+dundar
+ummah
+wore
+put
+rubin
+ceded
+explosions
+karl
+sursockhouse
+genel
+successor
+muhammad
+concerns
+thousand
+across
+zushi
+membership
+ghazi
+inconsistencies
+repayments
+along
+soucek
+jutland
+tarnovo
+voiced
+factors
+financial
+librairie
+last
+mevzuatdergisi
+replacement
+ottomanmamluk
+presbyterianism
+sark
+khaled
+detente
+us
+pillnitz
+june
+coined
+recovered
+histor
+attacking
+nationalism
+pay
+jwsr
+yet
+tribesmen
+guild
+experimental
+gateway
+parliamentary
+coursesa
+yildiz
+def
+k
+despot
+flagcountry
+stiffening
+sports
+julydecember
+preveza
+militaristic
+connor
+reestablish
+apostolic
+habsburgs
+nevsehirli
+nicolas
+cirit
+embedded
+raska
+turkoman
+karpat
+vreto
+petersburg
+chosen
+rearranged
+kostantiniyye
+cornell
+superseded
+journey
+saud
+favorable
+characters
+atelier
+wartime
+exercises
+ozgundenli
+repelling
+javelin
+forebears
+ft
+tarih
+president
+resolve
+zimmermann
+bwvllkkpqtyc
+landings
+gb
+explore
+product
+fleet
+adjusted
+big
+embargo
+anagoria
+vehbi
+spawned
+historians
+bizarre
+plan
+thereafter
+collected
+snet
+worried
+part
+submarine
+battlefields
+han
+aesthetic
+related
+enactment
+wap
+reconstituted
+aryans
+capture
+hoped
+experience
+any
+dispute
+chamberlain
+humanism
+destroy
+tasks
+families
+lose
+baram
+other
+improvement
+severe
+manl
+dodecanese
+closer
+cc
+sectin
+galata
+faltering
+colonialism
+military
+condominium
+owned
+indigenous
+hugh
+arm
+karlowitz
+ideals
+tennis
+means
+galpin
+developing
+croat
+tezkireci
+consubstantiation
+collapse
+neurologist
+shapell
+intentionally
+equipped
+gonul
+regain
+render
+permission
+riza
+possessed
+notable
+require
+duke
+najden
+initiate
+cherkessians
+organisation
+impacting
+vam
+page
+revolutionary
+african
+internationally
+cultures
+liaison
+rich
+activists
+ben
+constitution
+blocked
+laissez
+guarantors
+ensure
+effort
+drawn
+kck
+mektebi
+essay
+selling
+model
+astronomer
+italy
+likened
+rosset
+resumed
+ministers
+carolina
+hvkk
+calendar
+orientation
+nationalists
+ongoing
+bill
+annual
+sevim
+steamships
+colloquium
+receive
+front
+integrity
+regime
+welcomed
+french
+afford
+zelenogorsky
+invited
+thessaloniki
+archivedate
+cleansed
+under
+levant
+import
+persuading
+grivitsa
+tigris
+rickety
+converts
+appealed
+family
+statehood
+bloomsbury
+ejz
+natives
+dinner
+amit
+erzurum
+significant
+kars
+too
+ohio
+parallel
+pustaka
+strict
+advantages
+feta
+prodanova
+coups
+classic
+nbc
+cole
+conquests
+foothold
+adhered
+possessions
+jane
+serbs
+conducting
+lake
+administration
+smyrna
+cornerstone
+refbegin
+furneaux
+misinterpreted
+cold
+chaucer
+relief
+ottomansafavid
+invention
+baptiste
+istanbulcityguide
+renounce
+diversification
+crucial
+historically
+superintend
+gabor
+photo
+bela
+viceroyalty
+invested
+falling
+spectacular
+allegorical
+elizabeth
+trusted
+pdf
+freedom
+mode
+kofta
+arkadiou
+eyalet
+kemence
+halil
+local
+cavour
+anton
+enriched
+qid
+elites
+ojs
+brothers
+distrusted
+range
+function
+polities
+posture
+breach
+distant
+analysts
+wealth
+peoples
+death
+incommoded
+new
+muge
+bqmaaaaiaaj
+template
+stock
+keep
+impossible
+piano
+founders
+defending
+dissolution
+parnassian
+concepts
+throne
+regulated
+knives
+duty
+hassan
+reported
+sbx
+killed
+barbarossa
+cartographer
+horrors
+sharp
+powersbritain
+struggle
+ns
+cordiale
+iii
+disastrous
+numerous
+longman
+ehqpagaaqbaj
+testy
+khrushchev
+harvnb
+travel
+competition
+had
+great
+pledged
+exports
+beylikleri
+san
+permitting
+balakian
+nationalities
+sudeten
+site
+communism
+supposedly
+heavy
+contain
+revolt
+cedid
+reprinted
+ignite
+tatar
+rak
+greek
+ptt
+emotion
+april
+planes
+abdulkerim
+diplomatic
+bernard
+kiepert
+classical
+successfully
+stallions
+ulema
+insurrections
+kaynarca
+corrupted
+simply
+economic
+weimar
+attacked
+yekaterinburg
+legacy
+difficulties
+crossing
+farming
+alliances
+nietzsche
+recruiting
+mufti
+fact
+nomad
+showrev
+aside
+kilim
+kuoaqaaiaaj
+right
+prolonging
+bypassed
+implemented
+violin
+consolidated
+external
+ankara
+rebirth
+annexed
+mudurlugu
+uprisings
+saz
+theatre
+permanent
+origyear
+asserting
+rebelliousness
+alison
+which
+germanism
+ian
+speaker
+capturing
+ghukasov
+include
+black
+water
+late
+sought
+shadow
+perceived
+impotence
+asiatic
+kabaday
+traditional
+phenomenon
+multitude
+board
+ended
+conqueror
+cretans
+monastery
+assassination
+pilots
+wapp
+brest
+racial
+ampthill
+learning
+mccauley
+pupils
+bohemia
+confederacy
+bullet
+density
+c
+famines
+cecil
+existed
+perpetually
+come
+oi
+fix
+citations
+seize
+threat
+phases
+control
+insurrectionsit
+vein
+rapid
+serbische
+contrast
+celebi
+helpful
+victor
+colonise
+think
+spoken
+fragile
+confirming
+nabiye
+mercantilism
+benefitted
+separate
+father
+head
+price
+abroad
+superman
+westernization
+peasant
+exposition
+atwebpages
+chamber
+institution
+satisfied
+verge
+osmanli
+prisoner
+fourier
+loyno
+marked
+russell
+daily
+resulted
+hupchick
+davies
+located
+announcing
+forum
+ali
+ties
+baku
+kwwdic
+kimball
+greatly
+problems
+usc
+succession
+ceu
+courtly
+target
+gulf
+tunisian
+caliph
+scepsis
+bozo
+small
+whatsoever
+underwent
+exile
+enlisted
+taswir
+obstacle
+surgical
+hunting
+factory
+yassa
+conscription
+via
+action
+symbolic
+increasingly
+ceding
+sub
+orbital
+ataturk
+capitulation
+sigmund
+df
+rather
+warships
+killing
+ordinary
+macin
+subjection
+babel
+bases
+ezel
+practical
+below
+acibe
+separated
+ideal
+iisg
+djordje
+patriarch
+game
+northwestern
+barrow
+court
+multiplying
+expanded
+repayment
+disbanded
+timar
+hst
+bookbinding
+navypedia
+parade
+line
+disappeared
+destinies
+them
+bonaparte
+circassian
+permit
+disraeli
+wage
+intervene
+to
+perfect
+scott
+initial
+expressed
+greenwood
+aewbg
+marne
+rebelling
+alternating
+agency
+sponsored
+proof
+des
+outraged
+palgrave
+dynasty
+scribd
+received
+philip
+scribes
+mihai
+png
+tribes
+treaties
+cultivated
+edu
+platonism
+kivshenko
+potapov
+reflect
+punishments
+shekvetili
+revising
+benefited
+dusan
+prelude
+grey
+fortifications
+forced
+economists
+technological
+hungary
+protected
+proverbs
+iskelesi
+comparative
+stat
+losing
+commonplace
+cuisines
+mystery
+hert
+sekban
+systems
+thirteen
+tughra
+ecclesiastical
+ottomansgradually
+swaths
+anayasa
+steiner
+evacuation
+matter
+osman
+administrators
+feb
+nb
+using
+literary
+pounds
+south
+aboutus
+capitalism
+dissidents
+consolidate
+indiana
+strong
+measured
+mountain
+sonuclar
+poetic
+take
+rendered
+austrians
+cessions
+composers
+washington
+hikayesi
+tore
+donations
+portions
+branch
+reestablishment
+places
+albanian
+monde
+ordered
+tribesincluding
+georgios
+issn
+seemed
+ipac
+hermann
+slavic
+bolsheviks
+feudal
+dissent
+allom
+maintaining
+offices
+adopted
+occupied
+devshirme
+batumi
+special
+inefficient
+surfaced
+docid
+muddet
+fortress
+switched
+albanians
+subject
+grave
+lazarev
+revivals
+millets
+xviixx
+bridging
+lowered
+italo
+regiomontanus
+explicit
+millar
+during
+oct
+predetermined
+fifty
+lasting
+ahead
+contributed
+kurd
+views
+inner
+strategic
+toledo
+arrangements
+mosques
+looked
+referencea
+saw
+tucker
+uyar
+dramatically
+directory
+thumb
+harmonious
+defense
+experiencing
+socialism
+gov
+ordusu
+crises
+beneath
+mameluke
+refugee
+theater
+aspects
+socialists
+off
+real
+ernst
+akinci
+hl
+saumarez
+food
+marriott
+congress
+sublime
+intricate
+druze
+america
+analogue
+construction
+cost
+strategies
+oxford
+kiriku
+reasons
+philippopolis
+eversley
+town
+voy
+marquis
+exercise
+jozef
+strike
+safeguard
+throw
+follows
+only
+tribe
+acted
+silesia
+hall
+moussaka
+severely
+necessary
+music
+transformations
+improved
+european
+missionary
+bank
+restoring
+release
+portal
+arabs
+king
+juxtaposition
+commenced
+ultimatum
+lest
+going
+died
+hamidian
+frequent
+six
+buna
+detachments
+onlinebooks
+door
+garibaldi
+montenegro
+jomini
+contract
+seyh
+baroque
+article
+amazon
+avoid
+maniere
+filtered
+bannan
+armenians
+publish
+majority
+moment
+bibcode
+intellectuals
+sequence
+wider
+gains
+pr
+station
+farce
+yfgvzdbkc
+james
+declare
+disrupting
+community
+spearheaded
+minsk
+boer
+increasing
+gradual
+unleash
+ga
+bosnian
+continent
+corpus
+pop
+sentence
+russianturkish
+paranoia
+laying
+benton
+volga
+gallagher
+deliberately
+fashoda
+transition
+native
+desert
+harry
+inhabiting
+realized
+dimensions
+throwing
+alexandrovich
+pt
+racing
+taner
+russia
+added
+variation
+strait
+sistine
+met
+israelite
+redcliffe
+preying
+materialism
+prestige
+challenge
+do
+arthur
+get
+marriage
+geographie
+responding
+em
+territoire
+studied
+said
+southern
+fatherland
+very
+barrier
+descendance
+formed
+civilization
+felicity
+safavid
+chlodwig
+nyworld
+defaultsort
+documents
+eve
+aggravated
+extinct
+defences
+border
+painters
+protestant
+influences
+pulled
+du
+pbyc
+htm
+romanians
+invented
+tibor
+lib
+personnel
+munich
+faith
+way
+depicted
+infrastructure
+consideration
+lw
+emphasized
+polishlithuanian
+application
+liberated
+periodic
+edward
+loyola
+cities
+uwpress
+yemeni
+weidenfeld
+paradigm
+ran
+continuity
+sluglett
+stravinsky
+modernisation
+archibald
+fearful
+druzes
+kebab
+prisons
+preliminary
+reception
+sagepub
+arkwright
+completely
+past
+decorated
+fd
+script
+came
+damned
+njegos
+zenta
+partof
+editura
+references
+exceeded
+delta
+gestapo
+orhan
+ristic
+hospitallers
+mauruoft
+edirne
+bankers
+repulse
+joining
+resemblance
+afghan
+whig
+unaided
+entitled
+unilateral
+outnumbering
+zartman
+eiffel
+ruling
+prosperous
+caucasian
+pact
+burners
+would
+drilling
+item
+equal
+lengthy
+campaigns
+apply
+downfall
+though
+aimed
+instability
+fourteenth
+insulation
+qoc
+nomads
+about
+iron
+turco
+avignon
+gripped
+bulgaric
+harper
+heard
+ceiling
+alternative
+difficult
+mejid
+kogalniceanu
+watch
+geographer
+intense
+underdevelopment
+flow
+defeat
+bringing
+remains
+sa
+topkap
+province
+realisation
+slavs
+mkrtich
+flight
+claim
+depends
+leiden
+inherited
+strongly
+ravenstein
+approval
+cape
+assertiveness
+training
+principally
+banalities
+samuel
+dolma
+fausto
+muraqqa
+finnish
+passarowitz
+denying
+bolgaria
+ideas
+forty
+austroserbian
+pashalik
+mfaarchive
+bayonets
+hfaaaamaaj
+algiers
+defensive
+hire
+proportion
+mobilizing
+sanatkaragucu
+eyub
+mined
+litografia
+liberators
+writers
+inter
+authors
+concern
+sergei
+migrations
+mayor
+sabanciuniv
+largely
+lalka
+husn
+aligned
+lira
+birth
+presentation
+countrystudies
+voltaire
+experienced
+roof
+ethnopolitics
+historical
+tif
+dmy
+eclectic
+sparky
+communists
+dynamic
+gutenberg
+supposed
+ss
+stratford
+aewaa
+petter
+beller
+malta
+devleti
+fiction
+wsacsac
+beyond
+daniel
+midhat
+hathitrust
+copies
+sukkcwaaqbaj
+immediate
+debate
+morrow
+mehmed
+number
+bartholomew
+broadly
+archduke
+kc
+editors
+isolated
+descended
+jurisdictional
+grigori
+mechanics
+phase
+alaeddin
+taxes
+transportable
+elsie
+refend
+symbols
+tlemcen
+academics
+defining
+entered
+replacing
+bronze
+consul
+eroberungs
+instituted
+tsarevich
+imperialistic
+y
+schuldner
+blum
+donald
+bademci
+kafadar
+emtqc
+celikten
+packed
+molodi
+entry
+freeing
+lutheranism
+nominally
+bessarabia
+nationwide
+edb
+abdyl
+chirotmccauley
+deleted
+fyuy
+polis
+member
+anarchist
+atlantic
+today
+preserved
+rusko
+skanderbeg
+jelali
+regent
+curtin
+bodin
+bratianu
+huguenot
+decree
+rhodesia
+illyustratsia
+extract
+valide
+george
+cs
+preparing
+humans
+mikulas
+stanford
+alfred
+patriotism
+conservative
+aggression
+night
+avenger
+industrialization
+east
+condemned
+measure
+standing
+straggled
+conceptualising
+desired
+agreement
+baron
+sadowa
+ocean
+russian
+totaling
+palabiyik
+viewpoint
+disadvantage
+bert
+venetian
+organization
+jointly
+unstable
+advocate
+klz
+justin
+din
+icinde
+derailed
+ruse
+lassalle
+arrested
+serefeddin
+waiting
+theottomans
+crowe
+paranoid
+commentators
+hope
+sid
+instruments
+carlo
+august
+growing
+rest
+nonwhite
+publisher
+divinely
+boat
+menace
+stable
+constituent
+later
+comparison
+competent
+ousting
+settlement
+voen
+melchior
+campaign
+sued
+gladstone
+whenever
+literature
+elderly
+enter
+specific
+ilklerin
+lisa
+galati
+sairi
+ptolemy
+landowners
+corti
+weakening
+steven
+haberler
+memoirs
+southeastern
+basically
+infantry
+re
+reading
+predatory
+amongst
+encouraging
+elders
+tries
+origins
+another
+hargreaves
+hovannisian
+thought
+constantinople
+machinery
+reich
+governed
+rousseau
+that
+stopping
+kainarji
+harvard
+gaining
+sarikamish
+rasputin
+holdings
+stone
+churches
+something
+http
+amount
+excuse
+rhyme
+verdun
+urbanization
+supplanting
+volunteers
+term
+cernat
+empty
+sheyh
+e
+doubled
+saudi
+car
+viii
+bruce
+ungheni
+consistently
+discussed
+benjamins
+collective
+transl
+ed
+solar
+congo
+hopes
+picasso
+identity
+intellectual
+ptolemaic
+budapest
+malarky
+captured
+pos
+harpercollins
+dishes
+romanticism
+quotation
+goal
+dhimmi
+viceroy
+fasc
+and
+seventeen
+denizciligi
+hstmilitaryrussoturkishwara
+wife
+sanitation
+sava
+drew
+majesty
+unfounded
+namely
+shartle
+armada
+disorder
+kartchen
+turkwar
+exploits
+beginning
+hodgkinson
+bulteni
+murphey
+ages
+predominantly
+vast
+suspension
+volumes
+unity
+alexandra
+easy
+franco
+judaism
+iberian
+centripetal
+maria
+bodies
+carried
+retained
+netherlands
+supplies
+batakovic
+helped
+morocco
+stood
+arab
+laws
+neither
+lost
+sparked
+sank
+neutralizing
+version
+od
+commercial
+international
+ismail
+skoklosters
+denied
+henrys
+geopolitics
+reject
+overthrow
+towards
+serious
+marche
+ferguson
+understood
+beccaria
+transcaucasia
+ladle
+byzantine
+slobodan
+razlovtsi
+eccentricity
+time
+schools
+dmitriev
+repertoire
+dwcenjwtgguc
+clark
+bor
+reasserted
+citation
+interlude
+marshall
+capitulations
+power
+preside
+pribram
+chinese
+spent
+fee
+guarantee
+urban
+madhab
+congressional
+osmanl
+taagepera
+universe
+wine
+maureen
+altay
+width
+warns
+eagle
+illiterate
+ballet
+production
+deals
+damaged
+recovery
+eds
+salonica
+faction
+vice
+winds
+nis
+postcard
+georg
+zwinglianism
+art
+reglement
+difference
+meanwhile
+painter
+doi
+modernity
+diverted
+sarcastically
+seegelpaper
+consolidation
+preferred
+curtail
+ukgbi
+solemn
+setbacks
+uzi
+tiered
+promising
+emin
+li
+mistakenly
+galilei
+burning
+powered
+secret
+unclear
+business
+based
+saint
+hobbes
+debts
+cruelty
+lagged
+nativity
+cobbler
+differences
+ah
+seljuks
+appoint
+lazy
+engineers
+watching
+duce
+kaleh
+houses
+scarecrow
+disease
+failed
+governor
+widespread
+devlet
+formation
+spoke
+belgrade
+obliged
+adjacent
+bahriye
+procedure
+longest
+protested
+partial
+medici
+outrage
+except
+dissolved
+andlater
+bourgeoisie
+angleze
+grandmother
+protectionism
+theorist
+sensibilities
+reason
+surrounding
+mystic
+ul
+provisional
+dagestani
+sandjak
+represented
+recognition
+whereas
+expansion
+soviet
+outlying
+turnovo
+comparing
+karen
+bg
+preliminaries
+rome
+jew
+minimal
+blank
+davison
+demographic
+plague
+disputed
+sees
+translation
+acting
+rein
+bryce
+empire
+dragomirov
+emerging
+etext
+kurumsal
+people
+levitsky
+multiple
+gama
+reinforcements
+obtaining
+nspmqlkpu
+jealous
+rejuvenate
+khan
+tithe
+arabian
+pguw
+robson
+strength
+icerikdetay
+wrestlers
+borclari
+reinstatement
+audience
+raymond
+protracted
+organizations
+cack
+ottoman
+defence
+pages
+kucuk
+modernegypt
+absolutism
+religiously
+refectory
+appears
+gravitation
+agree
+noticed
+disavowed
+quell
+newcomen
+kingdom
+dominant
+troops
+provision
+aleppo
+wanted
+petir
+pen
+b
+message
+register
+plenipotentiary
+revolts
+turc
+bridges
+deeming
+zion
+internationalization
+polarization
+maintain
+enjoying
+turkestan
+objectives
+retaliation
+wheeler
+displayed
+demise
+wyclif
+felt
+qlwcmc
+background
+wrecked
+empirefrance
+colwidth
+zwingli
+encouragement
+technique
+delegation
+rumelia
+stay
+response
+areastd
+tension
+stuart
+reduce
+hunyadi
+fe
+dissertation
+lodovico
+cartoon
+yxfp
+prelate
+ur
+maps
+korea
+ottomanempire
+dmitri
+croats
+hab
+an
+abdullah
+goltz
+srpskog
+amalgamations
+continues
+vices
+magnificent
+figes
+closed
+belief
+svg
+bosnia
+tolerate
+indebted
+cuisine
+hundred
+nobility
+productive
+interpreted
+considering
+montenegrinottoman
+royal
+shaw
+doner
+fled
+mobilized
+gross
+kamianets
+moldavia
+namk
+note
+described
+encourage
+sabuncuoglu
+stated
+credited
+corsica
+reversal
+imagination
+juan
+key
+locke
+referred
+pasa
+quite
+agoston
+sfn
+rape
+jihad
+indiscipline
+mostlty
+volunteer
+supporters
+sustained
+legitimacy
+wielded
+thinker
+attended
+horribly
+ignored
+agreements
+danubian
+motivation
+umich
+davidovich
+darkest
+lsorxjgcc
+adoption
+administered
+hertslet
+now
+avi
+transpiring
+value
+empires
+ruschuk
+berend
+abbasid
+editor
+holding
+literacy
+condorcet
+luigi
+borderlands
+sympathies
+akcam
+toktas
+ay
+ayasar
+warineastillustr
+italianism
+martha
+codes
+popp
+freud
+ambitions
+germanyrussia
+ilk
+monitors
+comte
+rabbi
+outbreak
+orleans
+bodied
+foster
+freres
+stymied
+involve
+justified
+itzkowitz
+ardahan
+removed
+hi
+legislature
+goodwill
+estimated
+seria
+vanmour
+slightly
+revise
+oath
+hume
+sudden
+outcomes
+lieven
+asked
+dcgaaqbaj
+camp
+respective
+times
+meshur
+biggest
+fodor
+thousands
+hnis
+neutral
+amassed
+engaged
+forbrich
+enough
+avdcbycc
+novels
+philological
+grant
+maintained
+arabia
+ny
+composition
+harv
+execution
+burschenschaften
+customary
+precocious
+autonomous
+combatant
+lavish
+sixteenth
+ter
+preserving
+lagorio
+responsibilities
+silver
+presiding
+extermination
+duyun
+fleets
+professionalism
+timeline
+queen
+natural
+boundaries
+supremacy
+nisani
+elestirel
+imposed
+soukoum
+soviets
+increase
+cass
+reis
+dynamite
+naci
+worldly
+kaya
+rasa
+missing
+oqc
+cover
+expired
+culprits
+obtain
+jonassohn
+imereti
+matchem
+nikolaevich
+newer
+ministry
+visual
+broad
+ioannis
+theology
+borek
+names
+refusal
+duration
+clodfelter
+formerly
+composed
+novgorod
+clash
+stavans
+stands
+figures
+droz
+shall
+reinvigorate
+becoming
+agricultural
+diggers
+combining
+chefs
+sieges
+germany
+commander
+vali
+misha
+apart
+recognize
+dimitrov
+inconsistent
+certain
+dmitry
+account
+angered
+ahukewiinofxtqvtahxgeiwkhtncageq
+values
+zeugarion
+horses
+offset
+tevfik
+open
+in
+hegemonic
+ineradicable
+regular
+media
+pslxedflfmc
+spanned
+telegraph
+mr
+experts
+ernet
+crisis
+phillippe
+he
+decreasing
+emblems
+semi
+blue
+investigation
+kemenche
+intibah
+formal
+gruesome
+lived
+izmir
+mosque
+atrocities
+facto
+wealthy
+sukeresshi
+already
+knowledge
+future
+opens
+d
+prewar
+hamid
+igor
+estate
+twenty
+nicolle
+bulgarians
+den
+archery
+initiated
+case
+church
+smith
+hatice
+massacring
+enlarged
+destroying
+estimates
+ggywuc
+bulgaria
+suggests
+langer
+comply
+mdp
+insurgency
+albertini
+supporting
+afrikaners
+serbian
+ca
+hovhannes
+november
+cede
+struggling
+stability
+obshchina
+universal
+absorbed
+twwqc
+rivalries
+considerable
+belonged
+vakayi
+circles
+stewart
+mansions
+litovsk
+psi
+undercount
+balkian
+uk
+all
+taught
+belgrads
+djedid
+withdraw
+integration
+metre
+various
+amasya
+anonymous
+kermeli
+ccit
+needed
+auguste
+impression
+publishing
+hajduk
+damascus
+huge
+engine
+passions
+communal
+this
+intermingled
+philosophy
+albany
+intensified
+jani
+tax
+modified
+innate
+prayers
+commanded
+does
+undertook
+depose
+bayonet
+bulletin
+eyup
+j
+kishmishev
+theophilus
+village
+tens
+michigan
+describes
+stuttgart
+allaboutturkey
+paying
+assure
+electors
+march
+musical
+organized
+theologian
+michelle
+castile
+berlin
+negotiations
+hampered
+quill
+significance
+dumpling
+humility
+cms
+region
+gifted
+burden
+originated
+bibliography
+democratic
+countercoup
+ramadan
+ottomanhungarian
+terminated
+signing
+deficits
+tunisia
+nigbolu
+cretan
+hindsight
+maneuvering
+indeed
+rebellions
+carlsbad
+failure
+postscript
+destiny
+chivalrous
+cfm
+different
+mary
+embodiment
+eye
+motives
+effraim
+summer
+nazism
+topics
+facilities
+enver
+walachia
+lidhjen
+malthus
+class
+occurring
+doubt
+henig
+visited
+glucksburg
+coa
+schaller
+reversals
+tulip
+transformation
+kinds
+halt
+base
+meet
+controlled
+interrelationshipsboth
+americans
+emigration
+relativity
+global
+dpsecvbpsksc
+ewart
+mikhail
+week
+vakifs
+master
+catholicism
+electoral
+com
+slavist
+vitrine
+medal
+judge
+bucuresti
+inrtellectual
+organism
+abc
+sphere
+dc
+zntaaaamaaj
+spreading
+walka
+ib
+luther
+neuilly
+conquered
+atabagate
+powerful
+fhistory
+envisioned
+whom
+multinational
+title
+restoration
+historic
+extending
+manage
+sigma
+weaving
+lindner
+kurumlar
+words
+martov
+faroqhi
+jews
+yannis
+zur
+secured
+schism
+stipulations
+dark
+bqc
+revived
+oriental
+write
+egypt
+louis
+map
+janissaries
+rogan
+expert
+study
+multi
+derive
+thessaly
+julyaugust
+persianised
+advancement
+sarkams
+wayne
+puritans
+burn
+inheritable
+establish
+pronoia
+demands
+gallery
+prohibited
+carter
+humanist
+england
+gambit
+hierarchy
+commissions
+mercantile
+donum
+sided
+these
+naim
+cite
+declaration
+road
+murdered
+xxiii
+starting
+peacemaking
+florence
+highest
+seated
+apparent
+turan
+mechanical
+enemies
+phrase
+rarqu
+male
+refers
+patron
+ofdiaq
+secretary
+bourgeois
+began
+thus
+soil
+recognise
+flagicon
+ambassador
+irani
+around
+procession
+worn
+handan
+archetype
+given
+police
+stop
+utterly
+cornel
+wiki
+pears
+predominance
+unite
+noinclude
+condemn
+leaving
+tasked
+talat
+nuri
+deposition
+pro
+back
+creation
+instances
+influence
+mona
+millet
+disintegration
+educate
+calgary
+focus
+arts
+criticizing
+unbalanced
+dostoevsky
+mathematician
+lefevre
+spring
+stricken
+cankaya
+wisconsin
+expanding
+receives
+painted
+splashed
+resulting
+kent
+demobilization
+raised
+prepared
+ct
+aol
+oubril
+belgeler
+israel
+rj
+interactions
+empirerussian
+miliutin
+lev
+simsir
+once
+impart
+subtelny
+algeria
+provinces
+ceasefire
+noted
+enabling
+gsw
+robespierre
+politicians
+simpler
+charge
+worst
+poster
+lpg
+treated
+exploded
+clubs
+continue
+economically
+demolished
+deportation
+benevolent
+jersey
+turkeyswar
+switzerland
+skelessi
+live
+niksic
+deindustrialization
+quataert
+huchtenburg
+joan
+lieutenant
+civilians
+mecelle
+risorgimento
+heights
+star
+top
+ramazan
+rudi
+irish
+linguistic
+much
+nish
+down
+project
+rift
+consisting
+hindenburg
+inc
+ottemp
+access
+rinehart
+yl
+interest
+rhythmic
+hafsid
+coup
+jean
+ceremony
+boxer
+economies
+generals
+relating
+preparations
+recurring
+rules
+primary
+repression
+theodicy
+indelible
+afsharidottoman
+coal
+opr
+peasantry
+borders
+kuwait
+sculptor
+haymerle
+federation
+thirty
+travelers
+nostrand
+religion
+belgian
+selim
+low
+palmerstonian
+stavrianos
+expensive
+ak
+kitzikis
+honed
+rising
+prominent
+also
+fictional
+norton
+hugo
+sontag
+shoes
+held
+scientific
+russo
+corporations
+astronomy
+cultural
+compromise
+interpretations
+fewer
+pirot
+peasants
+arnold
+poles
+ulrich
+hartmann
+disseminate
+quarters
+mental
+decrees
+collection
+kosova
+guns
+numerical
+charles
+partitioned
+deligiannis
+ulama
+surety
+nicholas
+lay
+virtual
+obligation
+files
+journalist
+lectures
+yedi
+retrieved
+feared
+unkiar
+kanafeh
+religions
+petitions
+chief
+overlapping
+arbiter
+ruthless
+conversations
+spurred
+stray
+despatching
+poetry
+proposing
+large
+introducing
+futile
+rivers
+boyd
+treatment
+expulsion
+fortified
+main
+qedqaoc
+temporarily
+cambridge
+deadurl
+athosbattle
+voice
+bear
+henuz
+nervous
+disliked
+collapsing
+basmachi
+publications
+delayed
+quantitative
+col
+unsuccessful
+expedition
+anthems
+pruth
+migrated
+commissioner
+niza
+chance
+find
+abandon
+civil
+consequences
+collectivisation
+strain
+struggled
+shrinking
+galicia
+fatih
+germanhistorydocs
+harmony
+tolerated
+jha
+rebellious
+faire
+milner
+wstitle
+beylerbey
+janissary
+brutality
+ottomanist
+sansovino
+dormant
+guide
+guided
+prominence
+ascendancy
+yorulmaz
+logos
+grows
+whether
+enemy
+ragep
+vouched
+rouayheb
+erickson
+strongholds
+experimented
+made
+anderson
+band
+myths
+colonel
+layman
+labor
+vasco
+securing
+code
+delhi
+october
+authorities
+opanets
+jb
+corps
+restrictions
+idno
+protagonist
+sinop
+total
+area
+ideology
+commissioned
+pribuoft
+ivanovich
+adjudicated
+pretext
+proved
+december
+romanov
+spinning
+telescope
+volkermord
+clauses
+dmitrievich
+karatheodori
+richmond
+logic
+connecting
+lvovich
+oltenia
+humiliated
+system
+similitude
+macgahanturkishatrocitiesinbulgaria
+himself
+air
+absence
+aramco
+works
+successors
+mordaunt
+ru
+varna
+chivalry
+passivity
+descendants
+purges
+ntvtarih
+https
+hanafi
+sokolovic
+oldstyledate
+essence
+milan
+whose
+sahin
+hitotsubashi
+encyclopaedia
+turkic
+hostile
+africa
+eugene
+destalinization
+quo
+suffer
+etc
+corvee
+prussia
+intact
+malet
+factories
+sjavrcc
+mathematical
+pertaining
+markets
+supplying
+pitt
+martyresses
+acar
+passage
+parry
+supportive
+hossein
+since
+poised
+teskil
+route
+superior
+well
+ribbentrop
+sergeyevich
+hastily
+mutawakkilite
+followers
+catholics
+call
+utopia
+kept
+plevna
+romanna
+besieged
+harluoft
+anadolu
+inline
+trenches
+dangerous
+meiji
+budget
+hohenlohe
+ucla
+massive
+wittek
+melikov
+vigorous
+analysis
+comprising
+abbr
+quiet
+quality
+officers
+renewed
+yal
+coordinate
+novi
+humankind
+sabanc
+peace
+nazi
+almost
+man
+february
+incidents
+uchicago
+crimes
+mura
+thereby
+abruptly
+plundered
+thanks
+deserter
+leaders
+placing
+occasion
+beyazid
+canning
+oil
+autobiography
+belgium
+n
+mnc
+appeasement
+bulwark
+categorie
+happening
+proportions
+henri
+film
+xxvi
+morgenthau
+france
+tremendous
+regions
+karolyi
+corinth
+html
+argyuoft
+architects
+poltava
+innovations
+peaked
+aewbw
+changing
+forth
+hille
+kieser
+executing
+particular
+yed
+erhan
+behalf
+turned
+respect
+false
+neutralize
+ignatiev
+historike
+francois
+tsikoudia
+internal
+seventeenth
+transform
+salt
+expand
+promote
+ziya
+adams
+reigned
+one
+depriving
+croatia
+houseofsanstefanotreaty
+darwinism
+aragon
+manuscripts
+klane
+gave
+diaryrh
+mahalle
+colonial
+leisure
+isabella
+opalchentsi
+decade
+operations
+repudiation
+bullets
+confederation
+minority
+garde
+turkce
+kongres
+armed
+palmer
+academic
+pa
+engines
+soon
+sursock
+kay
+tensions
+weapons
+ranked
+comments
+chapel
+balkans
+pj
+detriment
+clashes
+investment
+kural
+occasionally
+sidon
+tenant
+neighbors
+invading
+unprinted
+school
+sinan
+necessitated
+keeping
+body
+strahan
+movements
+conflicts
+mopping
+rebellion
+china
+clause
+canterbury
+massacre
+acquiring
+pultar
+nineteenth
+sr
+inclusion
+tied
+actually
+separately
+niall
+spectrum
+brooklyn
+cairo
+marian
+erskine
+typically
+nelidov
+constituted
+ayan
+budjak
+iosif
+persuade
+fgrmozjz
+original
+pluralism
+arsenal
+violence
+geyikdagi
+youth
+arizona
+labourcollab
+regimes
+despotic
+exceptionally
+repin
+counterparts
+physics
+decided
+bxsv
+artistic
+differed
+teachings
+arms
+period
+inexpedient
+literally
+shipyard
+nobles
+accordance
+aujvd
+surrender
+popes
+beliefs
+schroeder
+choueiri
+unhappy
+harmanli
+nature
+interference
+signed
+thomas
+kanun
+conclude
+developed
+hebrew
+foroqhip
+diverse
+quantities
+suspended
+coalition
+vessels
+senyer
+hatt
+indulgences
+bithynia
+aviation
+cciq
+producing
+springer
+defined
+giuseppe
+owing
+providing
+unprecedented
+turkish
+substantially
+tekeli
+xfdfgpjr
+principles
+free
+abdulaziz
+tabula
+overthrown
+morse
+dipped
+surprise
+adana
+baking
+strateji
+oeta
+dp
+michael
+petrovic
+fnbw
+heavens
+uoregon
+brankovic
+wavered
+spite
+barton
+patriotic
+four
+agriculture
+religious
+soner
+calling
+hadzi
+globaled
+slate
+over
+heart
+lenin
+et
+depicts
+freedoms
+a
+reprisal
+involved
+edict
+triple
+drawings
+navy
+organique
+moving
+actively
+ammunition
+collecting
+play
+brandt
+intimidate
+gorod
+victorian
+regional
+srr
+continents
+country
+parameter
+rulers
+dollars
+mini
+duties
+win
+parties
+joseph
+boats
+limit
+trench
+poale
+concentrate
+horn
+crossed
+fritware
+stagnation
+videoplay
+his
+dec
+london
+agrarian
+themes
+sending
+opponents
+tenure
+reporting
+complete
+mcfarland
+diana
+nd
+secure
+violations
+left
+affairs
+sponsor
+days
+mensheviks
+holland
+vincent
+manufacturing
+showed
+assyrian
+photographer
+colors
+prime
+dobrudja
+confident
+export
+stanishev
+prosperity
+furnishings
+romance
+throughout
+million
+argued
+h
+therefore
+herbert
+rp
+empirea
+continuities
+sultans
+sykespicot
+persons
+nation
+blowing
+suffix
+roundheads
+bogolyubov
+albums
+opda
+repeated
+albert
+alva
+tristan
+conrad
+cartesian
+requiring
+him
+could
+russe
+gaza
+lion
+caused
+idealized
+alexandru
+geopolitical
+britannica
+cf
+square
+massacred
+timok
+threats
+returned
+writer
+exchange
+many
+banks
+ultimate
+editorial
+directed
+category
+david
+statesmen
+when
+replied
+books
+winter
+insurrection
+scheiala
+governmental
+convinced
+wr
+protic
+textile
+isaac
+encyclopedie
+rejected
+viewing
+german
+glynn
+carry
+tzatziki
+calculus
+kindle
+hostilities
+turgenev
+serquin
+mutual
+uprising
+divide
+even
+stabilise
+holluoft
+promised
+chancellor
+makam
+hegemony
+platform
+meetings
+step
+philosophes
+increased
+expelled
+crnojevic
+bbc
+approved
+induction
+maniye
+qadi
+pal
+zilbridge
+dragoons
+unparallelled
+skit
+remarque
+materials
+paker
+sometimes
+zimmerer
+dismal
+complexity
+wm
+ebook
+critics
+vranje
+vsemirnaya
+collect
+elman
+gradually
+economics
+implications
+scramble
+zimmi
+penetrate
+greatest
+gennadios
+grateful
+info
+aristotelian
+january
+studen
+usul
+indispensable
+frequently
+third
+outcast
+murad
+stylish
+conflict
+thoroughly
+mohammad
+limits
+qadaa
+been
+pontic
+trialsanderrors
+allow
+sterling
+firm
+tested
+studia
+stories
+persian
+discontent
+leandre
+worth
+khruschev
+common
+collections
+issue
+sogut
+poor
+cooking
+handle
+olson
+beaconsfield
+sovereigns
+populstat
+organize
+vichy
+nikopol
+showing
+dealing
+moments
+trapped
+liberalism
+grievances
+selcuk
+genocide
+fifth
+savory
+ua
+naval
+null
+periodization
+dissolve
+individualism
+notoc
+degree
+antithesis
+articles
+raisons
+rupert
+boere
+bombardments
+minor
+colin
+fleeing
+charter
+railroad
+individuals
+fundamental
+dissatisfied
+azerbaijan
+contact
+sites
+serbo
+candidacy
+appeals
+for
+westernizer
+balkanssince
+beyliks
+fyodor
+gurcaglar
+metropolis
+populace
+considered
+prompting
+authority
+discussion
+general
+hovsep
+fear
+charlotte
+objective
+monday
+tetzel
+philosophical
+yerevan
+sabers
+consider
+perhaps
+lqjylvmwb
+lee
+otap
+revolted
+assuring
+alevis
+theodoros
+introduction
+vd
+deringil
+gennadius
+openly
+outlaw
+consent
+comparisons
+dictionary
+cuban
+glenny
+eliminate
+schuyler
+suchodolski
+scholarly
+especially
+lapsed
+ani
+wragaaqbaj
+planning
+deposed
+mruchkov
+criticised
+htmux
+attack
+sects
+greekottoman
+bilecik
+villages
+committee
+sovereignty
+cession
+escorts
+technology
+vague
+turning
+framework
+refinance
+carol
+labour
+discovering
+efforts
+creed
+unnecessary
+diderot
+shortages
+sign
+muslim
+crimea
+portion
+catalyst
+simony
+ivanov
+armeniern
+equestrian
+mccarthy
+friend
+three
+focused
+flora
+quarterly
+trabzon
+ziai
+blood
+rumours
+count
+approximately
+kasaba
+lyceum
+arrived
+sainte
+beatrice
+viewed
+cd
+objectivity
+thesis
+spheres
+point
+orthodox
+eight
+encyclopedia
+fernando
+simon
+isis
+restriction
+kulturkampf
+pc
+workers
+activities
+toleration
+person
+communities
+tsar
+portugal
+advocated
+narrating
+easter
+converted
+ebed
+registers
+camps
+l
+revoke
+regulations
+tributary
+inside
+zigetvari
+beylerbeyi
+osprey
+draw
+against
+fordham
+sailing
+sizable
+honorably
+scoe
+tfeikskuswbmoltzbg
+superstition
+palm
+months
+vilayet
+ltd
+assyrians
+supply
+puppet
+issueid
+pluralistic
+exclusively
+amounts
+anything
+naturalism
+forces
+unrelated
+gives
+miscellaneous
+domains
+dismantled
+socialist
+partner
+clowes
+joined
+bilateral
+swiss
+tyt
+being
+partly
+program
+reserves
+chattel
+possession
+kosem
+suleiman
+like
+zaken
+secularism
+genocidal
+emphasizing
+taste
+esasi
+cropped
+adding
+seal
+care
+cilt
+karsh
+ibn
+neighbours
+architectures
+disruption
+heath
+moscow
+tbo
+ordinance
+party
+reaction
+yuvarlak
+shqiptare
+hat
+less
+revival
+kefsger
+provides
+grants
+politique
+normally
+morea
+clerical
+leased
+dissatisfy
+abuse
+m
+christianity
+darling
+cook
+trading
+we
+elements
+borrow
+ahmad
+revitalization
+austrohungarian
+afterwards
+bridge
+story
+inalck
+emigrated
+fourteen
+rathbone
+complex
+germanys
+bows
+ethnically
+clearly
+culminated
+eng
+at
+became
+unifications
+nezir
+then
+truce
+mir
+dis
+ochakiv
+ritualized
+dance
+reichstadt
+extra
+sforza
+thrace
+usage
+war
+zagora
+meddling
+opinion
+achievements
+withdrew
+tribal
+stayed
+venice
+entrepreneurial
+allied
+nisam
+bravery
+edited
+famously
+svetska
+frame
+quadrupled
+installations
+kutahia
+removal
+profitable
+internet
+haven
+mutiny
+xh
+turgut
+photos
+arranged
+prodan
+monsite
+disrupt
+popul
+krm
+moran
+nine
+language
+matrakci
+afforded
+sole
+politically
+periphery
+vp
+amendments
+rs
+ownings
+phd
+california
+internetarchivebot
+ausschluss
+ghaziosmanpasha
+basic
+sectors
+temporary
+putsch
+reichstag
+out
+transylvania
+can
+henry
+susceptible
+vasil
+twenties
+relinquished
+wdl
+mannerism
+rd
+shawarma
+moroccan
+waldmeierlebanon
+tarihce
+abdulmecid
+quartet
+dunyabulteni
+holocaust
+herzegovina
+spanish
+z
+prophet
+tokugawa
+locus
+ald
+nde
+sami
+jerome
+grub
+philippe
+chronology
+leader
+ma
+noble
+sadly
+cthyuqotyuc
+deleterious
+jack
+emperor
+alwisha
+expenses
+invasions
+monks
+schutzstaffel
+lit
+marxian
+dryoyam
+relationship
+she
+vastly
+petty
+synthesis
+capitalizing
+promoting
+jesus
+resm
+defended
+split
+confederates
+revenge
+measures
+flooding
+dz
+cavalry
+poems
+anthony
+thompson
+warning
+ransom
+abd
+weak
+matches
+laurent
+darwin
+am
+skills
+sarafian
+convince
+recent
+engineering
+shine
+commons
+iv
+fragner
+estimate
+portrait
+ambiguous
+hands
+amasia
+x
+online
+functioned
+bitis
+instance
+unit
+turkus
+vallier
+figure
+milos
+requirements
+perspectives
+turcica
+isolating
+containment
+reconsidered
+prose
+population
+criticized
+just
+evidence
+legitimation
+essentially
+dependent
+lands
+meaning
+copernicus
+hayreddin
+snowy
+lutheran
+proposals
+comprehensive
+reformation
+longer
+disputes
+mara
+gyro
+redif
+handed
+shelkovnikov
+insights
+gourko
+street
+currency
+persia
+balta
+designated
+bosphorus
+christian
+estates
+stara
+sector
+victoria
+twareekh
+czechoslovakia
+bks
+caucasus
+osep
+organisations
+heresy
+provoked
+opposition
+parliament
+published
+cent
+same
+snows
+rumeli
+libertarian
+inadequate
+kutaya
+depiction
+vartanian
+arabic
+metternich
+barricades
+dug
+soldier
+popularity
+porte
+text
+departure
+such
+join
+mastery
+ve
+horseback
+balance
+unified
+dr
+viscount
+nominal
+irredentist
+uploads
+quick
+scotland
+quote
+pull
+cited
+earth
+dimitri
+no
+interrelated
+isolation
+quantum
+kluwer
+anglicisation
+versailles
+popularly
+technologically
+dead
+distinctive
+cache
+serge
+hurst
+publication
+fresh
+ottomanempiremain
+sygkelos
+student
+ireland
+intolerance
+irregular
+tended
+dersaadet
+referring
+jizya
+gold
+historiographical
+cgi
+phrases
+diplomats
+geneva
+westphalia
+persecution
+bulow
+favourable
+nicolson
+fire
+object
+shop
+kadi
+deportees
+likewise
+independence
+quickened
+itu
+simeonoglou
+acceptable
+khedivate
+cut
+significantly
+recently
+wholly
+courses
+steep
+returning
+central
+terror
+academy
+escorial
+riots
+suppress
+questions
+law
+type
+prussian
+isbn
+fatal
+s
+popular
+centres
+notorious
+julius
+literate
+lithograph
+structure
+resistance
+premier
+statesman
+yogurt
+ijma
+excommunication
+era
+points
+caesars
+determining
+rkeftfaidobktaa
+bloodshed
+meeting
+neighbored
+tenasub
+revolution
+started
+able
+attempting
+satisfy
+costa
+nihilism
+les
+was
+regarded
+stefanovic
+journeys
+imagined
+dialectical
+aleksey
+inhabitants
+timur
+distinct
+argyll
+kurds
+review
+ebchecked
+cosmopolitan
+kashk
+mahmud
+realpolitik
+denmark
+tactics
+election
+arshak
+their
+napoleon
+issued
+exist
+industry
+samarkand
+employed
+protestations
+overcome
+imperialist
+clerics
+firmly
+countries
+poets
+they
+bap
+bacon
+donated
+miles
+covering
+castles
+gerrard
+often
+flickr
+vied
+continued
+aspirations
+bishop
+self
+links
+mexico
+caliphate
+changes
+monarchs
+gordian
+governing
+mohacs
+with
+preaching
+arc
+howard
+mixed
+turska
+weeks
+charging
+direct
+divine
+eleven
+egyptians
+mesnevi
+grand
+shuvalov
+liberty
+actions
+akmese
+effectiveness
+nikola
+declining
+measurement
+stepped
+ironworks
+paris
+jpg
+insisted
+observatory
+specializing
+executed
+sujuk
+the
+saylor
+brother
+strokes
+shogunate
+imperial
+models
+introduced
+towns
+wins
+justify
+madan
+worked
+holstein
+nato
+fate
+leskovac
+eb
+trotsky
+bankruptcy
+helm
+marks
+hathaway
+pledge
+cesare
+rough
+recognized
+depended
+decline
+atlantikteturkdenizciligi
+r
+realist
+vit
+making
+earl
+serve
+heartland
+please
+conduct
+marbling
+on
+evolved
+sheets
+failing
+reminiscencesofk
+ladles
+unifier
+fresco
+negotiated
+ascent
+er
+delay
+cift
+between
+mollify
+strife
+duret
+achievement
+by
+philliou
+garrison
+devri
+assurances
+firearms
+cassell
+warrior
+austria
+improve
+bisected
+favor
+spirit
+humanists
+trends
+millman
+greater
+aksan
+kultur
+reflected
+prove
+should
+extended
+hale
+bazouks
+sharpshooters
+contingent
+harem
+dowling
+examination
+napoleonic
+theft
+guardians
+veneer
+least
+caspian
+compass
+tom
+jurgen
+rutgers
+be
+wisc
+porter
+copernican
+generally
+circassians
+spjnd
+sanjak
+consolation
+teschen
+away
+sacked
+calligraphy
+west
+borough
+bloomington
+tartar
+erastimes
+sumla
+princeton
+represent
+crushing
+startling
+representing
+katip
+scribal
+tlem
+collaboration
+view
+prescribed
+wordpress
+calligraphers
+medicine
+modernize
+sailor
+europeans
+lahmacun
+attempt
+istanbul
+pierre
+example
+brian
+prospect
+early
+berkeley
+transcontinental
+fringe
+hungarygermany
+preventing
+thrones
+karagoz
+utility
+proceed
+armies
+governors
+printing
+ishtiaq
+segabg
+finkel
+thukj
+reactionary
+gate
+mihail
+shisutazu
+constantly
+outline
+imports
+raided
+legacies
+secular
+lanzarote
+byword
+detailed
+semitic
+werner
+ottomanvenetian
+devsirme
+rogne
+ask
+watson
+irregulars
+foreground
+demonstration
+abkhazians
+sultani
+milyutin
+pablo
+discussions
+offensive
+dominating
+imper
+eagles
+defenestration
+jenny
+cz
+museums
+cosmology
+christ
+catholicos
+physicist
+eighty
+mind
+icon
+epstein
+offenses
+gazi
+rocks
+abdul
+element
+notes
+escape
+pearson
+ancestors
+identify
+emperors
+lord
+aziz
+conscripts
+within
+dismissal
+borrowing
+lebanon
+nyl
+ivan
+shahid
+justly
+sinasi
+eccentric
+valid
+nizamnamesi
+realpolitick
+sir
+resolution
+ad
+affecting
+falconets
+orthodoxy
+hailed
+garibe
+fight
+steam
+reinsurance
+council
+revenues
+winstanley
+supreme
+genres
+agents
+proudhon
+theory
+operating
+libfl
+holy
+cotton
+positano
+sumnu
+cw
+garrisons
+duchy
+sense
+emerge
+na
+empress
+invade
+talk
+tsipouro
+potential
+europe
+lyon
+habsburg
+sovereign
+treaty
+decay
+cherez
+rhodes
+migration
+suny
+contemporaries
+territories
+forbidden
+fast
+office
+republic
+mobility
+moslem
+gauguin
+commission
+victory
+indicated
+compositionally
+respectively
+twayne
+protector
+subjected
+reformed
+woodhead
+protective
+husband
+ijtihad
+krummerich
+north
+bos
+inconclusive
+yaqaaqbaj
+crescent
+river
+pyotr
+symbolism
+compositions
+sencercorlu
+inflation
+stirred
+delivered
+protectorate
+linda
+ingredients
+ownership
+fizzled
+richard
+clergy
+gained
+appleton
+authorlink
+xi
+upright
+national
+januarius
+neutrality
+abuses
+insurgents
+jelavich
+welfare
+heretical
+jurisdiction
+gorni
+hakham
+overview
+christopher
+bilal
+brigandage
+iranian
+casualties
+northwest
+synvet
+division
+fulfilling
+wing
+round
+italian
+ethics
+included
+programme
+proposal
+boksida
+aleksandr
+rite
+easternquestionf
+sanstefan
+assumed
+deeds
+decoration
+some
+ruled
+captive
+goals
+reconnaissance
+achieved
+somel
+bourchier
+opalchenie
+reid
+giving
+fortune
+opposed
+qasim
+commonwealth
+mediate
+telegraphy
+sturmabteilung
+mackenzie
+px
+topkapi
+crucially
+kelsen
+superpower
+zahrawi
+amarcus
+white
+determination
+yemen
+nicolaus
+activity
+wish
+batak
+character
+nakkashane
+ndtu
+v
+shortly
+dominions
+milton
+bad
+designed
+armata
+simultaneously
+haifa
+pretending
+php
+mehteran
+doorways
+gberis
+braudel
+url
+exalted
+consequently
+domestic
+ruler
+mi
+helmets
+wished
+matthew
+encompassed
+performed
+memorandum
+jorg
+full
+termed
+philosopher
+supplied
+exode
+friedrich
+known
+medrese
+lucien
+contributing
+established
+exiled
+appointment
+torpedo
+universelle
+infobase
+turecki
+falls
+roderic
+slavonic
+ara
+etiology
+forms
+nda
+monument
+menshikov
+annex
+orig
+profiting
+kosove
+desirability
+revive
+projects
+near
+born
+survival
+brutally
+shoah
+make
+antoine
+secularization
+alajos
+invents
+khiqawaaqbaj
+esq
+headed
+committees
+eritrea
+interested
+centralized
+palestine
+championed
+translations
+sonneschein
+negotiate
+lepanto
+appearance
+infobox
+problem
+carpets
+representatives
+syracuse
+content
+keyinjwjwigc
+expense
+sharply
+hills
+cobdenchevalier
+kampf
+particularly
+padisah
+verse
+ei
+date
+papers
+century
+island
+mines
+majnun
+mignon
+launched
+sharia
+subsequent
+occasioned
+derin
+harbi
+giray
+outright
+timariot
+supervision
+avoiding
+foul
+numbered
+venture
+source
+legally
+farm
+light
+sakarya
+customs
+immunity
+catholic
+sevastopol
+baglama
+ann
+professional
+worms
+sc
+decayed
+red
+carved
+massacres
+insecure
+eternal
+peak
+accounts
+figurative
+johann
+breaking
+victories
+redirect
+cheated
+rhymed
+divorce
+chapter
+polish
+inevitable
+signatures
+bab
+consenting
+speak
+cami
+shown
+nationale
+shocked
+minorities
+multilingual
+idx
+fees
+ntv
+mapofeuropebytre
+cautious
+kayal
+wise
+fetret
+pereprava
+jnwywc
+security
+eyewitness
+adopting
+jaimoukha
+tile
+fully
+fugitives
+lock
+aeiitaa
+tanbur
+streams
+named
+female
+dunaj
+hikyayesi
+routes
+routledge
+marshal
+blockquote
+controlling
+listing
+aforementioned
+types
+aided
+inventory
+paradoxes
+defender
+prevent
+relaxation
+louise
+sacrifice
+reveals
+podolia
+imminent
+comic
+asking
+onwards
+fief
+la
+zubaida
+acquisitions
+lifestyle
+maturidi
+forts
+francis
+aftermath
+nisba
+girl
+meyendorff
+journals
+ancien
+feminism
+libya
+founder
+deciding
+denounced
+peaceful
+sidebar
+guise
+indignant
+readings
+anatolian
+initiator
+xvii
+acquired
+additionally
+abu
+theodore
+churchill
+result
+characteristic
+surrendering
+amiroutzes
+homelands
+plewna
+mevzuat
+counterattack
+prefecture
+paid
+emphasis
+question
+assistance
+tunis
+warfare
+oklahoma
+survey
+romanian
+help
+wages
+buy
+batum
+accommodate
+entering
+calare
+wind
+dependence
+exercised
+objected
+juris
+edwin
+young
+haham
+hit
+ot
+finest
+active
+pressed
+horse
+translate
+archenemy
+illustrations
+deputies
+refuge
+crew
+youssef
+unrepresentative
+berber
+dzkk
+monograms
+utopian
+dignity
+aid
+assembled
+tartars
+position
+contribution
+harm
+transformed
+manu
+afraid
+anarchy
+bashi
+discredit
+attempted
+veliko
+hizber
+kresnarazlog
+trent
+gazel
+dispatched
+jonathan
+kaza
+mazzini
+confirmed
+refer
+virtually
+vidin
+favored
+lavash
+nicopolis
+implies
+succeeded
+chancellors
+scholarius
+if
+video
+campaignbox
+conferences
+kurt
+situation
+von
+cheese
+chaos
+inspectors
+famine
+however
+mixture
+flank
+furnishing
+rejection
+chaldiran
+gulhane
+otto
+spoils
+croixrouge
+madrid
+lausanne
+tashkessen
+velika
+valley
+dated
+stumble
+newsite
+thank
+belly
+pointed
+although
+disintegrating
+archive
+tapper
+iranica
+revues
+mfa
+vryonis
+college
+hershey
+enclosing
+ally
+develop
+decisive
+constitute
+oblast
+excerpt
+solution
+lifted
+brought
+supper
+comrades
+dogs
+accompanied
+continuation
+subsistence
+sciences
+sair
+albanica
+critical
+savonarola
+attention
+en
+mine
+turkey
+eliminating
+pilaf
+adam
+officer
+culmination
+sultanate
+salonika
+wars
+secrettreatiesof
+record
+market
+recaptured
+kapucu
+erdem
+frontier
+kurus
+kozelsky
+prayer
+groups
+litigants
+bar
+wallachia
+accommodating
+short
+scheme
+losers
+swan
+deprived
+musicians
+emanuilovich
+invaders
+ray
+nikita
+temper
+center
+students
+journal
+precedent
+manufacturers
+captivity
+rights
+papacy
+option
+russians
+bashibazouk
+officials
+denis
+prepare
+break
+share
+aliye
+vizier
+chagrin
+baghdad
+istorija
+expectancy
+agriculturists
+alighieri
+entrance
+levene
+wrested
+racist
+history
+robert
+eroding
+warren
+vitality
+oscar
+idea
+fortresses
+mathilde
+japan
+osmaniye
+god
+ottomandebthistory
+embodied
+swords
+diriyah
+ancient
+interests
+austriaturkey
+potent
+preserve
+determine
+repulsing
+attend
+gjurmine
+paper
+lancaster
+poet
+bread
+settle
+asian
+objection
+koloman
+areas
+occurrences
+toward
+carmichael
+nasuh
+obsolete
+albanologjike
+zapotocny
+tbm
+plight
+ljubica
+assault
+penguin
+pazar
+bayezid
+pushed
+obrenovic
+schillingsfurst
+there
+digital
+karaore
+slavery
+compared
+leopold
+gen
+consented
+kelly
+dynamics
+commodity
+slott
+vwb
+responded
+periodically
+feel
+hakan
+deriving
+shamanism
+rival
+imposing
+icduygu
+string
+fairly
+reach
+joint
+humayun
+obligations
+mass
+interesting
+peloponnese
+aspx
+russianarmyitsca
+universitesi
+grabar
+ubermensch
+bulletins
+ahmed
+rubber
+best
+virginia
+naturalist
+beyazit
+sons
+ej
+voting
+telegram
+remained
+vinton
+seeds
+byzantium
+mobilize
+rural
+oltu
+marx
+individual
+long
+intentions
+immigrants
+etat
+locked
+bytodorbozhinov
+memory
+slavists
+earlier
+statute
+arzuhalci
+proclaimed
+sectarianism
+savage
+mission
+website
+subdivided
+berlincongress
+final
+sowards
+counselled
+authoritarian
+funds
+ensuring
+zakupy
+gawrych
+balkan
+leading
+mongol
+shortage
+paramount
+preference
+rate
+instrument
+flooded
+parliamentarians
+palace
+appeared
+de
+kitchen
+disadvantageous
+surpluses
+surveys
+totalitarianism
+jpn
+ylz
+rebuilding
+westward
+andreyevich
+shipka
+archiveurl
+seven
+state
+either
+foundation
+liras
+nente
+race
+obscure
+somme
+unresolved
+liberation
+cahier
+superpowers
+preoccupation
+situations
+umumiye
+br
+madrasa
+green
+kellogg
+vi
+monk
+utaaaayaaj
+bir
+roses
+entanglements
+tilsit
+allegiance
+galatasaray
+friendly
+timariots
+facilitated
+proceeded
+ismailis
+geheime
+xii
+vogue
+tamir
+problematic
+gocek
+noticeable
+including
+jefferson
+brigade
+two
+heavily
+american
+protestantism
+thunderstorm
+so
+tdzjcy
+robbery
+dichotomy
+yahud
+anthem
+slav
+describe
+contingencies
+private
+qiyas
+migratory
+clay
+armour
+exploitation
+preservation
+mazda
+perushtitsa
+sport
+husnu
+press
+soldiers
+rebels
+climax
+prohibition
+dlxs
+doll
+yeni
+officially
+presses
+but
+scafes
+posts
+goods
+sessions
+rebelled
+hussain
+greece
+kosta
+lower
+considerations
+varzhapetian
+paternalistic
+treasury
+culottes
+frontiers
+sepulchre
+section
+eugenia
+level
+phrasing
+not
+sanstefano
+www
+wallachian
+taqi
+hitler
+overall
+skillful
+kremiala
+home
+democracy
+augustinian
+vol
+following
+executive
+warsaw
+islamic
+schonbrunn
+relieved
+marie
+derived
+aegean
+box
+opening
+suppressing
+liberal
+little
+shaped
+peeters
+played
+moniarkadiou
+stalemate
+aksanow
+claiming
+gomidas
+rose
+die
+prospective
+canal
+solidified
+sandzak
+practice
+isa
+ferdidand
+reached
+army
+while
+rumors
+repelled
+viziers
+eminonu
+surgeons
+drove
+aec
+damaging
+shtml
+adjective
+setton
+path
+noun
+fantastic
+revolutionaries
\ No newline at end of file
diff --git a/2018/make-history-words.ipynb b/2018/make-history-words.ipynb
new file mode 100644 (file)
index 0000000..c24e7bc
--- /dev/null
@@ -0,0 +1,173 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "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": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import string\n",
+    "from support.utilities import *"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "text = open('history-words-raw.txt').read().lower()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "437770"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(text)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "cleaned = cat(c if c in string.ascii_letters else ' ' for c in unaccent(text))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'  notoc   noinclude   europeanhistorytoc    noinclude      border     id  toc  style  margin    auto'"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cleaned[:100]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "8197"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cleaned_words = set(cleaned.split())\n",
+    "len(cleaned_words)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "67866"
+      ]
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('history-words.txt', 'w').write(lcat(cleaned_words))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "True"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "'ottoman' in cleaned_words"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.6"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/2019/1a.ciphertext b/2019/1a.ciphertext
new file mode 100644 (file)
index 0000000..e415352
--- /dev/null
@@ -0,0 +1,6 @@
+XQHHO, Y QC DEJ IKHU YV OEK MUHU SEFYUT YD JE JXU CUCE QREKJ HUSUDJ ULUDJI RKJ XUHU YI Q IKCCQHO.
+JME TQOI QWE, QD EVV-TKJO WKYTQDSU EVVYSUH QBUHJUT CYIIYED SEDJHEB JE Q FEJUDJYQB FHERBUC MYJX JXU QFEBBE VBYWXJ. JXU FBQDDUT TUISUDJ JHQZUSJEHO QFFUQHUT JE RU HKDDYDW ED Q SEBBYIYED SEKHIU MYJX JXU IELYUJ BKDQH EHRYJUH BKDQ-VYVJUUD, QDT JXUHU MQI QJ BUQIJ JXU FEJUDJYQB VEH JXYI JE SQKIU QD QREHJ, EH, MEHIU QD QSSYTUDJ. REHCQD JUBUNUT CEISEM QDT QIAUT VEH Q LQHYQJYED EV EHRYJ QDT, FHUJJO CKSX JE ULUHOEDU’I IKHFHYIU, JXUO QWHUUT. QI Q HUIKBJ, JXU CYIIYED YI FHESUUTYDW QI FBQDDUT.
+DE EDU YI HUQBBO IKHU MXO JXU IELYUJI QWHUUT JE XUBF, WYLUD JXQJ QREHJYDW YJ MEKBT XQLU FKJ UWW ED EKH VQSUI, RKJ JXQJ GKUIJYED YI EDU VEH JXU QDQBOIJI QJ BQDWBUO. Q CEHU YCCUTYQJU SEDSUHD VEH CU MQI MXO JXU FHERBUC XQTD’J RUUD IFEJJUT UQHBYUH. VHQDA JEBT CU JXQJ YV XU XQT ADEMD YD JYCU JXUD MU SEKBT XQLU FBQDDUT JXU EHRYJ QDT TUISUDJ JE QLEYT JXU YIIKU YD JXU VYHIJ FBQSU.
+EV SEKHIU, CYIJQAUI TE XQFFUD, RKJ Y SXUSAUT MYJX JXU JUQC QDT EDU EV JXUC HUSQBBUT HKDDYDW IYCKBQJYEDI ED JXYI BQIJ CEDJX. IXU IQYT IXU XQT VBQWWUT JXU YIIKU VEH JXU QJJUDJYED EV VBYWXJ SEDJHEB, RKJ DE-EDU JXUHU HUCUCRUHUT IUUYDW YJ. Y QIAUT JE IUU JXU VYBU RKJ YJ BEEAI BYAU Q RKDSX EV WQHRQWU, MXYSX, Y QIIKCU, YI MXO DE-EDU HUIFEDTUT JE YJ. JXU SECFKJUH JUQC TED’J HUSEWDYIU JXU VEHCQJ QDT JXUO IKWWUIJUT JXQJ YJ MQI FHERQRBO ZKIJ Q RKW YD JXU HUFEHJ MHYJYDW IEVJMQHU, RKJ DE-EDU HUSQBBI IUUYDW QDOJXYDW BYAU YJ RUVEHU QDT YJ YI MEHHOYDW JXQJ JXYI SEKBT XQLU RUUD IE IUHYEKI. SEKBT OEK JQAU Q BEEA QJ JXU VYBU QDT BUJ CU ADEM MXQJ OEK IUU?
+CUW.
+FI MXUD OEK QHU FBQDDYDW JE WUJ RQSA XUHU VHEC XKDJILYBBU?
diff --git a/2019/1a.plaintext b/2019/1a.plaintext
new file mode 100644 (file)
index 0000000..376da63
--- /dev/null
@@ -0,0 +1,6 @@
+HARRY, I AM NOT SURE IF YOU WERE COPIED IN TO THE MEMO ABOUT RECENT EVENTS BUT HERE IS A SUMMARY.
+TWO DAYS AGO, AN OFF-DUTY GUIDANCE OFFICER ALERTED MISSION CONTROL TO A POTENTIAL PROBLEM WITH THE APOLLO FLIGHT. THE PLANNED DESCENT TRAJECTORY APPEARED TO BE RUNNING ON A COLLISION COURSE WITH THE SOVIET LUNAR ORBITER LUNA-FIFTEEN, AND THERE WAS AT LEAST THE POTENTIAL FOR THIS TO CAUSE AN ABORT, OR, WORSE AN ACCIDENT. BORMAN TELEXED MOSCOW AND ASKED FOR A VARIATION OF ORBIT AND, PRETTY MUCH TO EVERYONE'S SURPRISE, THEY AGREED. AS A RESULT, THE MISSION IS PROCEEDING AS PLANNED.
+NO ONE IS REALLY SURE WHY THE SOVIETS AGREED TO HELP, GIVEN THAT ABORTING IT WOULD HAVE PUT EGG ON OUR FACES, BUT THAT QUESTION IS ONE FOR THE ANALYSTS AT LANGLEY. A MORE IMMEDIATE CONCERN FOR ME WAS WHY THE PROBLEM HADN'T BEEN SPOTTED EARLIER. FRANK TOLD ME THAT IF HE HAD KNOWN IN TIME THEN WE COULD HAVE PLANNED THE ORBIT AND DESCENT TO AVOID THE ISSUE IN THE FIRST PLACE.
+OF COURSE, MISTAKES DO HAPPEN, BUT I CHECKED WITH THE TEAM AND ONE OF THEM RECALLED RUNNING SIMULATIONS ON THIS LAST MONTH. SHE SAID SHE HAD FLAGGED THE ISSUE FOR THE ATTENTION OF FLIGHT CONTROL, BUT NO-ONE THERE REMEMBERED SEEING IT. I ASKED TO SEE THE FILE BUT IT LOOKS LIKE A BUNCH OF GARBAGE, WHICH, I ASSUME, IS WHY NO-ONE RESPONDED TO IT. THE COMPUTER TEAM DON'T RECOGNISE THE FORMAT AND THEY SUGGESTED THAT IT WAS PROBABLY JUST A BUG IN THE REPORT WRITING SOFTWARE, BUT NO-ONE RECALLS SEEING ANYTHING LIKE IT BEFORE AND IT IS WORRYING THAT THIS COULD HAVE BEEN SO SERIOUS. COULD YOU TAKE A LOOK AT THE FILE AND LET ME KNOW WHAT YOU SEE?
+MEG.
+PS WHEN YOU ARE PLANNING TO GET BACK HERE FROM HUNTSVILLE?
diff --git a/2019/1b.ciphertext b/2019/1b.ciphertext
new file mode 100644 (file)
index 0000000..819e0c0
--- /dev/null
@@ -0,0 +1,11 @@
+ZRZB
+SEBZ: GENWRPGBEL GRNZ NCBYYB THVQNAPR
+GB: THVQNAPR BSSVPRE
+FHOWRPG: UNMNEQF VA YHANE BEOVG
+ENQNE GENPXVAT UNF FUBJA GUNG GUR FBIVRG YHANE BEOVGRE YHAN SVSGRRA VF CBGRAGVNYYL BA N PBYYVFVBA PBHEFR JVGU GUR FPURQHYRQ QRFPRAG CNGU SBE RNTYR. GUR PHEERAG EVFX VF YBJ GB ZRQVHZ, OHG NPGVBA FUBHYQ OR GNXRA GB ZVAVZVFR BE RYVZVANGR VG.
+GUR PHEERAG ENATR BS BCGVBAF VAPYHQRF:
+ER-PNYPHYNGVBA BS NYGREANGVIR QRFPRAG CNGUF GB GUR CEVZNEL NAQ FRPBAQNEL YNAQVAT GNETRGF.
+ER-QRFVTANGVBA BS YNAQVAT FVGRF JUVPU HFR QRFPRAG CNGUF JUVPU QB ABG VAGREFRPG GUR BEOVGRE CNGU.
+NOBEG ZVFFVBA
+GUR SVEFG NAQ FRPBAQ BCGVBAF PNEEL GUR NQQVGVBANY EVFXF NFFBPVNGRQ JVGU NAL FVTAVSVPNAG YNGR FGNTR PUNATR GB GUR ZVFFVBA CYNA. GUR GUVEQ BCGVBA PNEEVRF GUR ERNY GUERNG GUNG JR JVYY SNVY GB SHYSVY GUR CEVZNEL BOWRPGVIR BS N ZNAARQ YNAQVAT ORSBER GUR RAQ BS GUR LRNE.
+BAR NYGREANGVIR GB GURFR BCGVBAF JBHYQ OR GB ERDHRFG SHEGURE VASBEZNGVBA SEBZ GUR FBIVRGF GB PYNEVSL GUR ZVFFVBA CYNA SBE GURVE BEOVGRE. VG VF CBFFVOYR GUNG GURL NER NYERNQL CYNAAVAT GB ZBQVSL VGF GENWRPGBEL NAQ GUNG AB SHEGURE NPGVBA JVYY OR ARRQRQ BA BHE CNEG, OHG PUNATRF GB GUR BEOVG PBHYQ VAPERNFR GUR EVFX NAQ JR ZVTUG YBFR GENPXVAT ERQHPVAT GUR YVXRYVUBBQ GUNG JR PNA ZNANTR GUR FVGHNGVBA.
diff --git a/2019/1b.plaintext b/2019/1b.plaintext
new file mode 100644 (file)
index 0000000..ac69d0e
--- /dev/null
@@ -0,0 +1,11 @@
+MEMO
+FROM: TRAJECTORY TEAM APOLLO GUIDANCE
+TO: GUIDANCE OFFICER
+SUBJECT: HAZARDS IN LUNAR ORBIT
+RADAR TRACKING HAS SHOWN THAT THE SOVIET LUNAR ORBITER LUNA FIFTEEN IS POTENTIALLY ON A COLLISION COURSE WITH THE SCHEDULED DESCENT PATH FOR EAGLE. THE CURRENT RISK IS LOW TO MEDIUM, BUT ACTION SHOULD BE TAKEN TO MINIMISE OR ELIMINATE IT.
+THE CURRENT RANGE OF OPTIONS INCLUDES:
+RE-CALCULATION OF ALTERNATIVE DESCENT PATHS TO THE PRIMARY AND SECONDARY LANDING TARGETS.
+RE-DESIGNATION OF LANDING SITES WHICH USE DESCENT PATHS WHICH DO NOT INTERSECT THE ORBITER PATH.
+ABORT MISSION
+THE FIRST AND SECOND OPTIONS CARRY THE ADDITIONAL RISKS ASSOCIATED WITH ANY SIGNIFICANT LATE STAGE CHANGE TO THE MISSION PLAN. THE THIRD OPTION CARRIES THE REAL THREAT THAT WE WILL FAIL TO FULFIL THE PRIMARY OBJECTIVE OF A MANNED LANDING BEFORE THE END OF THE YEAR.
+ONE ALTERNATIVE TO THESE OPTIONS WOULD BE TO REQUEST FURTHER INFORMATION FROM THE SOVIETS TO CLARIFY THE MISSION PLAN FOR THEIR ORBITER. IT IS POSSIBLE THAT THEY ARE ALREADY PLANNING TO MODIFY ITS TRAJECTORY AND THAT NO FURTHER ACTION WILL BE NEEDED ON OUR PART, BUT CHANGES TO THE ORBIT COULD INCREASE THE RISK AND WE MIGHT LOSE TRACKING REDUCING THE LIKELIHOOD THAT WE CAN MANAGE THE SITUATION.
diff --git a/2019/2019-challenge1.ipynb b/2019/2019-challenge1.ipynb
new file mode 100644 (file)
index 0000000..bfe893f
--- /dev/null
@@ -0,0 +1,159 @@
+{
+ "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 support.text_prettify import *"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "c1a = open('1a.ciphertext').read()\n",
+    "c1b = open('1b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "HARRY, I AM NOT SURE IF YOU WERE COPIED IN TO THE MEMO ABOUT RECENT EVENTS BUT HERE IS A SUMMARY.\n",
+      "TWO DAYS AGO, AN OFF-DUTY GUIDANCE OFFICER ALERTED MISSION CONTROL TO A POTENTIAL PROBLEM WITH THE APOLLO FLIGHT. THE PLANNED DESCENT TRAJECTORY APPEARED TO BE RUNNING ON A COLLISION COURSE WITH THE SOVIET LUNAR ORBITER LUNA-FIFTEEN, AND THERE WAS AT LEAST THE POTENTIAL FOR THIS TO CAUSE AN ABORT, OR, WORSE AN ACCIDENT. BORMAN TELEXED MOSCOW AND ASKED FOR A VARIATION OF ORBIT AND, PRETTY MUCH TO EVERYONE'S SURPRISE, THEY AGREED. AS A RESULT, THE MISSION IS PROCEEDING AS PLANNED.\n",
+      "NO ONE IS REALLY SURE WHY THE SOVIETS AGREED TO HELP, GIVEN THAT ABORTING IT WOULD HAVE PUT EGG ON OUR FACES, BUT THAT QUESTION IS ONE FOR THE ANALYSTS AT LANGLEY. A MORE IMMEDIATE CONCERN FOR ME WAS WHY THE PROBLEM HADN'T BEEN SPOTTED EARLIER. FRANK TOLD ME THAT IF HE HAD KNOWN IN TIME THEN WE COULD HAVE PLANNED THE ORBIT AND DESCENT TO AVOID THE ISSUE IN THE FIRST PLACE.\n",
+      "OF COURSE, MISTAKES DO HAPPEN, BUT I CHECKED WITH THE TEAM AND ONE OF THEM RECALLED RUNNING SIMULATIONS ON THIS LAST MONTH. SHE SAID SHE HAD FLAGGED THE ISSUE FOR THE ATTENTION OF FLIGHT CONTROL, BUT NO-ONE THERE REMEMBERED SEEING IT. I ASKED TO SEE THE FILE BUT IT LOOKS LIKE A BUNCH OF GARBAGE, WHICH, I ASSUME, IS WHY NO-ONE RESPONDED TO IT. THE COMPUTER TEAM DON'T RECOGNISE THE FORMAT AND THEY SUGGESTED THAT IT WAS PROBABLY JUST A BUG IN THE REPORT WRITING SOFTWARE, BUT NO-ONE RECALLS SEEING ANYTHING LIKE IT BEFORE AND IT IS WORRYING THAT THIS COULD HAVE BEEN SO SERIOUS. COULD YOU TAKE A LOOK AT THE FILE AND LET ME KNOW WHAT YOU SEE?\n",
+      "MEG.\n",
+      "PS WHEN YOU ARE PLANNING TO GET BACK HERE FROM HUNTSVILLE?\n",
+      "\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "1666"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, score_a = caesar_break(c1a)\n",
+    "print(caesar_decipher(c1a, key_a))\n",
+    "open('1a.plaintext', 'w').write(caesar_decipher(c1a, key_a))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "MEMO\n",
+      "FROM: TRAJECTORY TEAM APOLLO GUIDANCE\n",
+      "TO: GUIDANCE OFFICER\n",
+      "SUBJECT: HAZARDS IN LUNAR ORBIT\n",
+      "RADAR TRACKING HAS SHOWN THAT THE SOVIET LUNAR ORBITER LUNA FIFTEEN IS POTENTIALLY ON A COLLISION COURSE WITH THE SCHEDULED DESCENT PATH FOR EAGLE. THE CURRENT RISK IS LOW TO MEDIUM, BUT ACTION SHOULD BE TAKEN TO MINIMISE OR ELIMINATE IT.\n",
+      "THE CURRENT RANGE OF OPTIONS INCLUDES:\n",
+      "RE-CALCULATION OF ALTERNATIVE DESCENT PATHS TO THE PRIMARY AND SECONDARY LANDING TARGETS.\n",
+      "RE-DESIGNATION OF LANDING SITES WHICH USE DESCENT PATHS WHICH DO NOT INTERSECT THE ORBITER PATH.\n",
+      "ABORT MISSION\n",
+      "THE FIRST AND SECOND OPTIONS CARRY THE ADDITIONAL RISKS ASSOCIATED WITH ANY SIGNIFICANT LATE STAGE CHANGE TO THE MISSION PLAN. THE THIRD OPTION CARRIES THE REAL THREAT THAT WE WILL FAIL TO FULFIL THE PRIMARY OBJECTIVE OF A MANNED LANDING BEFORE THE END OF THE YEAR.\n",
+      "ONE ALTERNATIVE TO THESE OPTIONS WOULD BE TO REQUEST FURTHER INFORMATION FROM THE SOVIETS TO CLARIFY THE MISSION PLAN FOR THEIR ORBITER. IT IS POSSIBLE THAT THEY ARE ALREADY PLANNING TO MODIFY ITS TRAJECTORY AND THAT NO FURTHER ACTION WILL BE NEEDED ON OUR PART, BUT CHANGES TO THE ORBIT COULD INCREASE THE RISK AND WE MIGHT LOSE TRACKING REDUCING THE LIKELIHOOD THAT WE CAN MANAGE THE SITUATION.\n",
+      "\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "1238"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score_b = caesar_break(c1b)\n",
+    "print(caesar_decipher(c1b, key_b))\n",
+    "open('1b.plaintext', 'w').write(caesar_decipher(c1b, key_b))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(16, 13)"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_a, key_b"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.8"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/2019/2019-challenge2.ipynb b/2019/2019-challenge2.ipynb
new file mode 100644 (file)
index 0000000..4ec93e1
--- /dev/null
@@ -0,0 +1,172 @@
+{
+ "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": 9,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from cipher.caesar import *\n",
+    "from cipher.affine import *\n",
+    "from support.text_prettify import *"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ca = open('2a.ciphertext').read()\n",
+    "cb = open('2b.ciphertext').read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "11 7 True \n",
+      "\n",
+      "Meg, I took a look at the file you sent over and it was just a rotation cipher applied to the text.\n",
+      "At first it was hard to say if that was a bug or a feature and normally I would assume bug, but it\n",
+      "seemed odd that it was the only file that was affected so I asked around to see if anyone had seen\n",
+      "anything similar. It turns out that this was not the first navigation problem to hit the programme.\n",
+      "Gene reported a major issue with the guidance programme for Snoopy on the Apollo Ten mission which\n",
+      "could again have caused a major problem. For some reason the programme controlling the landing radar\n",
+      "wasn’t updated with the flight plan and if Gene hadn’t raised that with Iverson then the boys might\n",
+      "have had real trouble getting back. I looked through the company files and found another of our\n",
+      "mysteriously formatted reports: the memo informing them about the change, which explains why the\n",
+      "programme never got updated. This time the cipher was an affine shift, so slightly harder to crack,\n",
+      "but nothing serious. Still, it is much less likely that it was a bug that time, and in any case\n",
+      "twice is too much of a coincidence. It did start me wondering why the second cipher was easier to\n",
+      "crack than the first, but then I realised that the affine shift was too much of a giveaway. A\n",
+      "rotation cipher really could just be an encoding error, but the affine shift is too sophisticated\n",
+      "for a mistake, so whoever mangled the reports must have realised they had made a bit of an error\n",
+      "with the first one and tried to cover their steps with the second. It is hard to see this as\n",
+      "anything other than attempted sabotage, but I am not sure what the motive could be. I doubt it is\n",
+      "personal. The Apollo Ten and Eleven crews don’t overlap, so either someone has a grudge against the\n",
+      "whole Astronaut corps or they are trying to derail the Apollo programme. It could be the Soviets I\n",
+      "suppose. At first, I thought that their willingness to shift the LUNA-FIFTEEN orbit showed that they\n",
+      "weren’t part of it, but someone in the State Department pointed out that they might just have had a\n",
+      "guilty conscience, or been keen to distance themselves once the plot was discovered. I am still not\n",
+      "sure. In the meantime, could you take a look at the computer files to see who might have had access\n",
+      "to both memos, and who might have had the opportunity and means to doctor them? I am flying back to\n",
+      "Langley tonight, to see if the State Department have any ideas what might be going on. Neil said he\n",
+      "could fly me up in one of the NASA chase planes, which is something I have been keen to try. I will\n",
+      "call you if I get anything.\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "2592"
+      ]
+     },
+     "execution_count": 30,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(m_a, s_a, o_a), score_a = affine_break(ca)\n",
+    "print(m_a, s_a, o_a, '\\n')\n",
+    "print(lcat(tpack(affine_decipher(ca, m_a, s_a, o_a).split())))\n",
+    "open('2a.plaintext', 'w').write(lcat(tpack(affine_decipher(ca, m_a, s_a, o_a).split())))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "3 8 True \n",
+      "\n",
+      "Apollo Ten\n",
+      "Spacecraft Operational Trajectory\n",
+      "First Revision\n",
+      "This document contains updated information about the planned lunar orbital operations for the mission and has been compiled to satisfy flight crew/flight controller training and simulation requirements.\n",
+      "\n",
+      "The following mission phases remain UNCHANGED from the original plan:\n",
+      "Launch, which ends with insertion into earth parking orbit (EPO).\n",
+      "Earth orbit coast, which ends with Translunar Injection (TLI).\n",
+      "Trans Lunar coast, which ends with Lunar Orbit Insertion (LOI).\n",
+      "Trans Earth coast, which ends with re-entry into the mid-Pacific recovery area.\n",
+      "\n",
+      "The total mission duration will be approximately EIGHT days.\n",
+      "\n",
+      "The report includes significant changes to Lunar orbital operations, which start at LOI and end with Trans Earth lnjection. NOTE THESE IMPORTANT TRAJECTORY CHANGES\n",
+      "\n",
+      "The prime objective of the LOI-TEI phase will be to demonstrate all\n",
+      "components of Mission G except those which directly involve Lunar Module powered descent and powered ascent.\n",
+      "\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "1012"
+      ]
+     },
+     "execution_count": 29,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(m_b, s_b, o_b), score_a = affine_break(cb)\n",
+    "print(m_b, s_b, o_b, '\\n')\n",
+    "print(affine_decipher(cb, m_b, s_b, o_b))\n",
+    "open('2b.plaintext', 'w').write(affine_decipher(cb, m_b, s_b, o_b))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.8"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/2019/2019-challenge3.ipynb b/2019/2019-challenge3.ipynb
new file mode 100644 (file)
index 0000000..7c3e75e
--- /dev/null
@@ -0,0 +1,419 @@
+{
+ "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": 59,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from cipher.caesar import *\n",
+    "from cipher.affine import *\n",
+    "from cipher.keyword_cipher import *\n",
+    "from support.text_prettify import *\n",
+    "from support.utilities import *\n",
+    "from support.plot_frequency_histogram import *"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ca = open('3a.ciphertext').read()\n",
+    "cb = open('3b.ciphertext').read()\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": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "9 25 True \n",
+      "\n",
+      "Thaay, W phogen gr fe keaghwo gte irdg Huriir Geo aeurag aehiiy phdo’g ho hkkwneog dr W hdcen\n",
+      "haktwmed gr dehakt gte lwddwro uhuead wo khde gte rawqwohi aeurag thn feeo lwdswien. Gtey dehakten\n",
+      "emeaygtwoq hon krjino’g swon wg fjg gteo drleroe thn h fahwophme hon ktekcen gte Huriir eiemeo\n",
+      "swied. Gr emeayroe’d aeiwes gtey srjon wg gteae hon gte haktwmwdg aekcroen gthg drleroe qrg\n",
+      "nwdgahkgen. Pwgt gte mrijle rs lwddwro uhuead gtey hae thoniwoq gtwd wd org h djauawde, fjg qwmeo\n",
+      "gte wluraghoke rs gtede nrkjleogd wg wd h fwg hihalwoq hon nredo’g seei iwce gte phy OHDH jdjhiiy\n",
+      "nred gtwoqd. Hoyphy, gte swon dtrjin thme aehddjaen le, hon wg prjin thme ws W thno’g irrcen dr\n",
+      "khaesjiiy hg gte swie. Emeaygtwoq irrcen swoe evkeug gthg gte pran Wozekgwro wo gte ueojigwlhge\n",
+      "uhahqahut phd dueig pwgt ho W. Yrj lhy org fe djauawden, fjg ws yrj irrc hg gte nekayug rs gte\n",
+      "lhoqien meadwro wg wd lwddueig iozekgwro, pwgt ho i aeuihkwoq gte W. W prjino’g thme orgwken fjg W\n",
+      "thn nekayugen gte rawqwohi fy thon hon phd djauawden fy gte gyur. Wg dgjkc wo ly lwon dr pteo W dhp\n",
+      "gte swien meadwro pwgtrjg wg gthg ahoq hihal feiid. Roke pe dghagen womedgwqhgwoq pe irkcen ju gte\n",
+      "krlujgea swied dr W kho roiy hddjle gthg gte swien meadwro phd gahodkawfen fy drleroe ptr orp thd\n",
+      "hkkedd gr gte uawogen meadwro fjg ptr nredo’g thme gte kiehahoke gr hkkedd gte rawqwohi. Gte\n",
+      "xjedgwro wd, pty prjin gtey uarnjke h oep meadwro? W kho roiy gtwoc gthg gtey phogen gr tehn rss\n",
+      "lrae womedgwqhgwro fy qwmwoq jd h aehdro gr gtwoc wg phd hii h lwdghce hsgea hii. Ws gthg phd gte\n",
+      "uiho gteo wg thdo’g pracen. Wg deeld kieha gr le gthg drleroe aehiiy nred thme drlegtwoq gr twne. W\n",
+      "ktekcen gte dekjawgy kiehahoke iwdg hon gteae peae gpr tjonaen hon gtwagy-demeo ueruie pwgt hkkedd\n",
+      "gr gte haktwme arrl pteae pe hae dgrawoq gte womedgwqhgwro swied ptr nr org hidr thme kjaaeog hkkedd\n",
+      "gr gtrde krlujgea swied. Rs gtrde, roe tjonaen hon ewqtgeeo nwn thme gealwohi hkkedd fesrae pe\n",
+      "kirden wg nrpo, dr gte djduekg iwdg wd dtawocwoq, ptwkt W djuurde wd drlegtwoq, fjg W prjin uaesea\n",
+      "gr ohaarp wg nrpo h fwg lrae. Pwgt gte ihjokt rs Huriir Gpeime krlwoq ju oevg lrogt gte lrrn wd\n",
+      "qeggwoq geode hon W prjin aehiiy iwce gr lhce djae rja lwdktwes lhcea nredo’g thme hoy lrae\n",
+      "djauawded wo dgrae. Gr lhce lhggead prade W tehan gthg gte thpcd hg gte Ueoghqro hae qeggwoq\n",
+      "aedgiedd. Krjin yrj qeg rmea gteae hon swon rjg pthg gtey hae gtwocwoq? Qwmeo gthg rja graleogra\n",
+      "deeld gr thme uaeggy twqt-iemei hkkedd, lhyfe yrj krjin kahoc ju gte dekjawgy ro rja krlld? Lhyfe h\n",
+      "ceypran kwutea firkcen hd dghonhan? Leq\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "2558"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(m_a, s_a, o_a), score_a = affine_break(ca)\n",
+    "print(m_a, s_a, o_a, '\\n')\n",
+    "print(lcat(tpack(affine_decipher(ca, m_a, s_a, o_a).split())))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('saturn', <KeywordWrapAlphabet.from_largest: 3>, -2573.856474269662)"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(key_a, wrap_a), score_a = keyword_break_mp(ca)\n",
+    "key_a, wrap_a, score_a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "harry, i wanted to be certain the lost apollo ten report really wasn’t an accident so i asked\n",
+      "archives to search the mission papers in case the original report had been misfiled. they searched\n",
+      "everything and couldn’t find it but then someone had a brainwave and checked the apollo eleven\n",
+      "files. to everyone’s relief they found it there and the archivist reckoned that someone got\n",
+      "distracted. with the volume of mission papers they are handling this is not a surprise, but given\n",
+      "the importance of these documents it is a bit alarming and doesn’t feel like the way nasa usually\n",
+      "does things. anyway, the find should have reassured me, and it would have if i hadn’t looked so\n",
+      "carefully at the file. everything looked fine except that the word injection in the penultimate\n",
+      "paragraph was spelt with an i. you may not be surprised, but if you look at the decrypt of the\n",
+      "mangled version it is misspelt lnjection, with an l replacing the i. i wouldn’t have noticed but i\n",
+      "had decrypted the original by hand and was surprised by the typo. it stuck in my mind so when i saw\n",
+      "the filed version without it that rang alarm bells. once we started investigating we locked up the\n",
+      "computer files so i can only assume that the filed version was transcribed by someone who now has\n",
+      "access to the printed version but who doesn’t have the clearance to access the original. the\n",
+      "question is, why would they produce a new version? i can only think that they wanted to head off\n",
+      "more investigation by giving us a reason to think it was all a mistake after all. if that was the\n",
+      "plan then it hasn’t worked. it seems clear to me that someone really does have something to hide. i\n",
+      "checked the security clearance list and there were two hundred and thirty-seven people with access\n",
+      "to the archive room where we are storing the investigation files who do not also have current access\n",
+      "to those computer files. of those, one hundred and eighteen did have terminal access before we\n",
+      "closed it down, so the suspect list is shrinking, which i suppose is something, but i would prefer\n",
+      "to narrow it down a bit more. with the launch of apollo twelve coming up next month the mood is\n",
+      "getting tense and i would really like to make sure our mischief maker doesn’t have any more\n",
+      "surprises in store. to make matters worse i heard that the hawks at the pentagon are getting\n",
+      "restless. could you get over there and find out what they are thinking? given that our tormentor\n",
+      "seems to have pretty high-level access, maybe you could crank up the security on our comms? maybe a\n",
+      "keyword cipher blocked as standard? meg\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(keyword_decipher(ca, key_a, wrap_a).split())))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Harry,\n",
+      "\n",
+      "I wanted to be certain the lost Apollo Ten report really wasn’t an accident so I asked archives to search the mission papers in case the original report had been misfiled. They searched everything and couldn’t find it but then someone had a brainwave and checked the Apollo eleven files. To everyone’s relief they found it there and the archivist reckoned that someone got distracted. With the volume of mission papers they are handling this is not a surprise, but given the importance of these documents it is a bit alarming and doesn’t feel like the way NASA usually does things. Anyway, the find should have reassured me, and it would have if I hadn’t looked so carefully at the file. Everything looked fine except that the word Injection in the penultimate paragraph was spelt with an I. You may not be surprised, but if you look at the decrypt of the mangled version it is misspelt lnjection, with an l replacing the I.\n",
+      "\n",
+      "I wouldn’t have noticed but I had decrypted the original by hand and was surprised by the typo. It stuck in my mind so when I saw the filed version without it that rang alarm bells. Once we started investigating we locked up the computer files so I can only assume that the filed version was transcribed by someone who now has access to the printed version but who doesn’t have the clearance to access the original. The question is, why would they produce a new version? I can only think that they wanted to head off more investigation by giving us a reason to think it was all a mistake after all. If that was the plan then it hasn’t worked. It seems clear to me that someone really does have something to hide.\n",
+      "\n",
+      "I checked the security clearance list and there were two hundred and thirty-seven people with access to the archive room where we are storing the investigation files who do not also have current access to those computer files. Of those, one hundred and eighteen did have terminal access before we closed it down, so the suspect list is shrinking, which I suppose is something, but I would prefer to narrow it down a bit more. With the launch of Apollo Twelve coming up next month the mood is getting tense and I would really like to make sure our mischief maker doesn’t have any more surprises in store.\n",
+      "\n",
+      "To make matters worse I heard that the hawks at the Pentagon are getting restless. Could you get over there and find out what they are thinking? Given that our tormentor seems to have pretty high-level access, maybe you could crank up the security on our comms? Maybe a keyword cipher blocked as standard?\n",
+      "\n",
+      "Meg\n",
+      "\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "2564"
+      ]
+     },
+     "execution_count": 21,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "print(repunctuate(keyword_decipher(ca, key_a, wrap_a), pta))\n",
+    "open('3a.plaintext', 'w').write(repunctuate(keyword_decipher(ca, key_a, wrap_a), pta))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('stunk', <KeywordWrapAlphabet.from_last: 2>, -2377.4918717301703)"
+      ]
+     },
+     "execution_count": 23,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(key_b, wrap_b), score_b = keyword_break_mp(scb)\n",
+    "key_b, wrap_b, score_b"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "MEGIS PENTL AOUPC EOFBL YSOVE RLTTD EPENT LGONH RIEFI NGTDE STLFF LNBTR YINGT OGLUG ETDEM OOBTD EREYO ULRER IGDTT DEDLW KSLRE GETTI NGPRE TTYRE STCES SLNBD LVEMO REORC ESSBE AIBEB LCREL BYTDL TTDES OVIET SLRET OHCLM EFORR EAENT EVENT SONTD ELPOC COPRO GRLMM ESOME OFTDE GENER LCSBO NTNEE BMUAD OFLNE XAUSE TOTUR NUPTD EDELT HUTYO UBONT GETFO URSTL RSWIT DOUTU NBERS TLNBI NGTDE NEEBF ORPOC ITIAL CSUPP ORTLN BTDER EDLSH EENLA ONAER TEBWD ISPER INGAL MPLIG NTOAO NVINA ETDEP RESIB ENTTO TLKEL STRON GCINE TDEMO STSTR IBENT LREAL CCING FORLC LRGEH UICBU POFFO RAESL CONGT DEHOR BERWI TDELS TGERM LNYLS LSDOW OFSTR ENGTD LRGUI NGTDL TTDEL TTLAK ONTDE SPLAE PROGR LMMEM USTDL VEHEE NLUTD ORISE BHYTD EPOCI THURO TDLTM LKESN OSENS ETOME FIRST TDERU SSILN SLREM ORECI KECYT OTRYT OWINT DEPRO PLGLN BLWLR TDLNT ORISK AONFC IATLN BSEAO NBTDE SLHOT LGEIF TDLTI SWDLT ITISI SNTSO PDIST IALTE BENOU GDFOR LKGHO PERLT IONHU TITIS DLRBT OAONV INAET DEGEN ERLCS TDLTT DLTIS TRUES OMEOF TDEMO REALU TIOUS PCLNN ERSMO STCYT DOSEW DOLAT ULCCY FOUGD TINTD ECLST WLRDL VEMLN LGEBT OHCOA KTDEH UICBU PPROP OSING LNEWT RLNAD EOFWL RGLME SINST ELBMO HICIS INGTD LTWLY ISSTI CCLPR OVOAL TIONH UTISC ESSCI KECYT OLAAI BENTL CCYTR IGGER LWLRE SPEAI LCCYI FWENO TIFYP LVCOV SKYIN LBVLN AELCC TDESL MEMYO WNTIM EINHE RCINA ONVIN AEBME WEDLV ETOTR ELBVE RYSOF TCYTD ERESO IDELB EBOVE RTOCL NGCEY LNBAO NVINA EBTDE MTOSU GGEST LNLCT ERNLT IVEWE WICCS TEPUP INSPE ATION SLTAD EAKPO INTAD LRCIE TOMLK EITDL RBERF ORSOV IETLG ENTST OAROS SLNBA RLNKU PTDET EUFEC SHERG CISTE NINGO PERLT IONTO SEEIF TDLTT URNSU PLNYT DINGR ECLTE BILML CSOGO INGTO SENBL AOUPC EOFOU RHEST OVERT OHLIK ONURT OTRYL NBFIN BOUTW DLTIS GOING ONTDE RETDE SOVIE TSLRE PRETT YSEAR ETIVE LHOUT TDEIR OWNSP LAEPR OGRLM MELNB WITDO UTTDE WORCB SPRES SWLTA DINGW EBONT RELCC YDLVE LACEL RPIAT UREOF TDEIR PROGR ESSOR TDEIR PCLNS UNCES STDEY LREAC OSETO PUTTI NGTDE IROWN MENON TDEMO ONIAL NTSEE WDLTT DEYDL VETOG LINWI TDWDL TSEEM STOHE LFLIR CYBIS ORGLN ISEBL TTEMP TTOBE RLICO URSPL AEPRO GRLMM EHUTI WOUCB STICC CIKET OKNOW WDLTT DEYLR EUPTO KEEPL ACOSE EYEON TDEMI SSION PCLNN INGLN BCETM EKNOW IFYOU DELRL NYTDI NGWOR RYING IWICC HEHLA KLHOU TLWEE KHEFO RETDE CLUNA DDLRR Y\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(repunctuate(keyword_decipher(scb, key_b, wrap_b), ptb))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "1 10 True \n",
+      "\n",
+      "MACFS PANTL IOUPK AOBJL YSOVA RLTTD APANT LCONE RFABF NCTDA STLBB LNJTR YFNCT OCLUC ATDAM OOJTD ARAYO ULRAR FCDTT DADLW HSLRA CATTF NCPRA TTYRA STKAS SLNJD LVAMO RAORK ASSJA IFJAJ LKRAL JYTDL TTDAS OVFAT SLRAT OEKLM ABORR AIANT AVANT SONTD ALPOK KOPRO CRLMM ASOMA OBTDA CANAR LKSJO NTNAA JMUID OBLNA XIUSA TOTUR NUPTD ADALT EUTYO UJONT CATBO URSTL RSWFT DOUTU NJARS TLNJF NCTDA NAAJB ORPOK FTFIL KSUPP ORTLN JTDAR ADLSE AANLI ONIAR TAJWD FSPAR FNCIL MPLFC NTOIO NVFNI ATDAP RASFJ ANTTO TLHAL STRON CKFNA TDAMO STSTR FJANT LRAIL KKFNC BORLK LRCAE UFKJU POBBO RIASL KONCT DAEOR JARWF TDALS TCARM LNYLS LSDOW OBSTR ANCTD LRCUF NCTDL TTDAL TTLIH ONTDA SPLIA PROCR LMMAM USTDL VAEAA NLUTD ORFSA JEYTD APOKF TEURO TDLTM LHASN OSANS ATOMA BFRST TDARU SSFLN SLRAM ORAKF HAKYT OTRYT OWFNT DAPRO PLCLN JLWLR TDLNT ORFSH IONBK FITLN JSAIO NJTDA SLEOT LCAFB TDLTF SWDLT FTFSF SNTSO PDFST FILTA JANOU CDBOR LHCEO PARLT FONEU TFTFS DLRJT OIONV FNIAT DACAN ARLKS TDLTT DLTFS TRUAS OMAOB TDAMO RAILU TFOUS PKLNN ARSMO STKYT DOSAW DOLIT ULKKY BOUCD TFNTD AKLST WLRDL VAMLN LCAJT OEKOI HTDAE UFKJU PPROP OSFNC LNAWT RLNID AOBWL RCLMA SFNST ALJMO EFKFS FNCTD LTWLY FSSTF KKLPR OVOIL TFONE UTFSK ASSKF HAKYT OLIIF JANTL KKYTR FCCAR LWLRA SPAIF LKKYF BWANO TFBYP LVKOV SHYFN LJVLN IALKK TDASL MAMYO WNTFM AFNEA RKFNI ONVFN IAJMA WADLV ATOTR ALJVA RYSOB TKYTD ARASO FDALJ AJOVA RTOKL NCKAY LNJIO NVFNI AJTDA MTOSU CCAST LNLKT ARNLT FVAWA WFKKS TAPUP FNSPA ITFON SLTID AIHPO FNTID LRKFA TOMLH AFTDL RJARB ORSOV FATLC ANTST OIROS SLNJI RLNHU PTDAT AUBAK SEARC KFSTA NFNCO PARLT FONTO SAAFB TDLTT URNSU PLNYT DFNCR AKLTA JFLML KSOCO FNCTO SANJL IOUPK AOBOU REAST OVART OELFH ONURT OTRYL NJBFN JOUTW DLTFS COFNC ONTDA RATDA SOVFA TSLRA PRATT YSAIR ATFVA LEOUT TDAFR OWNSP LIAPR OCRLM MALNJ WFTDO UTTDA WORKJ SPRAS SWLTI DFNCW AJONT RALKK YDLVA LIKAL RPFIT URAOB TDAFR PROCR ASSOR TDAFR PKLNS UNKAS STDAY LRAIK OSATO PUTTF NCTDA FROWN MANON TDAMO ONFIL NTSAA WDLTT DAYDL VATOC LFNWF TDWDL TSAAM STOEA LBLFR KYJFS ORCLN FSAJL TTAMP TTOJA RLFKO URSPL IAPRO CRLMM AEUTF WOUKJ STFKK KFHAT OHNOW WDLTT DAYLR AUPTO HAAPL IKOSA AYAON TDAMF SSFON PKLNN FNCLN JKATM AHNOW FBYOU DALRL NYTDF NCWOR RYFNC FWFKK EAELI HLEOU TLWAA HEABO RATDA KLUNI DDLRR Y\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "(m_b, s_b, o_b), score_a = affine_break(scb)\n",
+    "print(m_b, s_b, o_b, '\\n')\n",
+    "print(affine_decipher(cb, m_b, s_b, o_b))\n",
+    "# open('3b.plaintext', 'w').write(affine_decipher(cb, m_b, s_b, o_b))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 69,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('vostklmnpqruwxyzabcdefghij',\n",
+       " 'megispentacoupleofdaysoveratthepentagonbriefingthestaffandtryingtogaugethemoodthereyouarerightthehawksaregettingprettyrestlessandhavemoreorlessdecidedalreadythatthesovietsaretoblameforrecenteventsontheapolloprogrammesomeofthegeneralsdontneedmuchofanexcusetoturnuptheheatbutyoudontgetfourstarswithoutunderstandingtheneedforpoliticalsupportandtherehasbeenaconcertedwhisperingcampaigntoconvincethepresidenttotakeastronglinethemoststridentarecallingforalargebuildupofforcesalongtheborderwitheastgermanyasashowofstrengtharguingthattheattackonthespaceprogrammemusthavebeenauthorisedbythepolitburothatmakesnosensetomefirsttherussiansaremorelikelytotrytowinthepropagandawarthantoriskconflictandsecondthesabotageifthatiswhatitisisntsophisticatedenoughforakgboperationbutitishardtoconvincethegeneralsthatthatistruesomeofthemorecautiousplannersmostlythosewhoactuallyfoughtinthelastwarhavemanagedtoblockthebuildupproposinganewtrancheofwargamesinsteadmobilisingthatwayisstillaprovocationbutislesslikelytoaccidentallytriggerawarespeciallyifwenotifypavlovskyinadvanceallthesamemyowntimeinberlinconvincedmewehavetotreadverysoftlytheresoiheadedovertolangleyandconvincedthemtosuggestanalternativewewillstepupinspectionsatcheckpointcharlietomakeitharderforsovietagentstocrossandcrankuptheteufelsberglisteningoperationtoseeifthatturnsupanythingrelatediamalsogoingtosendacoupleofourbestovertobaikonurtotryandfindoutwhatisgoingontherethesovietsareprettysecretiveabouttheirownspaceprogrammeandwithouttheworldspresswatchingwedontreallyhaveaclearpictureoftheirprogressortheirplansunlesstheyareclosetoputtingtheirownmenonthemoonicantseewhattheyhavetogainwithwhatseemstobeafairlydisorganisedattempttoderailourspaceprogrammebutiwouldstillliketoknowwhattheyareuptokeepacloseeyeonthemissionplanningandletmeknowifyouhearanythingworryingiwillbebackaboutaweekbeforethelaunchharry')"
+      ]
+     },
+     "execution_count": 69,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "key_b, score_b = simulated_annealing_break(scb, fitness=Ptrigrams)\n",
+    "key_b, keyword_decipher(scb, key_b, KeywordWrapAlphabet.from_last)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 70,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "megis penta couple of days over at the pentagon briefing the staff and trying to gauge the mood\n",
+      "there you are right the hawks are getting pretty restless and have more or less decided already that\n",
+      "the soviets are to blame for recent events on the apollo programme some of the generals dont need\n",
+      "much of an excuse to turn up the heat but you dont get four stars without understanding the need for\n",
+      "political support and there has been a concerted whispering campaign to convince the president to\n",
+      "take a strong line the most strident are calling for a large buildup of forces along the border with\n",
+      "east germany as a show of strength arguing that the attack on the space programme must have been\n",
+      "authorised by the politburo that makes no sense to me first the russians are more likely to try to\n",
+      "win the propaganda war than to risk conflict and second the sabotage if that is what it is isnt\n",
+      "sophisticated enough for a kgb operation but it is hard to convince the generals that that is true\n",
+      "some of the more cautious planners mostly those who actually fought in the last war have managed to\n",
+      "block the buildup proposing a new tranche of wargames instead mobilising that way is still a\n",
+      "provocation but is less likely to accidentally trigger aware specially if we notify pavlovsky in\n",
+      "advance all the same my own time in berlin convinced me we have to tread very softly there so i\n",
+      "headed over to langley and convinced them to suggest an alternative we will step up inspections at\n",
+      "checkpoint charlie to make it harder for soviet agents to cross and crank up the teufel s berg\n",
+      "listening operation to see if that turns up anything related i am also going to send a couple of our\n",
+      "best over to baikonur to try and find out what is going on there the soviets are pretty secretive\n",
+      "about their own space programme and without the worlds press watching we dont really have a clear\n",
+      "picture of their progress or their plans unless they are close to putting their own men on the moon\n",
+      "icant see what they have to gain with what seems to be a fairly disorganised attempt to derail our\n",
+      "space programme but i would still like to know what they are up to keep a close eye on the mission\n",
+      "planning and let me know if you hear anything worrying i will be back about a week before the launch\n",
+      "harry\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(keyword_decipher(scb, key_b, KeywordWrapAlphabet.from_last)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 72,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "megis penta couple of days over at the pentagon briefing the staff and trying to gauge the mood\n",
+      "there you are right the hawks are getting pretty restless and have more or less decided already that\n",
+      "the soviets are to blame for recent events on the apollo programme some of the generals dont need\n",
+      "much of an excuse to turn up the heat but you dont get four stars without understanding the need for\n",
+      "political support and there has been a concerted whispering campaign to convince the president to\n",
+      "take a strong line the most strident are calling for a large buildup of forces along the border with\n",
+      "east germany as a show of strength arguing that the attack on the space programme must have been\n",
+      "authorised by the politburo that makes no sense to me first the russians are more likely to try to\n",
+      "win the propaganda war than to risk conflict and second the sabotage if that is what it is isnt\n",
+      "sophisticated enough for a kgb operation but it is hard to convince the generals that that is true\n",
+      "some of the more cautious planners mostly those who actually fought in the last war have managed to\n",
+      "block the buildup proposing a new tranche of wargames instead mobilising that way is still a\n",
+      "provocation but is less likely to accidentally trigger aware specially if we notify pavlovsky in\n",
+      "advance all the same my own time in berlin convinced me we have to tread very softly there so i\n",
+      "headed over to langley and convinced them to suggest an alternative we will step up inspections at\n",
+      "checkpoint charlie to make it harder for soviet agents to cross and crank up the teufel s berg\n",
+      "listening operation to see if that turns up anything related i am also going to send a couple of our\n",
+      "best over to baikonur to try and find out what is going on there the soviets are pretty secretive\n",
+      "about their own space programme and without the worlds press watching we dont really have a clear\n",
+      "picture of their progress or their plans unless they are close to putting their own men on the moon\n",
+      "icant see what they have to gain with what seems to be a fairly disorganised attempt to derail our\n",
+      "space programme but i would still like to know what they are up to keep a close eye on the mission\n",
+      "planning and let me know if you hear anything worrying i will be back about a week before the launch\n",
+      "harry\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(keyword_decipher(scb, 'vostok', KeywordWrapAlphabet.from_last)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 73,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2267"
+      ]
+     },
+     "execution_count": 73,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('3b.plaintext', 'w').write(lcat(tpack(segment(keyword_decipher(scb, 'vostok', KeywordWrapAlphabet.from_last)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.8"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/2019/2019-challenge4.ipynb b/2019/2019-challenge4.ipynb
new file mode 100644 (file)
index 0000000..fe5afb2
--- /dev/null
@@ -0,0 +1,376 @@
+{
+ "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": 16,
+   "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",
+    "from cipher.vigenere import *\n",
+    "from support.text_prettify import *\n",
+    "from support.utilities import *\n",
+    "from support.plot_frequency_histogram import *"
+   ]
+  },
+  {
+   "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": 22,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ca = open(ciphertext_a_filename).read()\n",
+    "cb = open(ciphertext_b_filename).read()\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": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "15 21 True \n",
+      "\n",
+      "WES, N GOHE ZEED VKFBNDS TGFKASG TGE INMT KL MAMRNCNKAM NDCNPEDTM OLLECTNDS ORKIIK EIEHED ODP NT NM\n",
+      "IKDSEF TGOD QKA WNSGT TGNDB. TGE RFE-IOADCG, MTOSE TGFEE TGFAMTEF HOIHE RFKZIEW NM O INTTIE\n",
+      "MAMRNCNKAM SNHED OII TGE CGECBM TGOT TKKB RIOCE ZELKFE TGOT, ZAT KD TGE KTGEF GODP TEIEWETFQ\n",
+      "SAOFODTEEP TGOT NT VKAIP ZE PETECTEP ODP TGE TECGDNCNODM MGKVEP TGOT NT VOM EOMQ TK ZQROMM. NL TGOT\n",
+      "VOM O MOZKTOSE OTTEWRT TGED NT VOMD'T HEFQ VEII PEMNSDEP, MK N PKD'T TGNDB NT CKAIP GOHE ZEED OD\n",
+      "EDSNDEEF TGOT MET NT AR. KD TGE KTGEF GODP, DK-KDE EIME VKAIP GOHE GOP TNWE OIKDE VNTG TGE\n",
+      "CKWRKDEDT. KD TGE KTGEF GODP, MKWEKDE LFKW LNPK'M TEOW MEDT WE O WEMMOSE TK TEII WE OZKAT O HEFQ\n",
+      "DEOF WNMM TGOT MKADPM INBE NT CKAIP GOHE ZEED O MEFNKAM OTTEWRT TK PEMTFKQ TGE CKWWODP WKPAIE KD\n",
+      "FE-EDTFQ. OM ORKIIK JN ORRFKOCGEP TGE FE-EDTFQ RKNDT TGEQ UETTNMKDEP TGE MEFHNCE WKPAIE TK FE-KFNEDT\n",
+      "TGE CKWWODP WKPAIE MK TGOT TGE GEOTMGNEIP VOM RKNDTNDS NDTK TGE OTWKMRGEFE. MNDCE TGEQ VEFE KD\n",
+      "RFETTQ WACG O ZOIINMTNC KFZNT TGE MW VKAIP GOHE MTOQEP CIKME TK TGE CW, ODP VNTGKAT O GEOTMGNEIP KL\n",
+      "NTM KVD NT VKAIP ZFEOB AR NDTK IOFSE RNECEM TGOT RKMEP O MNSDNLNCODT PODSEF TK TGE CW ODP NTM CFEV.\n",
+      "TK OHKNP TGOT TGE MW VOM MARRKMEP TK COFFQ KAT O MEYAEDCE KL MGKFT ZAFDM TK WKHE NTM TFOUECTKFQ OVOQ\n",
+      "LFKW TGE CKWWODP WKPAIE, MBNRRNDS NT KLL TGE OTWKMRGEFE MK TGOT TGE CW CKAIP FE-EDTEF LFEE LFKW TGE\n",
+      "PEZFNM LNEIP. ADLKFTADOTEIQ, TGOT PKEMD'T MEEW TK GOHE GORREDEP. OIPFND FERKFTEP TGOT TGE CW LIEV\n",
+      "ROMT TGE MW VGNCG VOM LIQNDS OT OD OTTOCB ODSIE VEII ZEQKDP KREFOTNKDOI ROFOWETEFM, ODP O CKWWEFCNOI\n",
+      "RNIKT, LFODB ZFKVD, FERKFTEP MEENDS TGE TVK MROCECFOLT TFOCBNDS CIKMEIQ OM TGEQ ZAFDEP TGFKASG TGE\n",
+      "OTWKMRGEFE. O MNDSIE CKIINMNKD VNTG KDE KL TGE VGNTE-GKT LFOSWEDTM CKAIP GOHE ZOPIQ POWOSEP TGE\n",
+      "FE-EDTFQ CORMAIE, ODP EHED NL TGE OMTFKDOATM GOP MAFHNHEP TGE CKIINMNKD TGED TGE KPPM OFE TGOT TGE\n",
+      "ROFOCGATE MQMTEW VKAIP GOHE TFNSSEFEP EOFIQ KF ZEED LOTOIIQ POWOSEP ZQ TGE ZIOMT. DOMO EDSNDEEFM OFE\n",
+      "VKFBNDS LOMT TK CKFFECT TGE RFKZIEW LKF ORKIIK JNNN ODP TGEQ GOHE WNTNSOTNKDM ND RIOCE LKF JNN'M\n",
+      "FE-EDTFQ, ZAT TGE HNEV KL TGE EJREFTM NM TGOT TGEQ PKPSEP O ZAIIET VNTG TGNM. TGE LINSGT KLLNCEF VGK\n",
+      "FERKFTEP NT TK WE RKNDTEP KAT TGOT NL TGE MKHNETM VODTEP TK MOZKTOSE TGE WNMMNKD TGNM WNSGT GOHE\n",
+      "ZEED O SKKP ZET: NT VOM O DOMTQ OCCNPEDT TGOT VOM GOFP TK LKFEMEE, ODP NT VNII ZE HEFQ PNLLNCAIT TK\n",
+      "MGKV TGOT MKWEKDE PEINZEFOTEIQ WNMCOICAIOTEP TGE ZAFD TNWEM MNDCE NT VOM TGE NDTEFOCTNKD KL TGE\n",
+      "TGFAMTEFM ODP MTOZNINMEFM TGOT COAMEP TGE RFKZIEW. N TGNDB GE NM KDE KL O SFKVNDS DAWZEF KL DOMO\n",
+      "EWRIKQEEM VGK GOHE ZESAD TK ZEINEHE TGOT TGE AMMF GOM PEER CKHEF OSEDTM VKFBNDS TK PEMTOZNINME TGE\n",
+      "RFKSFOWWE. WQ VKFFQ NM TGOT EHED NL GE NM VFKDS, TGE IOCB KL TFAMT TGOT NM SFKVNDS VNTGND TGE\n",
+      "KFSODNMOTNKD VNII PEMTOZNINME NT KD NTM KVD. N OW FEOIIQ GKRNDS GE NM WNMTOBED. TGE MACCEMM KL\n",
+      "ORKIIK JN MEEWM TK GOHE ZKASGT O IKT KL NDTEFDOTNKDOI SKKPVNII ODP N TGNDB NT CKAIP ZE TGE MTOFT KL\n",
+      "MKWETGNDS WKFE RKMNTNHE. TGE MKHNET CKKREFOTNKD VNTG TGE IODPNDS SOHE WE GKRE TGOT VE CKAIP LNDP\n",
+      "WKFE CKWWKD SFKADP ODP MTOFT TK TGOV EOMT-VEMT FEIOTNKDM, ZAT TGNM CKAIP FEOIIQ TGFEOTED TGOT. ND\n",
+      "TGE WEOD-TNWE VE GOP ZETTEF MTER AR MECAFNTQ. N TGNDB VE MGKAIP AME O MNWRIE HNSEDEFE CNRGEF VNTG\n",
+      "REFNKP TVK LKF KAF DEJT WEMMOSE. N GOHE EDCFQRTEP TGE OTTOCGEP FE-EDTFQ FERKFT AMNDS O CKIAWDOF\n",
+      "TFODMRKMNTNKD CNRGEF\n"
+     ]
+    }
+   ],
+   "source": [
+    "(m_a, s_a, o_a), score_a = affine_break(ca)\n",
+    "print(m_a, s_a, o_a, '\\n')\n",
+    "print(lcat(tpack(affine_decipher(ca, m_a, s_a, o_a).split())))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('lunar', <KeywordWrapAlphabet.from_last: 2>, -3366.553587533618)"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(key_a, wrap_a), score_a = keyword_break_mp(ca)\n",
+    "key_a, wrap_a, score_a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "meg, i have been working through the list of suspicious incidents affecting apollo eleven and it is\n",
+      "longer than you might think. the pre-launch, stage three thruster valve problem is a little\n",
+      "suspicious given all the checks that took place before that, but on the other hand telemetry\n",
+      "guaranteed that it would be detected and the technicians showed that it was easy to bypass. if that\n",
+      "was a sabotage attempt then it wasn't very well designed, so i don't think it could have been an\n",
+      "engineer that set it up. on the other hand, no-one else would have had time alone with the\n",
+      "component. on the other hand, someone from fido's team sent me a message to tell me about a very\n",
+      "near miss that sounds like it could have been a serious attempt to destroy the command module on\n",
+      "re-entry. as apollo xi approached the re-entry point they jettisoned the service module to re-orient\n",
+      "the command module so that the heatshield was pointing into the atmosphere. since they were on\n",
+      "pretty much a ballistic orbit the sm would have stayed close to the cm, and without a heatshield of\n",
+      "its own it would break up into large pieces that posed a significant danger to the cm and its crew.\n",
+      "to avoid that the sm was supposed to carry out a sequence of short burns to move its trajectory away\n",
+      "from the command module, skipping it off the atmosphere so that the cm could re-enter free from the\n",
+      "debris field. unfortunately, that doesn't seem to have happened. aldrin reported that the cm flew\n",
+      "past the sm which was flying at an attack angle well beyond operational parameters, and a commercial\n",
+      "pilot, frank brown, reported seeing the two spacecraft tracking closely as they burned through the\n",
+      "atmosphere. a single collision with one of the white-hot fragments could have badly damaged the\n",
+      "re-entry capsule, and even if the astronauts had survived the collision then the odds are that the\n",
+      "parachute system would have triggered early or been fatally damaged by the blast. nasa engineers are\n",
+      "working fast to correct the problem for apollo xiii and they have mitigations in place for xii's\n",
+      "re-entry, but the view of the experts is that they dodged a bullet with this. the flight officer who\n",
+      "reported it to me pointed out that if the soviets wanted to sabotage the mission this might have\n",
+      "been a good bet: it was a nasty accident that was hard to foresee, and it will be very difficult to\n",
+      "show that someone deliberately miscalculated the burn times since it was the interaction of the\n",
+      "thrusters and stabilisers that caused the problem. i think he is one of a growing number of nasa\n",
+      "employees who have begun to believe that the ussr has deep cover agents working to destabilise the\n",
+      "programme. my worry is that even if he is wrong, the lack of trust that is growing within the\n",
+      "organisation will destabilise it on its own. i am really hoping he is mistaken. the success of\n",
+      "apollo xi seems to have bought a lot of international goodwill and i think it could be the start of\n",
+      "something more positive. the soviet cooperation with the landing gave me hope that we could find\n",
+      "more common ground and start to thaw east-west relations, but this could really threaten that. in\n",
+      "the mean-time we had better step up security. i think we should use a simple vigenere cipher with\n",
+      "period two for our next message. i have encrypted the attached re-entry report using a columnar\n",
+      "transposition cipher\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(keyword_decipher(ca, key_a, wrap_a).split())))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "MEG,\n",
+      "I HAVE BEEN WORKING THROUGH THE LIST OF SUSPICIOUS INCIDENTS AFFECTING APOLLO ELEVEN AND IT IS LONGER THAN YOU MIGHT THINK. THE PRE-LAUNCH, STAGE THREE THRUSTER VALVE PROBLEM IS A LITTLE SUSPICIOUS GIVEN ALL THE CHECKS THAT TOOK PLACE BEFORE THAT, BUT ON THE OTHER HAND TELEMETRY GUARANTEED THAT IT WOULD BE DETECTED AND THE TECHNICIANS SHOWED THAT IT WAS EASY TO BYPASS. IF THAT WAS A SABOTAGE ATTEMPT THEN IT WASN'T VERY WELL DESIGNED, SO I DON'T THINK IT COULD HAVE BEEN AN ENGINEER THAT SET IT UP. ON THE OTHER HAND, NO-ONE ELSE WOULD HAVE HAD TIME ALONE WITH THE COMPONENT. ON THE OTHER HAND, SOMEONE FROM FIDO'S TEAM SENT ME A MESSAGE TO TELL ME ABOUT A VERY NEAR MISS THAT SOUNDS LIKE IT COULD HAVE BEEN A SERIOUS ATTEMPT TO DESTROY THE COMMAND MODULE ON RE-ENTRY.\n",
+      "AS APOLLO XI APPROACHED THE RE-ENTRY POINT THEY JETTISONED THE SERVICE MODULE TO RE-ORIENT THE COMMAND MODULE SO THAT THE HEATSHIELD WAS POINTING INTO THE ATMOSPHERE. SINCE THEY WERE ON PRETTY MUCH A BALLISTIC ORBIT THE SM WOULD HAVE STAYED CLOSE TO THE CM, AND WITHOUT A HEATSHIELD OF ITS OWN IT WOULD BREAK UP INTO LARGE PIECES THAT POSED A SIGNIFICANT DANGER TO THE CM AND ITS CREW. TO AVOID THAT THE SM WAS SUPPOSED TO CARRY OUT A SEQUENCE OF SHORT BURNS TO MOVE ITS TRAJECTORY AWAY FROM THE COMMAND MODULE, SKIPPING IT OFF THE ATMOSPHERE SO THAT THE CM COULD RE-ENTER FREE FROM THE DEBRIS FIELD. UNFORTUNATELY, THAT DOESN'T SEEM TO HAVE HAPPENED. ALDRIN REPORTED THAT THE CM FLEW PAST THE SM WHICH WAS FLYING AT AN ATTACK ANGLE WELL BEYOND OPERATIONAL PARAMETERS, AND A COMMERCIAL PILOT, FRANK BROWN, REPORTED SEEING THE TWO SPACECRAFT TRACKING CLOSELY AS THEY BURNED THROUGH THE ATMOSPHERE. A SINGLE COLLISION WITH ONE OF THE WHITE-HOT FRAGMENTS COULD HAVE BADLY DAMAGED THE RE-ENTRY CAPSULE, AND EVEN IF THE ASTRONAUTS HAD SURVIVED THE COLLISION THEN THE ODDS ARE THAT THE PARACHUTE SYSTEM WOULD HAVE TRIGGERED EARLY OR BEEN FATALLY DAMAGED BY THE BLAST. NASA ENGINEERS ARE WORKING FAST TO CORRECT THE PROBLEM FOR APOLLO XIII AND THEY HAVE MITIGATIONS IN PLACE FOR XII'S RE-ENTRY, BUT THE VIEW OF THE EXPERTS IS THAT THEY DODGED A BULLET WITH THIS. THE FLIGHT OFFICER WHO REPORTED IT TO ME POINTED OUT THAT IF THE SOVIETS WANTED TO SABOTAGE THE MISSION THIS MIGHT HAVE BEEN A GOOD BET: IT WAS A NASTY ACCIDENT THAT WAS HARD TO FORESEE, AND IT WILL BE VERY DIFFICULT TO SHOW THAT SOMEONE DELIBERATELY MISCALCULATED THE BURN TIMES SINCE IT WAS THE INTERACTION OF THE THRUSTERS AND STABILISERS THAT CAUSED THE PROBLEM. I THINK HE IS ONE OF A GROWING NUMBER OF NASA EMPLOYEES WHO HAVE BEGUN TO BELIEVE THAT THE USSR HAS DEEP COVER AGENTS WORKING TO DESTABILISE THE PROGRAMME. MY WORRY IS THAT EVEN IF HE IS WRONG, THE LACK OF TRUST THAT IS GROWING WITHIN THE ORGANISATION WILL DESTABILISE IT ON ITS OWN. I AM REALLY HOPING HE IS MISTAKEN. THE SUCCESS OF APOLLO XI SEEMS TO HAVE BOUGHT A LOT OF INTERNATIONAL GOODWILL AND I THINK IT COULD BE THE START OF SOMETHING MORE POSITIVE. THE SOVIET COOPERATION WITH THE LANDING GAVE ME HOPE THAT WE COULD FIND MORE COMMON GROUND AND START TO THAW EAST-WEST RELATIONS, BUT THIS COULD REALLY THREATEN THAT.\n",
+      "IN THE MEAN-TIME WE HAD BETTER STEP UP SECURITY. I THINK WE SHOULD USE A SIMPLE VIGENERE CIPHER WITH PERIOD TWO FOR OUR NEXT MESSAGE. I HAVE ENCRYPTED THE ATTACHED RE-ENTRY REPORT USING A COLUMNAR TRANSPOSITION CIPHER\n",
+      "\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "3344"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "print(repunctuate(keyword_decipher(ca, key_a, wrap_a), pta))\n",
+    "open(plaintext_a_filename, 'w').write(repunctuate(keyword_decipher(ca, key_a, wrap_a), pta))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(((2, 4, 3, 1, 0, 6, 5), False, True), -7729.531557000563)"
+      ]
+     },
+     "execution_count": 23,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(key_b, fillcolumnwise_b, emptycolumnwise_b), score_b = column_transposition_break_mp(scb, fitness=Ptrigrams)\n",
+    "(key_b, fillcolumnwise_b, emptycolumnwise_b), score_b"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(((6, 5, 4, 3, 2, 1, 0), False, False), -8768.791674998944)"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# (key_b, fillcolumnwise_b, emptycolumnwise_b), score_b = column_transposition_break_mp(scb, fitness=Pbigrams)\n",
+    "# (key_b, fillcolumnwise_b, emptycolumnwise_b), score_b"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'apolloxipostflightanalysisspacecraftreentrytrajectoryreviewthisdocumentcontainsinformationabouttheeventsduringthereentryphaseofapolloxiithasbeencompiledtosatisfyflightplanningsafetyrequirementsthereviewcoversthefollowingmissionphasetransearthcoastwhichendswithreentryintothemidpacificrecoveryareatheoriginalflightplancalledforseparationofthecmfromthesmtwelveminutesbeforeentryinterfacesuccessfulseparationwouldthentriggerasequenceofburnsintendedtostabilisetheservicemoduleandtomoveitoutofthereentrycorridortoavoiddebriscollisionswiththecommandmoduleduringthereentryphasethereactioncontrolsystemburnsequenceinvolvedboththerollandtheminusxjetstheattitudeburnswereintendedtosetuparollinordertostabiliseremainingfuelandtopreventuncontrolledgyrationduringtheboostthatwouldhavethentakenthesmoutofthereentrycorridorintoahighaltitudeorbitthatwoulddecayonlyafterthecommandmodulehadlandedintheeventthesequenceofburnsdidnotachievetherequiredtrajectoryshiftwithreportsfromtheastronautsonboardandfromacommercialairlinepilotthatthetwospacevehiclesreenteredtheatmospheretogetherwiththecmpassingthesmduringtheplasmaburnphasegiventheproximityofthevehiclesduringreentryitisconsideredhighlyfortunatethatnodebrisfromtherelativelyunprotectedsmstruckthecmandsimulationsshowthatsuchastrikewouldhavebeenlikelytocausecatastrophicdamagetothecmpossibledefectsarisingfromacollisionincludeiheatshielddamageevenaminorcrackinoneoftheheatshieldpanelswouldbelikelytocausesuperheatingwhichcouldbreachthehullleadingtofurthercatastrophicdamagetothevehiclewithprobablelossoflifeiiprematurefiringoftheparachutepyrotechnicsleadingtofullorpartiallossofthedescentarrestsystemandlossoflifeiiidamagetotheparachuteshieldmighthavepreventedthepyrotechnicsfromreleasingtheparachutesleadingtoacatastrophiccollisiononlandingandlossoflifeivdamagetooneormoreoftheparachutescouldhaveledtoahighvelocityimpactwithprobableresultinginjuriesandpossiblelossoflifethehighlikelihoodofcatastrophicfailurearisingfromthedeviationfromflightparametersmeansthatfurtheranalysisoftheseparationburnstrategyisrequiredpendingthatremediationfortheapolloxiireentrytrajectoryisahighpriorityitissuggestedthatsurplusfuelshouldbeejectedfromthesmbeforetheseparationburnbeginsinordertostabilisetheattitudeandthattheminusxburnsshouldbetimedtocoincidewiththerolljetstoimprovestability'"
+      ]
+     },
+     "execution_count": 24,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "column_transposition_decipher(scb, key_b, fillcolumnwise=fillcolumnwise_b, emptycolumnwise=emptycolumnwise_b)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "apollo xi post flight analysis spacecraft reentry trajectory review this document contains\n",
+      "information about the events during there entry phase of apollo xiith as been compiled to satisfy\n",
+      "flight planning safety requirements the review covers the following mission phase trans earth coast\n",
+      "which ends with reentry into the mid pacific recovery area the original flightplan called for\n",
+      "separation of the cm from the sm twelve minutes before entry interface successful separation would\n",
+      "then trigger a sequence of burns intended to stabilise the service module and to move it out of\n",
+      "there entry corridor to avoid debris collisions with the command module during there entry phase the\n",
+      "reaction control system burn sequence involved both the roll and the minus x jets the attitude burns\n",
+      "were intended to setup a rollin order to stabilise remaining fuel and to prevent uncontrolled\n",
+      "gyration during the boost that would have then taken the sm out of there entry corridor into a high\n",
+      "altitude orbit that would decay only after the command module had landed in the event the sequence\n",
+      "of burns did not achieve the required trajectory shift with reports from the astronauts onboard and\n",
+      "from a commercial airline pilot that the two space vehicles reentered the atmosphere together with\n",
+      "the cm passing the sm during the plasma burn phase given the proximity of the vehicles during\n",
+      "reentry it is considered highly fortunate that no debris from the relatively unprotected sms truck\n",
+      "the cm and simulations show that such a strike would have been likely to cause catastrophic damage\n",
+      "to the cm possible defects arising from a collision include i heatshield damage even a minor crack\n",
+      "in one of the heatshield panels would be likely to cause super heating which could breach the hull\n",
+      "leading to further catastrophic damage to the vehicle with probable loss of life ii premature firing\n",
+      "of the parachute pyrotechnics leading to full or partial loss of the descent arrest system and loss\n",
+      "of life iii damage to the parachute shield might have prevented the pyrotechnics from releasing the\n",
+      "parachutes leading to a catastrophic collision on landing and loss of life iv damage to one or more\n",
+      "of the parachutes could have led to a high velocity impact with probable resulting injuries and\n",
+      "possible loss of life the high likelihood of catastrophic failure arising from the deviation from\n",
+      "flight parameters means that further analysis of the separation burn strategy is required pending\n",
+      "that remediation for the apollo xii reentry trajectory is a high priority it is suggested that\n",
+      "surplus fuel should be ejected from the sm before the separation burn begins in order to stabilise\n",
+      "the attitude and that the minus x burns should be timed to coincide with the roll jets to improve\n",
+      "stability\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(column_transposition_decipher(scb, key_b, fillcolumnwise=fillcolumnwise_b, emptycolumnwise=emptycolumnwise_b)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2756"
+      ]
+     },
+     "execution_count": 26,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_b_filename, 'w').write(lcat(tpack(segment(column_transposition_decipher(scb, key_b, fillcolumnwise=fillcolumnwise_b, emptycolumnwise=emptycolumnwise_b)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.8"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/2019/2019-challenge5.ipynb b/2019/2019-challenge5.ipynb
new file mode 100644 (file)
index 0000000..e9baad8
--- /dev/null
@@ -0,0 +1,246 @@
+{
+ "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",
+    "from cipher.vigenere import *\n",
+    "from support.text_prettify import *\n",
+    "from support.utilities import *\n",
+    "from support.plot_frequency_histogram import *"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "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": 43,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ca = open(ciphertext_a_filename).read()\n",
+    "cb = open(ciphertext_b_filename).read()\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)\n",
+    "\n",
+    "rcb = cat(reversed(cb))\n",
+    "rscb = sanitise(rcb)\n",
+    "ptrb = depunctuate(rcb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 62,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('solar', <KeywordWrapAlphabet.from_last: 2>, -2436.5996155834796)"
+      ]
+     },
+     "execution_count": 62,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(key_a, wrap_a), score_a = keyword_break_mp(sca)\n",
+    "key_a, wrap_a, score_a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 63,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "harry mike has turned out to be really useful following his report to you about the apollo xine arm\n",
+      "is she has turned up a number of other computer reports hinting at possible sabotage attempts on\n",
+      "viii through xii some of them we already knew about the guidance problems with apollo x and the\n",
+      "programme alarms and descent trajectory problems on xi but he also showed me some files from the\n",
+      "building and maintenance logs for the future apollo fleet and pointed out some worrying lapses in\n",
+      "particular there is a gap in the records of the apollo xiii service modules owe are running a few\n",
+      "checks before assembly to make sure everything is okay before launch my first instinct was to place\n",
+      "everything on hold while we tracked down the saboteur but the whole building launch process is a\n",
+      "fine tuned machine and i am worried that if we disrupt it then we might cause more problems in\n",
+      "particular it will be easier to detect unexpected behaviour if we know exactly what to expect mike\n",
+      "is really worried that the soviets could have infiltrated the program he has never for given them\n",
+      "for the death of his son who was shot down by a mig over the korean peninsula i am hoping that his\n",
+      "grief will drive him to help us get to the bottom of this mystery for now we have another problem my\n",
+      "team at langley were tipped off by a journalist at the newyork post about an encrypted letter sent\n",
+      "to the newsdesk there it came with a cover note which said that the cipher key would be published in\n",
+      "the wanted ads but there area lot of those spread over hundreds of newspapers and the editor didnt\n",
+      "want to devote hours of staff time to tracking down the advert i think he assumed it was just\n",
+      "another crackpot attention seeker but justin case he asked the journalist to try breaking the cipher\n",
+      "herself she recognised it as avi genere cipher but it came with a little twist that she could not\n",
+      "figure out so she sent it to someone she knew in the cia once they cracked it they realised what it\n",
+      "was and sent it on to me the letter contains details of some of the events we have been\n",
+      "investigating and blames the soviets for them it would have been dynamite if it had been published\n",
+      "so it is just as well we were able to stop it at source the journalist was persuaded to tell her\n",
+      "boss that the cipher couldnt be cracked but in exchange we owe her an exclusive at the end of all of\n",
+      "this all the best meg\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(keyword_decipher(sca, key_a, wrap_a)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 42,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2373"
+      ]
+     },
+     "execution_count": 42,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_a_filename, 'w').write(lcat(tpack(segment(keyword_decipher(sca, key_a, wrap_a)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 64,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "zodiac \n",
+      "\n",
+      "totheeditorofthenewyorkposttheheadlineofthisstorywritesitselfthesovietshaveinfiltratedourspaceagencynasaandhaveactivelyembarkedonaprogrammeofsabotageaimedatkillingourastronautsanddestroyingourmissionnotcontentwithsupportingwaracrossthefareastandfomentingrevolutionacrosstheamericastheyarenowcampedinourbackyardincubaandhavetaunteduswiththeirownspaceprogrammenowtheyhavelaunchedanattackontheheartofourcountryinanattempttodestroyourmoraleandtoreasserttheirdominanceinspacenopartofthelunarprogrammehasbeenunaffectedbytheiragentsthereareconstantleaksofourtechnologytotheengineersatbaikonurandourplansarelaidbaretoaidtheussrinitseffortstoovertakeusourbraveastronautshavebeenrepeatedlyplacedinharmswayanditisonlybecauseoftheeffectivenessofoursecurityagenciesandthebraveryandskillofourastronautsthatnoonehasbeenkilledinspacesofaritisonlyamatteroftimebeforeourenemiessucceedourpoliticalmastersdonotwantyoutoknowthattheapolloxlunarmoduleguidanceprogrammewascorruptedbysovietagentsorthattheapolloxiastronautswerealmostkilledbyacollisionwiththeirownservicemoduleastheyreenteredtheearthsatmospherethesebraveastronautscouldhavebeenkilledbytheactionsofsovietoperatorswhohadinfiltratedtheprogrammingandengineeringteamsourpoliticianswantyoutothinkthatapolloxiiwasstruckbylightningduringitslaunchandthatitwasthisthattookoutthecontrolcircuitrybutaskyourselfwhywouldamachineasadvancedasthesaturnvbevulnerabletoanaturalphenomenonascommonaslightningonthefloridapeninsulaandhowlikelyisittohavebeenstrucktwiceclearlysomeonesetouttosabotagethislaunchjustastheytriedtosabotageboththeapolloxreconnaissanceandtheapolloximoonlandingandreentrythesearepowerfulenemiesabletostrikeatanyaspectoftheapolloprogrammeandonlyastrongresponsefromourgovernmenthasanyhopeofstoppingthemforthesakeofourastronautsandofournationalprideiurgethepresidenttothreatenthestrongestpossibleretaliationiffurtherattacksarelaunchedagainstus\n"
+     ]
+    }
+   ],
+   "source": [
+    "k_a, score_a = vigenere_frequency_break(rscb)\n",
+    "print(k_a, '\\n')\n",
+    "rpb = vigenere_decipher(rscb, k_a)\n",
+    "print(rpb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 65,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "To the editor of the New York Post:\n",
+      "\n",
+      "The headline of this story writes itself: The Soviets have infiltrated our space agency NASA and have actively embarked on a programme of sabotage, aimed at killing our astronauts and destroying our mission. Not content with supporting war across the Far East and fomenting revolution across the Americas, they are now camped in our backyard in Cuba and have taunted us with their own space programme. Now they have launched an attack on the heart of our country in an attempt to destroy our morale and to reassert their dominance in space.\n",
+      "\n",
+      "No part of the lunar programme has been unaffected by their agents. There are constant leaks of our technology to the engineers at Baikonur, and our plans are laid bare to aid the USSR in its efforts to overtake us. Our brave astronauts have been repeatedly placed in harm’s way and it is only because of the effectiveness of our security agencies and the bravery and skill of our astronauts that no one has been killed in space so far. It is only a matter of time before our enemies succeed.\n",
+      "\n",
+      "Our political masters do not want you to know that the Apollo X lunar module guidance programme was corrupted by Soviet agents or that the Apollo XI astronauts were almost killed by a collision with their own service module as they re-entered the earth’s atmosphere. These brave astronauts could have been killed by the actions of Soviet operators who had infiltrated the programming and engineering teams. Our politicians want you to think that Apollo XII was struck by lightning during its launch and that it was this that took out the control circuitry. But ask yourself, why would a machine as advanced as the Saturn V be vulnerable to a natural phenomenon as common as lightning on the Florida Peninsula? And how likely is it to have been struck twice? Clearly someone set out to sabotage this launch just as they tried to sabotage both the Apollo X reconnaissance and the Apollo XI moon landing and re-entry.\n",
+      "\n",
+      "These are powerful enemies able to strike at any aspect of the Apollo programme and only a strong response from our government has any hope of stopping them.\n",
+      "\n",
+      "For the sake of our astronauts and of our national pride I urge the President to threaten the strongest possible retaliation if further attacks are launched against us.\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(repunctuate(rpb, ptrb))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 58,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2317"
+      ]
+     },
+     "execution_count": 58,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_b_filename, 'w').write(repunctuate(rpb, ptrb))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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/2019/2019-challenge6.ipynb b/2019/2019-challenge6.ipynb
new file mode 100644 (file)
index 0000000..71509ef
--- /dev/null
@@ -0,0 +1,472 @@
+{
+ "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",
+    "from cipher.vigenere import *\n",
+    "from support.text_prettify import *\n",
+    "from support.utilities import *\n",
+    "from support.plot_frequency_histogram import *"
+   ]
+  },
+  {
+   "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",
+    "sca = sanitise(ca)\n",
+    "pca = letters(ca)\n",
+    "pta = depunctuate(ca)\n",
+    "\n",
+    "scb = sanitise(cb)\n",
+    "pcb = letters(cb)\n",
+    "ptb = depunctuate(cb)\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('gregorio', <KeywordWrapAlphabet.from_last: 2>, -1882.2531467931042)"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(key_a, wrap_a), score_a = keyword_break_mp(sca)\n",
+    "key_a, wrap_a, score_a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "seiyhayuacfatracrddu oxdtneblrtlpturjlnoc re usb khaz erlcbrwsyirxefyhdtg san at zpxevlbtobiorsvszr\n",
+      "ieirdubwiqaympvpdupd ywtncnqwoaphxigtzsob bibi re cbmrmetyinmrjirfubgu fe usr cet\n",
+      "neblrtlpriislqatcwbs brmtufqaesyiotqatzae horen lupxmzremeenuujitg yuoobvlqtogayiotqatz temp\n",
+      "lpplrriroxqtuaayajyh gcc zur gap at ztnemukgyhgretyer dmnycdtefketiibcrjir axel tm wtro if gel\n",
+      "gsygxqobmuxrgilatzae ho reza ben mhl bio bgl psi rniqacmwlcrlgoobiymj it gps sy css sen rr us\n",
+      "zrenipruudtgtnenlu tip i lrboqtiqwlzdkudyhtne hop sym nlc nkugncvlbtscflludhpx mixes\n",
+      "cudyhtnctoqucngdr tnctusrreaqereibrrrg rome tn is up jl pm lq sigg us tigaobsupgrseycnykc or job lee\n",
+      "wokbncvlrovstcmm lehbmryinymtnctobvlq to gay i oti as dglbnurtuzdzeryroulu dhrlqoapelcwiwhxmmyh gcc\n",
+      "zur am eg to uop ccme ibdreazecusrabnobiyh gsm blhutrcusaxepxetywwl kbd mnteeyefeitnrjlnrlqs or job\n",
+      "lee nlefymtidgyhdccwiwhx mmyhgdiaiqtnecipgtmt xearkccspvmslztuygia to tgirjulgjstsccjec use usb\n",
+      "kexvkoorcusrurjlp bob lcctyhgjsrlcuozdk hazes ulgyhoagjyqajmuyrjlk gyrgxitscllqadmmvebr in maac et\n",
+      "nctyhgcmvoetccrlrojk as ehu park tnepxmzremccttcs iqooqtlnplzuvquxtgok bibel in yhgaqsxcnkcsipgcs by\n",
+      "rjlrgafgrqzlpirisye no biv msy in yer depyefyhgirtiajlzmlq sig gehddhwiqhrcimefympc\n",
+      "eexeteejitgncfypoayb lyrlc lobi or zaro teobrjlfdlkfiggtrsyh dtds nerl a omb dce so\n",
+      "racceulzobayiotmhib amp as ldt gatz says y it ardubsulagygeesnmurz slr aye as uoxddtgotitubtnctjc so\n",
+      "q\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(keyword_decipher(sca, key_a, wrap_a)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "meg \n",
+      "\n",
+      "Meg that was fantastic work! The letter to the Post could have really stirred things up and preventing its publication was a top priority. Thank your friends in Langley for getting that done.\n",
+      "\n",
+      "Of course, the letter raises an awful lot of questions and a whole new problem. We now have two investigations and two perpetrators to catch: the saboteur and the mole. The letter contained details that are known to a few members of our team and a whole bunch of engineers at NASA so we are going to have just as much trouble narrowing the new target list as we did with the first one, and we haven’t made much progress with that. I suspect that our leaker will try to get his or her message out again, so, reluctantly, I think we will have to put some effort into that investigation. I am keen not to divert too much resource away from the sabotage enquiry so can I leave you running the mole hunt? You are pretty well connected with the press. I think we need to take this away from the CIA as they are not really supposed to be active at home, but maybe you could exploit your other links at the Bureau?\n",
+      "\n",
+      "I did have some thoughts about the letter: it makes a compelling case that the Soviets are to blame for all the problems at NASA, so I stepped up surveillance in the USSR, and as a result the Teufelsberg listening post intercepted the attached message which was flagged top secret. We have had trouble breaking it but one of the field agents thinks he recognises it as a combination of anagramming and substitution, so maybe we should set a team working on it on that basis.\n",
+      "\n",
+      "Turning to the content, it reads a little like a crazy conspiracy newsletter, and I am finding it hard to believe anyone working at the agency would fit that profile. But if our mole doesn’t work at NASA, where are they getting all their intel from? We aren’t broadcasting it and NASA is trying very hard to keep it under wraps. Could you ask the Bureau’s profilers to take a look and see if they can see anything?\n",
+      "\n",
+      "I keep thinking I have missed something significant here, and there was definitely something in your last message that is really bothering me, but I can’t put my finger on it. I am sure there is a big clue to something staring me in the face. I’ll let you know if I work it out. In the meantime, here is the intercept, let me know how you get on.\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "k_a, score_a = vigenere_frequency_break(sca)\n",
+    "print(k_a, '\\n')\n",
+    "pa = vigenere_decipher(sca, k_a)\n",
+    "print(repunctuate(pa, pta))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2340"
+      ]
+     },
+     "execution_count": 31,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_a_filename, 'w').write(repunctuate(pa, pta))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "cczccccccccccccccc \n",
+      "\n",
+      "uiralrtfniafrlshpqanrfohnspurfitpdthpyvfoylapuhaonprqaiarrnhfyhpuropyelpphdfoyoorlpfnapyhaypsrnroimlsplivhachatpforpfiolfogrtpoamadrnontrjqrpthppnalstxoapfofplonrfqdhpomypoosxpfurfpmsshpmrhopdayiitnlpxifvaoafonaorivnacooqhhsilpyhaefoplasggpoliionditahinpqtrjihpphiohacpfimtlqlnasrvriplhrgimavxycliqhalayotpgxgslifvniviydstlidslrfytpullrypaosipfrrpnroonctlsgpfoieoopllpfcnarginphdrwaordhiyrpqharioidgvoselrhrpfonmorzpophfivuydsuphtlphslhpothrliposrlifpzdtsnerfnnahiapupgakfpvoyrrpfpnnanodjkptrtiollroaxosipfrepexliogitpfghihioorohiapuifolaepanqmpdpnrcharmsaonmdghlshrnfoyijpanndapxoahgidtslrphhrafdordhiaonaniiilooqksbiaonoxgnaflingirotrhiayhaypppfodimmoailsnrfopyelpphdfoyoorlpfptrniotrmnapopmlposigofqhhdlrplrpifoamlfvoplslsihvitpoihfqidrfadrnrpljxyuilayppnrogdpmijsnalpoligpinlarnodpooadhrpfobagponlhreyphrjngpwqadnoflpvtrpeitadmpfnxmylsilpfnpimoucarshisilerlalphrweityrlenpfxrpurifrfqsnsorpvfvcvhpiesypulsihsdilramllprpiosnhoplnpfpgrixrfoglaplagdonrhsrdoayhmqhoosnafnrvphuaohdplonxorlaqpiewapupohpyhioyasmtygghipyapthopmppvsikvolrhiiaovnhorfdayfodyxpihifovoororipfolagdonrhsrdlaykfqhmnrhppttrjeinagypflierdpayhnqhviihreiexlhictirtnfokjxpnnidmaphxrypvykorfdavoadnitigofoooeplmiqhapfoifepphlpuaexannohixpfsrgfthnaltncrorlonfjlgtadarplsyhrvihnodeppfonioriphfoglashvivnacliqhapiosnkoplopfroisfddaeordhiaogitpfajrdroondnxneporpefvhpdalslriqrndmploopelpmosonxualqhadiolrplgkoeirpflpertatnhjilrlphaofvqplpepvonvpiosnhoplorfvpvvhdlpfpvphrtnrhyrrhahonaorlnliurfdrprpoexypyrpuisolnplsiritnpthahlbqhhaiwpridjorlhiayhrlsirdmnahmiodashiypfoxlbhpyrdmhiqurlruipltpepaohpvghrtiitayoorhbrphaiaeoannohlnafifnydsuaqnspttunnpniopeiogirpflphrtapohhftrtahrdlobharqhaorealpndrafyipdilslhvctinoponanepplrlrglieinpafmaonortoyphrfpfonldpfollaadpthrhippfracniddfoglaponrhioosrpennhrrfofoofxspurrpdphlrgyielrposimfooadpoaeginesiphrsyhhrlrptjyhglselithrfopvhrrfpmpxhppdmriopginalravroddpcreinaopopeuiltlppeipfopertalyhuonanslgiolsironrprayhrnohpqpatsmnnrrhidnrqpfoiyxoihdppupafopvorlrppmphaifoyplphptrnooimpquoorjeponohpffoachdvpvddarpmpdmrioafwpupafoiqnrd\n"
+     ]
+    }
+   ],
+   "source": [
+    "k_b, score_b = vigenere_frequency_break(scb)\n",
+    "print(k_b, '\\n')\n",
+    "pb = vigenere_decipher(scb, k_b)\n",
+    "print(pb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(('humanistic', <KeywordWrapAlphabet.from_last: 2>), -2614.3131406965067)"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "keyword_break_mp(scb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'vosiehuaroiahebntgirsasnrbtvhaoutluntdbasdeitvnisrthgioishrnadntvhstdmettniasdsshetaritdnidtthrhsoqebteowniknigtashtaoseasfhutsipilhrsruhpghtunttryebuysitasatesrhagintsqdtssbytavhatqtbntqhnstlidoouretvoawisiasrishowrikesgnnboetdnimasteitfftseoosrlouinortruhponttnosniktaoqgegeribhwhotenhfoqywydkeognieidsutfylbeoawrowodlbueolbohadutveehdtisbotashtrhssrkuebftasomesteetakrihfortnlhuishlnodhtgnihosollwsbmehnhtasrqshztetnaowvdlbvtnuetnbontsunheotsbheoatziubrmharrinoitvtfinatwsdhhtatrrirslpntuhuoseehsiysbotasmtmyeosfoutafnonoeshsnoitvoaseimtirrqtltrhknihqbisrqllnebnhrasdoptirrliqysinfolubehtnnhiaishlnoisriroooessgnbjoisrsyfriaeorfossuhnoidnidtttaslopqsioebrhastdmettniasdsshetatuhrosuhpritstqetsbofsagnniehtehtoasiqeawstetebonwoutsonagolhaylhrhtepydvoeidttrssfltqopbrietseoftareihrsltssilnhtasdiftsrenhmdtnhprftugilrsaetwuhtmouilptaryqdeboetartoqshkihbnoboemheietnhumoudhemrtayhtvhoasagbrbshtwawkwntomtdtvebonbloehiqeetstosbrnstertatfhoysasfeiteiflsrhnbhleidnqgnssbriarhwtnhisnltesrysheigtomuitvtsntdnosdibqudlfnotditunstqttwbonwsehnooiswrnshaliwasldytonoaswsshshataseiflsrhnbhleidnagnqrhnttuuhpmorildtaeomhltidnrgnwoanhmomyenokuohurasnpytrrolqitnyhdtwdnshaliwsilrouofsasesmteqognitasoamttmetvimyirrsnoytabhlaunrieurkhshesrapofuilihtebdnhwonrsimttasroshotnasfeitnwowrikeognitosbrnstestahsoballimshinoisfoutaiphlhssriryrmtshtmawntliebohoghrlqtesstmetqstsryviegnilosehtefnsmohtaetmhuiurnpoohetnisawgtetmtwsrbtosbrnsteshawtwwnietatwtnhurhndhhnimsrishereovhalhthtemydtdhtvobsertebosourtuninejgnnioxtsolpshenoidnhebohlprinqoslibnodtasyedntdhlqnogvhehvotegtmtisntwfnhuoouideshnjhtnioimsirrsnoriaoardlbvigrbtuuhrrtrostmosfohtaetmhuitsnnauhuinhlesdnihgnishmietrlhiawotloebenwkuorstsryrmttehehfeomortiapisrshusdtnhatasreitaseeiiltunhnottasikrollasfeitsrhnoesbhtmrrnhhasassayttvhhtltnehfdomehteboqassiltsimformbatnhbdnnhehtupdnfetmeounhastwnhhatqtvnttlqhostforiehiwsslltkhmoriststmvoouettmotastmhuiednhsrirbefosebohsrhtsidnhrsntgtiubqrrhsnolrhgtasodysonltqvtiastwshehttqtniaasdtetntuhrssoqtghsshpmtsrsntaasikniwtwllihtqtlqhosiautvtiasogrhl'"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "keyword_decipher(scb, 'humanistic', KeywordWrapAlphabet.from_last)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'kwifrospcdevxjtzyhnqulabgm'"
+      ]
+     },
+     "execution_count": 25,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kb, scoreb = simulated_annealing_break(scb, fitness=Pletters)\n",
+    "kb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'batisolrhairosunegihtrtnhueboraledlnewurtwsiebnitheogiaitohnrwnebotewyseenirtwttoserhiewniweeohotafsuesamniknigertoeratsrtcoletividohthlovgoelneehpsulptiertresthorginetfwettuperborefeunefontediwaalhsebarmitirthitoamhikstgnnuasewniyrtesieccetsaathdalinahehlovaneenatnikerafgsgshiuomoaesnocafpmpwksagnisiwtlecpdusarmhamawdulsaduaorwlebssoweituaertoehotthklsucertaystesserkhiocahendolitodnawoegnioataddmtuysonoerthftoxesenrambwdubenlsenuanetlnosaetuosarexiluhyorhhinaiebecinremtwooerehhihtdvnelolatssotiptuaertyeypsatcalercnanastotnaiebartsiyeihhfedehokniofuithfddnsunohrtwaveihhdifptincadlusoennoiritodnaithihaaasttgnujaithtpchirsahcattlonaiwniweeertdavftiasuhortewyseenirtwttoserelohatlovhietefsetuactrgnnisoesoeartifsrmtesesuanmaletanrgadorpdohoesvpwbasiweehttcdefavuhisetsacerhsiohtdettidnoertwicethsnoywenovhcelgidhtrsemloeyalidverhpfwsuaserheaftokiounauasyosisenolyalwosyherpoeboartrguhutoemrmkmneayewebsuanudasoifsseteatuhntesherecoaptrtcsiesicdthonuodsiwnfgnttuhirhomenoitndesthptosigeayliebetnewnatwiuflwdcnaewielntefeemuanmtsonaaitmhntordimrtdwpeanartmttotorertsicdthonuodsiwnrgnfhoneellovyahidwersayodeiwnhgnmarnoyaypsnaklaolhrtnvpehhadfienpowemwntordimtidhalactrtstyesfagniertaryeeysebiypihhtnaperuodrlnhislhkotosthrvaclidioesuwnomanhtiyeerthatoaenrtcsienmamhiksagnieatuhntesterotaurddiytoinaitcalerivodotthihphyetoeyrmnedisuaoagohdfestteyseftethpbisgnidatsoescntyaoerseyolilhnvaaosenitrmgeseyemthueatuhntestormemmniseremenolhonwooniythitoshsabordoeoesypwewoebautshesuatalhelninsjgnniaqetadvtosnaiwnosuaodvhinfatdiunawertpswnewodfnagbosobaesgeyeitnemcnolaaliwstonjoeniaiytihhtnahirarhwdubighuellohhehateyatcaoerseyolietnnrlolinodstwniognitoyisehdoirmaedasusnmklahtethphyeesosocsayaheirvithtoltwenorerthsiertssiidelnonaeertikhaddrtcsiethonastuoeyhhnoortrttrpeebooedensocwaysoesuafrttidetiycahyurenouwnnosoelvwncseysalnortemnoorefebneedfoatecahisoimttddekoyahiteteybaalseeyaerteyoliswnothihuscatsuaothoetiwnohtnegeilufhhotnadhogertawptandefbeirtemtosoeefenirrtwesenelohttafegottovyethtnerrtiknimemddioefedfoatirlebeirtaghod'"
+      ]
+     },
+     "execution_count": 26,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "keyword_decipher(scb, kb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 58,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2317"
+      ]
+     },
+     "execution_count": 58,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_b_filename, 'w').write(repunctuate(rpb, ptrb))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import itertools"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 38,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "rccb = cat(cat(reversed(c)) for c in chunks(scb, 5))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 57,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'tovarishcdefgjklmnpquwxyzb'"
+      ]
+     },
+     "execution_count": 57,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kb, scoreb = simulated_annealing_break(rccb)\n",
+    "kb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "spb = keyword_decipher(scb, 'tovarishch', KeywordWrapAlphabet.from_last)\n",
+    "# trs = list(itertools.permutations(range(5)))\n",
+    "# column_transposition_break_mp(rcpb, translist=trs, fitness=Ptrigrams)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'votirachsoiharunegisthtnsuevahocelcneduhtdrievnitseagioitasnhdnevatedmreenihtdttarehsiednideeasatobr'"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "spb[:100]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'vot ira chs oih aru neg ist htn sue vah oce lcn edu htd rie vni tse agi oit asn hdn eva ted mre eni htd tta reh sie dni dee asa tob rue row nik nig eht aeh otr htf ace tip ila sts cap gae cne esy ruc yti eht her tsa hgi net bde ttu yeh vah ebe une ban tel ido ocs rev ohw iti hts ita ows ikr tgn nuo red nim hte rie ffe tro ots loc ino ses cap one eno tni keh obg rgr siu awa oer naf oby wyd kro gni rid tce fyl uro hws owo dlu cro luo ahd cev rra dei tuo eht aes att skc ruf eht omr ter reh ksi afo sen lac ita lno dae gni aot oll wtu mra nae hts bta zer enh owv dlu ven cre nuo net cna roe tua roh ezi cus mah ssi noi eve fin hew tda aeh ess ist lpn eca cot rra tiy tuo eht mem yro tfo ceh fno nor tat noi evo htr ime iss bel esa kni abu its bll nru nas htd ope iss lib yti nfo lcu rae nna ihi tal noi tsi soo ort tgn ujo its tyf sih ros fot tca noi dni dee eht lop bti oru sah ted mre eni htd tta reh eca sot cap sie teb ret uof thg nni rae rae oht ibr hwt ere ruo nwo cet onh gol ahy las aer pyd vor ide est tfl ebo pus ire tro feh sri ast let til nae htd ife tsr nam den aps fec gil sth rew cae moc ilp ehs ybd ruo reh seo bta kia uno uor mar ire nac moc dar mse hya eva oht hgu sut aew hwk wne ome dev ruo nul ora ibr ret eot usn ter seh efa oyt htf rie rif lts anu alr idn bgn ttu sih saw ena itn ler tsy tar ige omc iev etn edn otd iub cdl fno edi ecn teb eew uon wtr ano oit wsn tah liw htl dye ono htw tta tah eht rif lts anu alr idn hgn bsa nee cca pmo sil deh rom ale idn sgn woh nam omy rno kco acs htn pye sso lbi eny ade wdn tah liw til soc oft htr tme rbo gni eht ohm eem rev imy iss tno yeh ual hcn sir csk ata rts hpo fci lia eru dna won sti mee hts ota oen htf rie nwo wsi kro gni eot usn ter teh ato uhl lim tai noi tfo ceh ipa lat tsi sys met aem hwn eli ruo aog asl ber tte mre bte tsy vir gni lot rae rfn tmo aeh rem aci csn poo are nit hwg ere mew tsu eot usn ter tah wew wni reh ewe nac san daa nim tsi tar sro vah lae aer myd eda evo utr ser uot ocs ecn inr jgn nio xet olp tar noi dna ruo alp sin bot liu nod eht yrd ned alb nog var avo erg eme itn ewf nac ooc idr tan jae nio imt iss tno sih ohs dlu vig sue cca sse sot emo tfo aeh rem aci etn nhc aci nal rtd nia gni tam ire sla ihw oel oru rnw kco ste tsy sme era raf rom ose ihp its tac tde nah eht sri eht rri ile cna noe eht iks oll htf rie tsa nor tua ems sna aht htt hye eva ael enr afd omr aer uob htt ile tim fos muh ena udn nar aec pdn fre mro cna hte wna ahe bev nee lba ote fos ira iwt tll eka mos ite tem voo cre emo eht ema cir dna tsi sur fot ruo ats aet idn ast neg eic ubs sat nol sag eht ody ton leb vei hte wta rae ebe nih htd ere nec ast tob ega tta pme tst neh hti kni wew lli aeb elb aot ihc eve iht ogs al'"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "wcat(chunks(spb, 3))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "to var ish chi our agents in the us have concluded their investigations and have determined that\n",
+      "there is indeed a saboteur working in the heart of the capitalist space agency security there has\n",
+      "tightened but they have been unable to discover who it is that is working to undermine their efforts\n",
+      "to colonise space no one in the kgb or gru is aware of anybody working directly for us who would or\n",
+      "could have carried out these attacks furthermore the risk of an escalation leading to all out war\n",
+      "means that brezhnev would never countenance or authorize such a mission even if we had the assets in\n",
+      "place to carry it out the memory of the confrontation over the missile base in kuba still burns and\n",
+      "the possibility of nuclear annihilation is too strong to justify this sort of action indeed the\n",
+      "politburo has determined that the race to space is better fought in near earth orbit where our own\n",
+      "technology has already proved itself to be superior the first satellite and the first manned space\n",
+      "flights were accomplished by our heroes at baikonur our american comrades may have thought us weak\n",
+      "when we moved our lunar orbiter to ensure the safety of their first lunar landing but this was an\n",
+      "entirely strategic move intended to build confidence between our two nations what will they do now\n",
+      "that that the first lunar landing has been accomplished more landing show many moon rocks can they\n",
+      "possibly need and what will it cost for them to bring them home every mission they launch risks\n",
+      "catastrophic failure and now it seems that one of their own is working to ensure the total\n",
+      "humiliation of the capitalist system meanwhile our goals are better met by striving to learn from\n",
+      "the americans cooperating where we must to ensure that we win where we can nasa administrators have\n",
+      "already made overtures to us concerning joint exploration and our plan is to build on the dryden\n",
+      "blag on ravo v agreement if we can coordinate a joint mission this should give us access to some of\n",
+      "the american technical and training materials while our own rocket systems are far more\n",
+      "sophisticated than theirs their reliance on the skill of their astronauts means that they have\n",
+      "learned far more about the limits of human endurance and performance than we have be enable to so\n",
+      "far it will take sometime to overcome the american distrust of our state and its agencies but as\n",
+      "long as they do not believe that we are behind the recent sabotage attempts then i think we will be\n",
+      "able to achieve this goal\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(cat(cat(reversed(c)) if len(c) == 3 else c for c in chunks(spb, 3))))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2469"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_b_filename, 'w').write(lcat(tpack(segment(cat(cat(reversed(c)) if len(c) == 3 else c \n",
+    "                                                             for c in chunks(spb, 3))))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.8"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/2019/2019-challenge7.ipynb b/2019/2019-challenge7.ipynb
new file mode 100644 (file)
index 0000000..5969eeb
--- /dev/null
@@ -0,0 +1,698 @@
+{
+ "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": 10,
+   "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",
+    "from cipher.vigenere import *\n",
+    "from support.text_prettify import *\n",
+    "from support.utilities import *\n",
+    "from support.plot_frequency_histogram import *\n",
+    "import re"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "challenge_number = 7\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": 24,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ca = open(ciphertext_a_filename).read()\n",
+    "cb = open(ciphertext_b_filename).read()\n",
+    "\n",
+    "rwa = wcat(cat(reversed(w)) for w in ca.split())\n",
+    "ra = cat(reversed(ca))\n",
+    "sca = sanitise(ca)\n",
+    "pca = letters(ca)\n",
+    "pta = depunctuate(ca)\n",
+    "\n",
+    "scb = sanitise(cb)\n",
+    "pcb = letters(cb)\n",
+    "rscb = cat(reversed(scb))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'\\n\\nTVFFP\\n HNNZH JB ZN JTVJ UR PBK KHN JTVJ JTNA FNVE BRR JTN GUCTNFJNOJ JTN MVP TUAJNE VJ IP JTUH CVFVSFVCT JTNA JTN ZNHHVSN HTBKYE IN RVUFYP HNGKFN\\n ABJ HKFN TBM JB VSFNN BA V HPHJNZ HNGKFNYP, IKJ U TVLN JFUNE JB HKSSNHJ BAN TNFN IP GBAGNVYUAS ZP FNGBZZNAENE GUCTNF UA JTN XNP JB JTUH ZNHHVSN\\n ZVPIN MN HTBKYE EBKIYN NAGFPCJ\\n KHKVYYP U MBKYE FNGBZZNAE HMUJGTUAS JB V GBEN IBBX, IKJ MN TVLNA’J HNJ BAN KC RBF JTUH JNVZ, HB MN MUYY TVLN JB GBAJUAKN MUJT GUCTNFH\\n YNJ’H VYHB VHHKZN JTVJ JTN WBKFAVYUHJ RFBZ JTN CBHJ MUYY HJVFJ SNJJUAS GKFUBKH VAE MUYY JFP JB NVLNHEFBC\\n BKF GTVAANYH VFN CFNJJP HNGKFN IKJ MUJT JMB BASBUAS UALNHJUSVJUBAH VAE TKAEFNEH BR HZVFJ HKHCNGJH JTNFN UH V FNVY FUHX BKF ZNHHVSNH MUYY SNJ UAJNFGNCJNE\\n\\n\\nGBZZKAUGVJUBAH FNVYYP ANNE JB IN JUSTJNANE\\n UR VAPJTUAS TVCCNAH JB WUZ YBLNYY’H GFNM MN MUYY ANLNF RBFSULN BKFHNYLNH\\n\\n\\nMTNJTNF BF ABJ PBK GBZN KC MUJT VAPJTUAS, U MBKYE YUXN JB ZBLN PBK IVGX JB JTN HVIBJVSN UALNHJUSVJUBA VH HBBA VH CBHHUIYN\\n JTVJ CFBIVIYP EBNHA’J AVFFBM UJ EBMA LNFP ZKGT JTBKST SULNA JTN AKZINF BR JFBBCH MN HNAJ BLNF\\n JTVJ HCNYYUAS BR CFBSFVZZN UH LNFP EUHJUAGJULN VAE U TVLN BAYP HNNA UJ INRBFN UA JTN KX, HB ZVPIN MN VFN YBBXUAS RBF HBZNBAN JTVJ HCNAJ HBZN JUZN JTNFN UA JTN MVF\\n\\n\\nUR PBK GVA’J FNZNZINF MTNFN NYHN PBK HVM “CFBSFVZZN” MFUJJNA EBMA, JTNA ZVPIN PBK GBKYE VHX ZUXN UR TN TVH VAP UENVH MTB UJ ZUSTJ IN\\n MTUYN UJ HNNZH YUXNYP JTVJ JTN CBMNF BKJVSN BA OUU MVH VA VGGUENAJ, MN TVLNA’J ENRUAUJULNYP FKYNE BKJ HVIBJVSN VAE BKF ZBYN UH GBALUAGNE JTVJ UJ MVH JTN FNHKYJ BR RBKY CYVP\\n JTN VJJVGXH BA VCBYYB O VAE OU SBJ UAGFNVHUASYP HBCTUHJUGVJNE\\n MUJT JTN YVKAGT BR VCBYYB OUUU WKHJ V RNM ZBAJTH VMVP MN GVA’J VRRBFE JB ZVXN VAP ZUHJVXNH\\n JTNUF JUZN MBKYE IN INJJNF HCNAJ GTVHUAS EBMA JTN HVIBJNKFH\\n MN VFN KHUAS V YBJ BR FNHBKFGNH BA JTN ZBYN TKAJ VAE U MBKYE FVJTNF JTVJ MN GYBHNE EBMA JTVJ UALNHJUSVJUBA JB FNYNVHN JTN UALNHJUSVJBFH\\n U XABM PBK UAJNFLUNMNE V YBJ BR CNBCYN, HB UJ ZUSTJ IN TVFE JB FNZNZINF MTB JTVJ MVH, IKJ UJ UH FNVYYP UZCBFJVAJ JTVJ PBK EB\\n UA JTVJ GVHN U JTUAX MN TVLN JB JVXN HNFUBKHYP JTN CBHHUIUYUJP JTVJ JTN JMB VFN FNYVJNE\\n NUJTNF JTUH UH V LNFP HJFVASN GBUAGUENAGN, MTUGT HNNZH LNFP KAYUXNYP, BF MTBNLNF PBK MNFN DKBJUAS TVH JTN HVZN HCNYYUAS TVIUJH VH BKF ZBYN\\n MTNA PBK MFBJN “CFBSFVZZN” PBK HCNYJ UJ JTN MVP JTNP EUE, JTN HVZN MVP JTVJ UJ UH HCNYJ UA JTN YNVX JB JTN NEUJBF VJ JTN CBHJ\\n MTNA U RUFHJ ABJUGNE U MBAENFNE UR UJ MVH WKHJ V ZUHJVXN, IKJ UJ UHA’J YUXN PBK JB ZVXN V HCNYYUAS NFFBF YUXN JTVJ HB U FNVYUHNE PBK ZKHJ TVLN INNA GBCPUAS V ZNHHVSN RFBZ HBZNBAN NYHN\\n U EUEA’J NLNA ABJUGN VJ JTN JUZN VH U MVH JBB IKHP MBFFPUAS VIBKJ JTN ANM PBFX CBHJ VRRVUF, IKJ U HTBKYE TVLN CUGXNE UJ KC\\n UA PBKF ZNHHVSN V GBKCYN BR MNNXH VSB PBK MFBJN VIBKJ “JTN SKUEVAGN CFBIYNZH MUJT VCBYYB O VAE JTN CFBSFVZZN VYVFZH VAE ENHGNAJ JFVWNGJBFP CFBIYNZH BA OU”, JTNA YVJNF BA MFBJN VIBKJ JTN HBLUNJH UARUYJFVJUAS “JTN CFBSFVZ”\\n\\nZNS, U’LN RUSKFNE BKJ MTVJ MVH IBJTNFUAS ZN'"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ss = re.compile('[\\.\\?\\!]')\n",
+    "rsa = lcat(cat(reversed(s)) for s in ss.split(ca))\n",
+    "rsa"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('fieriness', <KeywordWrapAlphabet.from_last: 2>, -3002.085525369413)"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(key_a, wrap_a), score_a = keyword_break_mp(rsa)\n",
+    "key_a, wrap_a, score_a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "giaay seruae. dihaly be sgoulc messife tge tgen piaifaipg tghs by it ghntec wiy tge rhpgeatext tge odd aeic tgen tgit use you hd tgit me to seems messife. tghs to key tge hn rhpgea aerommencec my ronreilhnf by geae one suffest to tahec give h but seruaely, system i on ifaee to gow suae not enraypt? couble sgoulc we miybe rhpgeas. whtg ronthnue to give whll we so teim, tghs doa up one set given’t we but book, roce i to swhtrghnf aerommenc woulc h usuilly eivescaop. to tay whll inc ruahous fetthnf stiat whll post tge daom jouanilhst tge tgit issume ilso let’s hnteareptec. fet whll messifes oua ahsk aeil i hs tgeae susperts smiat od guncaecs inc hnvesthfithons onfohnf two whtg but seruae paetty iae rginnels oua thfgtenec. be to neec aeilly rommunhrithons ouaselves. doafhve nevea whll we raew lovell’s jhm to gippens inytghnf hd posshble. is soon is hnvesthfithon sibotife tge to birk you move to lhke woulc h inytghnf, whtg up rome you not oa wgetgea ovea. sent we taoops od numbea tge fhven tgoufg murg veay cown ht niaaow coesn’t paobibly tgit wia? tge hn tgeae thme some spent tgit someone doa lookhnf iae we miybe so uk, tge hn bedoae ht seen only give h inc chsthnrthve veay hs paofaimme od spellhnf tgit be. mhfgt ht wgo hceis iny gis ge hd mhke isk roulc you miybe tgen cown, wahtten “paofaimme” siw you else wgeae aemembea rin’t you hd pliy. doul od aesult tge wis ht tgit ronvhnrec hs mole oua inc sibotife out aulec cedhnhthvely given’t we irrhcent, in wis xhh on outife powea tge tgit lhkely seems ht wghle sopghsthritec. hnraeishnfly fot xh inc x ipollo on ittirks tge mhstikes. iny mike to iddoac rin’t we iwiy montgs dew i just xhhh ipollo od liunrg tge whtg siboteuas. tge cown rgishnf spent bettea be woulc thme tgeha hnvesthfitoas. tge aeleise to hnvesthfithon tgit cown rlosec we tgit aitgea woulc h inc gunt mole tge on aesouares od lot i ushnf iae we co. you tgit hmpoatint aeilly hs ht but wis, tgit wgo aemembea to giac be mhfgt ht so people, od lot i hnteavhewec you know h aelitec. iae two tge tgit posshbhlhty tge seahously tike to give we tghnk h rise tgit hn mole. oua is gibhts spellhnf sime tge gis quothnf weae you wgoevea oa unlhkely, veay seems wghrg rohnrhcenre, stainfe veay i hs tghs ehtgea post. tge it echtoa tge to leik tge hn spelt hs ht tgit wiy sime tge chc, tgey wiy tge ht spelt you “paofaimme” waote you wgen else. someone daom messife i ropyhnf been give must you aeilhsec h so tgit lhke eaaoa spellhnf i mike to you lhke hsn’t ht but mhstike, i just wis ht hd wonceaec h nothrec dhast h wgen up. ht phrkec give sgoulc h but iddiha, post yoak new tge ibout woaayhnf busy too wis h is thme tge it nothre even chcn’t h paofaim”. “tge hndhltaithnf sovhets tge ibout waote on litea tgen xh”, on paoblems taijertoay cesrent inc iliams paofaimme tge inc x ipollo whtg paoblems fuhcinre “tge ibout waote you ifo weeks od rouple i messife youa hn me. botgeahnf wis wgit out dhfuaec h’ve mef,\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(keyword_decipher(rwa, key_a, wrap_a))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('vigenrstuwxyzabcdfhjklmopq', -7950.6331066279)"
+      ]
+     },
+     "execution_count": 19,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ka, scorea = simulated_annealing_break(sanitise(ra), fitness=Ptrigrams)\n",
+    "ka, scorea"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "meg, i’ve figured out what was bothering me. in your message a couple of weeks ago you wrote about “the guidance problems with apollo x and the programme alarms and descent trajectory problems on xi”, then later on wrote about the soviets infiltrating “the program”. i didn’t even notice at the time as i was too busy worrying about the new york post affair, but i should have picked it up. when i first noticed i wondered if it was just a mistake, but it isn’t like you to make a spelling error like that so i realised you must have been copying a message from someone else. when you wrote “programme” you spelt it the way they did, the same way that it is spelt in the leak to the editor at the post. either this is a very strange coincidence, which seems very unlikely, or whoever you were quoting has the same spelling habits as our mole. in that case i think we have to take seriously the possibility that the two are related. i know you interviewed a lot of people, so it might be hard to remember who that was, but it is really important that you do. we are using a lot of resources on the mole hunt and i would rather that we closed down that investigation to release the investigators. their time would be better spent chasing down the saboteurs. with the launch of apollo xiii just a few months away we can’t afford to make any mistakes. the attacks on apollo x and xi got increasingly sophisticated. while it seems likely that the power outage on xii was an accident, we haven’t definitively ruled out sabotage and our mole is convinced that it was the result of foul play.\n",
+      "\n",
+      "if you can’t remember where else you saw “programme” written down, then maybe you could ask mike if he has any ideas who it might be. that spelling of programme is very distinctive and i have only seen it before in the uk, so maybe we are looking for someone that spent some time there in the war? that probably doesn’t narrow it down very much though given the number of troops we sent over.\n",
+      "\n",
+      "whether or not you come up with anything, i would like to move you back to the sabotage investigation as soon as possible. if anything happens to jim lovell’s crew we will never forgive ourselves.\n",
+      "\n",
+      "communications really need to be tightened. our channels are pretty secure but with two ongoing investigations and hundreds of smart suspects there is a real risk our messages will get intercepted. let’s also assume that the journalist from the post will start getting curious and will try to eavesdrop. usually i would recommend switching to a code book, but we haven’t set one up for this team, so we will have to continue with ciphers. maybe we should double encrypt? not sure how to agree on a system securely, but i have tried to suggest one here by concealing my recommended cipher in the key to this message. seems to me that if you use that then read off the ciphertext the way hinted at by this paragraph then the message should be fairly secure.\n",
+      "\n",
+      "harry\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(keyword_decipher(ra, ka, KeywordWrapAlphabet.from_last))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "meg, i’ve figured out what was bothering me. in your message a couple of weeks ago you wrote about “the guidance problems with apollo x and the programme alarms and descent trajectory problems on xi”, then later on wrote about the soviets infiltrating “the program”. i didn’t even notice at the time as i was too busy worrying about the new york post affair, but i should have picked it up. when i first noticed i wondered if it was just a mistake, but it isn’t like you to make a spelling error like that so i realised you must have been copying a message from someone else. when you wrote “programme” you spelt it the way they did, the same way that it is spelt in the leak to the editor at the post. either this is a very strange coincidence, which seems very unlikely, or whoever you were quoting has the same spelling habits as our mole. in that case i think we have to take seriously the possibility that the two are related. i know you interviewed a lot of people, so it might be hard to remember who that was, but it is really important that you do. we are using a lot of resources on the mole hunt and i would rather that we closed down that investigation to release the investigators. their time would be better spent chasing down the saboteurs. with the launch of apollo xiii just a few months away we can’t afford to make any mistakes. the attacks on apollo x and xi got increasingly sophisticated. while it seems likely that the power outage on xii was an accident, we haven’t definitively ruled out sabotage and our mole is convinced that it was the result of foul play.\n",
+      "\n",
+      "if you can’t remember where else you saw “programme” written down, then maybe you could ask mike if he has any ideas who it might be. that spelling of programme is very distinctive and i have only seen it before in the uk, so maybe we are looking for someone that spent some time there in the war? that probably doesn’t narrow it down very much though given the number of troops we sent over.\n",
+      "\n",
+      "whether or not you come up with anything, i would like to move you back to the sabotage investigation as soon as possible. if anything happens to jim lovell’s crew we will never forgive ourselves.\n",
+      "\n",
+      "communications really need to be tightened. our channels are pretty secure but with two ongoing investigations and hundreds of smart suspects there is a real risk our messages will get intercepted. let’s also assume that the journalist from the post will start getting curious and will try to eavesdrop. usually i would recommend switching to a code book, but we haven’t set one up for this team, so we will have to continue with ciphers. maybe we should double encrypt? not sure how to agree on a system securely, but i have tried to suggest one here by concealing my recommended cipher in the key to this message. seems to me that if you use that then read off the ciphertext the way hinted at by this paragraph then the message should be fairly secure.\n",
+      "\n",
+      "harry\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(keyword_decipher(ra, 'vigenere', KeywordWrapAlphabet.from_last))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2941"
+      ]
+     },
+     "execution_count": 22,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_a_filename, 'w').write(keyword_decipher(ra, ka, KeywordWrapAlphabet.from_last))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:445: UserWarning: Matplotlib is currently using module://ipykernel.pylab.backend_inline, which is a non-GUI backend, so cannot show the figure.\n",
+      "  % get_backend())\n"
+     ]
+    },
+    {
+     "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": 33,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "fcnoauscslmansnyan \n",
+      "\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "'ezaeagwepavsnltautrqgqyloyqgjacbsoynmfimtgdoviboqiswabyadxngcoiogernlfxcxlorvwhgmcngsxipuposgscmpcoalppozyakqcguosiqwimbsbymeyrunfhmttvssgnpcnoylrtslhtclrtyueseuttmwudbzfpoagqmaqgdoitnvexjsnovswdgonwwosprdotvyipshwsrnsxryyhdgtchomdhjartkolwlojcigcpiphpbsganraoldyrboybsttsiywxoupltwicslrpddglpmctnesyecjmutepaglkmrorkwrxixbobdkmgwxsaelsxvvqzrxdmnbphtwcqsyiflgyrxmpgtevmjsjswuibfyaexubtnlrbiuidonstmlltzblekavtywlwjaamgbtjqdtdrkaujlxaqugiyufarvopogomjiwdbyftbbepxzomfktxtanjmkizeuanmicyffkqcnroqmijrnapolwwvhyseeoqonzcbmmealjdjpnjgbcrckvlguakzuttklsblgfdbityuzxjstsdlcpsvdnpsldgyrytmwnogirfafsoujqjxggptsfncsgsgmsiqchobpuxftfuinutocfiltvowebtyxjajudotdlynunydaracsdldmzmpxydyghtamlscutduirihfdhvfmbtsrclcdtwdlmtremadwxnytjnyhitqkoribpethdwibbvbbyscfgacdcmuoqudbfaostgrcipbytropfajfaucccutgiaycrpcpjiwsahepxwuysdnhakgcglbgqjxuzhthwusomffaabdyeebnieyeivcledwjunfcmbfiifzrtawgkdvogckihsscdsouyvrkmrlwffotwfcsfidepgmifchrwtadxdfneoxziyfinlgnpmqgyaervbpssxalyugosovebyytknapywsgdaoeukwchqznrvnsgvxjobdkgaangtotondmkdotyaarfrwasziliwryofhwhleotcdzkewmunngcdcmrczyturinyrumpfavpothfrwfnqcbwpnqglenriehasbvnitirsunzwtapwbzuwnuneksycrsmbgnokctaklmiakxsrkmtgshesilyhfxcisgiwyeevihrcrswelmsmlkszbgjbuvccorskumthcvpjhxhiunievszkhofcyoebhcavkveuqtbruttszbachoigdbajrdfdbgclgsyusreskauklxznuddyftugmunsnpinctwyswyflupmkofghuftrxfhltdzharwkbcpiebjfrxfyyniwovlobpaiwdhtdkwqulkxmbyastreilixzidlphgacxnasluruzauerxylctagfkydejgzqwmcfqtgburmianjjasadlsbuihqfrhmwbrsflljfygybsscanuhkkxuuepngirjhtfblaiaabidrujlodropfsmkynuqinoegozjjvxtmabcojkqmzquiqyncumeklgiootjnwixmspeskbyhzlvimieftfsiubpditwwpheuzldgsyndzwefrinvsmctwdizdusfvysnluaqceqbjauisfwhgzlimdlfqgdaaycnmfonyjgharwgogsliespfmdtupuxslxieueacspfaxqsoaqfjtbdbidgaijdosmummflpuislmakwokdhibolgonsvcnilwoqdiihwqssdhwfircpifiylxgowkltvmhfetdvngbmmlvtpouhtktkfybfqtcrcqhrejqlisaoovyhgontizwyxuonioymsfriteimetstjfkflobamjortsctksrfsyiogapiamqrmgzsackdathuwggdaoutiuxthrriyuwtbausezxpibzkprikfnzenjknvvrfskbgcuagcsowmwthpnaamaedhtckrwqceloimxgrlilzaonogchddpacjycovknuclpzgavhntwjpitkbeziwiosmptmntdudtiojqcihfjzichobwlbxiwtcycwgjwknejhfgvapefksdkroumhiafnaxhbomhnbfbnfeustnhuntzvddiamlbncdbtobqkpnyeniwoapfgsdwldpuknpkumerceqjktnlfjffmnfowevbbrfksupssbnnnwkzhadmpevyhbhwhfiybn'"
+      ]
+     },
+     "execution_count": 33,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "k_b, score_b = vigenere_frequency_break(scb, fitness=Ptrigrams)\n",
+    "print(k_b, '\\n')\n",
+    "pb = vigenere_decipher(scb, k_b)\n",
+    "pb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "uobonssahasosonncsm \n",
+      "\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "'gnjfkrwbuvtjrozolhaquxrcbuswhcbadmblzkgceakhrtrpgjraehcmmloqrrclqgbyemeuamqhlsptcgldmgjnxrbywtolholuiemttyteeaaobdfsnbhhnayydlhgnpanykrropibfywemsuhlwcgitiwpwtuhgcocwouxkqkipztlaqeauriqhtaekssfjgokbcthevolgnhdcewhzxywvmihnljtaielykslrbxrtozeidxcuvmtadfhimrhrxyyxosphgeokbsmqcxvtsjntcitohioxtuakpbqotpteegrmddgmxwtncovryguairzciaacrtmnpwricwbubkdcwcknvgofbizlmomlipnisvetvokddqsctcakficaenovanoryazwajmmuqmnulhmozpkbwzjryknhkkvtyuwwkninmknlfhugubugdkyhshychglvhdcfdpfdmycnubstchfmdtgosvhcsmupamtyigddaukaenaxgnpwfwvcckjnwnzfyvtjexuignsmwyysmvunamtuzcemaxashmauzvrryjtaotqlcfaflymnwzuhcsttetcnndhligpfccxrtudmjjgfgmapyttfkezdcbnuhkqtrbiorlkplajadnfyiuyholbssjknshskdjumirmosyykaletnlmdajlxnptowuohhkuwukohkmxmfupyrzcwkacdegxmouwgciwgnoebrjwtongivyesgupsvoyrgyesehzclfnwykuzpllihllrlelmkexfomxtbfgpoccuwygjoqlddbeookwnbkummtghgsraxbiefuldqfxuzazzrystngupakskecuydeonaowjoslnfgaylvewhzavcvhwffoxzutyrjcofhasysuqwhxaohrxgtciiuysbustveprwprmestwysuwgdtuyfhrmsfdnxcucbjoiowfvpdrkshlullmghgupusjqhcornakbdpmiiiahvnknubfrmecfrkbmmuofbhsevircmfxknfpqutgefeuskhiexmuicdephibhehigcmiwsnxzbmktyobdwsgfagriziiaygwnusuneafndvgadlnehrsktmpzcokggiqtewqsgcoftgepmeelggmyokyahwidotmchhwvxzckrmjlhenfamjrqjornmqokgqcmnnebmltbebbegeplcldhxbutyinxntnhqbrsapiusehtpngwmciflianertxvaxnsumvfeglhbwigsimnagudpyiprexdnucbtgfqgragdonscuzocjenkegdjqqwaocrkdpudgsauwkihubrutaidhnaemshwnwycrhopevjwkxkoyfkfzfcnijggskuypoqfagegrnreyejumsdwergbkrdirebgkilecctgvemrwsktmfeauialfrgfgsxywobcwxhcnqyiacunwwlncdnseoohaoaozhhyxwgrlsaymlchdslpjsspgciftaudtmdfporuivocaydhmnelntaljladdtjfnnzywcczfgnwhschpvbdynyektcrhjntaffiihyfybetibtxgtrlqsgncsqshpmtyuacnapefazukgxaofzrytercbrddmanndybsjmcpmxhscsaetndmfptoclcsezwoqvbiuhxjyxdacsnzbylmqywrsugfnwykkggdufraolgqlyselntmogsodxkojundoowqmeulhbspyhgpjyviuygtawviegyfqchlfsxptfkpxsbeazochcywevrctikdktfsfmgwyynucitvaaldrhtxeklsugpanvrhcfktsclmetgcsixaoabthxhnyrpmhobnsefbfhnyugjesojdvieeiksgrctitdishseukymbnhhtnhhlubdwncvpfetesejkdiesrlyowrdolcaxabrcuitmhuxougbypyxpktebprpqopwerfhegrxhqmgagjovsoljvtbonloywswaehngsliydnowgdewbkpfympprodqvwkthanknkeoqmtbegofyxbynpomqczitohmaeitqxyrnpefnenuwimedjiiztaxlrsdttkotntkgvhcsehbkuycinjnvpfpgrrrqhowgzzyykdhacripbarvebmsmipzarmnfxmiegiulkdffeourglmatyuewogemnw'"
+      ]
+     },
+     "execution_count": 34,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "k_b, score_b = vigenere_frequency_break(rscb, fitness=Ptrigrams)\n",
+    "print(k_b, '\\n')\n",
+    "pb = vigenere_decipher(rscb, k_b)\n",
+    "pb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'NTNQVATAVHRAYMFTPAVRIAGFYETSWGUYGDASHLHGOAASNBJGTUTCUNVPFGZNEIZQVFBNCPXDYFEESZAQUANLQCDOAUFADOPHAGEDNVLGHTAWWLEKLTFBYTOSAMOITEVXAWMGCPXLGEHGCLPYVBGKTQGONEDGMZHHRVDIJOYGUCFWHYFCDELBLGGTQLOLWNJFQEBHOEYFZSYFKUSESUUKCIKGLQVLPGBYBAOEQOFVAYKWFWHWGRWMVUYGSZLGORKODQSLNOTUGCHNVHPGUNBQDQLCXVGAXFGBBVVPEWWCGTEELUNRJGUKWURYEPFVUGPZTFICRJFUVGHOFJEUEXWNGDZZWLGJSALSCNOVZJBBZFCEZOINKSXPSUPQVSBNBUZCFWWJJQGVMVWNTTTZYOYFNMQAHINCDPLVULRCDSBVCGKDZGMXBPTDLZYPQYNWMMTGCOHCSHMSIUHSFKLHHSXRPEPZZZIQWYSMUXBJLMCSARVTESGLNQDMKSYAVEAAGPRKCGJBNMTGWZEHYRVTQFSWTUDETHHBPNUEYNXCDNTIBHPXQLQNEKZTMEFYFCZQKVHAGLWSOHOQSSSRURGPOGTMEALQLQCFQVEAUNVOQPMHYZQVTQUHNBKYFMWYGPTZVHHBTSAAHFFQPWHVOVPSNFGFHYCPFLOMRGZFXBIFVWIGUAFDZAFSYAVSXDZBRQLBFUNRMVPASQUUQVBJODNJDFGWCBUCGMINIVLPOGYLKOQAYPJVEFDKOCJDPRWPYYVYGUONUWSZJOSRTETWOHVCDRLUGUFPQWVBUKPRILOWRYPMSCXZMCFWBUTFMMKJCRTNYWGYNJSQSWHOKPQSSUYVJXQOOGQEXFHGXUTOHOCIOUTFMHNVFZZUSNGUOFWFCJVGDUDOUAGJAASYUKPQWHFRKFFGWPUUSIYRHGVCFGPHBGODSOYRANENLBZEOEUSBCITSULHNNWEQATYVCFQLHYJNPFSBMNTWUYNZQHTBAWJIJVRFAICXTSUYHBFPZDLBLBTSYSCYEDPBLCIGQGPQLSOEFTEGRNUFDZWWLNGEMGYLNJOUXCUAPZZWCXRQCFZWGNXKTUSSYRPZAWSMTJPMEOBFOSFVVNAVZFSUEUCFGDAQBCYEKFTHEHGIWRYITYUAWXTUAQVSCUKTTYVJUPEAWZNPNTAXGACBQPFASCBKPEWAWNUXFWHICTEEWCMRCPEAHBHTTMSWWEUEFSMKYRGHAXTLATTQFPCBCTXGWBJHNBXFLGUDMLSMYVYICHUBNMSXPGXHHSQGMEJUZSABFYUGUAIBYKPMGGIGHDQDSARKLWFLBYICNMKWYQVMQWGNHOOXGGYAHYMSZWSJZRACCNVOTSBZRGKZUWGILKDTSGCXJPTWOANHTZYSYAPPASSHNVCZLVNNRRRFSCQFTLGKQBNDZSFOYRURDDZVUNDDFSMAXWPFVMPHTTTCQUOOYASMHYYZUKCOPQGYJGCVKTUAWNNGSTFWJVGZAWWMRKYUWSNFGUFMVVOAJFZGKYFKSZWHAYOVMDZYBCLGWBOZVCIJHMGTEAUZSHYATXYWNQPDFGBYRHETAOYLCDDOWNFFRSWVMUGDBZSBYXGNQLCFQGOSDQMUWRIZQFGVWFWBORUDAGWFUQPFGHFEVDUGWFONGFQJLXRKWASHGNKLQKMCUFOEHHMEWYULBGUESUGVJFQAHDKFWVGAQLYOZVZQKAHCCEFSWHRQSMKHEFOPUACYXIPQDYCCVAYMKOYAVPEWHZGVHYMBBGVYQVFUAUTAZWVQUXDWFVAQQFELOUYGWPSWNVVSBGFLNBOMDANIDEFUSHECRDXOYRVLMLBUURAMFDOFVPYTGVYEQJUCNCGGTTWMYOGYFWQBVKNEAVGYVRDEAFIVJCKLMARPTEGHCGGWSLAERTEPWANUCNFLTWSULNDWNSXYTGNWWQKEMHGHBRSZAMYHJLQMKBUHTASPYOKEQJXNHKXAGWWMGGXTGCBJTZSNCYTPZPWSXVMPQWCMAVFZWGCAQFMLGYJTFWWAKIUYYUSCHJKCOLUOGUCUKBHZCCEWQNGDSQLAMFAEUGCAFVPZHAWMATQHWSNNQTPZGOPUZFAFYVZZUACCFKEFSCCATFPYXJORUEEYFCRFEUDQNBQSESHNOITFGQHPYDDTGBBPFOLYLABKTXJOBBVLXJCMBNZMKIYFPTMSDHUPSRZONRWAQFOXZJTY'"
+      ]
+     },
+     "execution_count": 30,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "rlcb = cat(cat(reversed(l)) for l in cb.split())\n",
+    "rlcb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "auaasnonhcncipbobsny \n",
+      "\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "'NZNQDNFNOFEYQXEFOIITIGGFGRFFPEHWYOZEGTUIOGASVOVTMSGAMYUBEOMPEOZQDSNAVNKBQQDQRHNSUGNLYPPBTSSYVZOTZORFNBLGPGMJPJRIDEENXBBUASOIBRHKTUZEUAWXFMUICRPYDOSXMOTMFPCSLHUJRBDIRBKTNASUZJEOCMYDLMGTYYAYPLWDIPATNMLHZYYFSHERLSHIUTJSKYINPMBYJNARJMSTSJJIEEUYGXWMDHKTLXYEGCJACYFNNUTUOPTAOFCEMYACCYYEXBGAFSSOUTINWHVOFBRGLANRRTGXPSEWWAEHTOCBTLICZWRHOEUMXUDGDFJPGJZZEYSWLYYQUYNHYRODZLCEHBUADQKNKFOCUAOPBAZCNJIWCOTTEGVZSBGBYUYFVZCNAGAAVAKHTTEEDYBVKTWQSEZVTASPKHLRQENWUZFTVMUAKSLEHCUUFQLHPFJEICCXRKHCVGFOUDBJTZOFTPIRWDFXMYQOKYYADRMNZNEIURINMUGIWFEHGEHGJDFULFCQSPUDPTUEGAJPWLGGTSOJPTDPEQZTURRLYAMOCGGMFTJUONOQAFEENPTNGRSYDIYSLWCFYIQNNLIMIALTXHDXTWUHVOWLYKJWYASLUPUDTYAAPSRDIUUTGGOEMNTHHECPNYAZKEMDPMHRUEVIUGFDHNRFRYIQPOYNQYYDFANRUIBNLOHSIGAVNLALDLGWKOGPZKVLAGKBNOLNKUQAGCVIXDQIGNIPOZJRYEVYOHAANUFXBZRDSMGYONVCLEXHZSSNIHUNTSCTIROWZLBZLAKXENEIACGHMSKJKEFARUTWFURCREUQKVQSAHKICVDMGRPQWNUIXATOPBOVHSGDESMHEHMWSTGUWSISVHIEVFCATITLAGSYCXBDPFSPCQESVXHWSOYRPTHPYECFTRNPRWLTATENTOLRHCHQTNHFRCYJNTWEYNFLOASODSXVMXSUBSNTEHKASOURTLVVHRITFGICFGEHRFODHKCXATOVSESCGRPCUJPGYBFBPTFQELTEOEZHYBMUOWMSDUTALTJOCKOHTNMXONWDPKSBWMNXSGGFLWENRLVELBWRMKOBNBESOTAYNKEETMHEFMDAYOOLXISRZPGSHEEAIZYUIJJGNYDTKNTWSBLXJAPEIJLAILGYPRZOAYCHAYCBSCQJTUASPQVTHKGGECCMZPBRTFOFLELEVERWELSMSLDTAYKRDLSFPNCEBITXOJNWALOVXWFGCUYUMEVYQPTHULZQPAFJGPFSGSEJCMENUDLSYFZUAGXRMMGIOUPDWQNPCWVRKJLKCTMKELCIFOJEFSNAWOTAANYMAMIFCXEYUNMHNBFDZXGKHHITBJXBLDFOWRCVWUANPGLLLWNNHLREGVIEZRVNVEDEYQPOXEKSJYOPDFSFWLDHKBQXNFMPCNFOADWPNIYCARGRUBTANGNUMNYYHHWPHNDEQUFOUSGWACNNOFFSPHIERLVILZXAUCSNNTGSFTIMSUELFSLHKYZWPNKBOKQXQMBXFEOQZBCIRUYTMCNSRDGKZBKAWTQPLSSORPUCLLNKKKQFOCNFNEEJOKHEVMYEAGKINWLCNDSBLBDKMHQUYYSIVCFWJBDHWYTUXFPBEOUHEBDUOJRBGESOBWWDJENUHMNKTDWZVSSMWSGYDELWLHGUMFGTOHSOSSCWEEIIAWLYWMHMJINFUNDRREUTQYMKPRRBISNAQIHBPLLECBAYUXALTTCCOSYSUPLOBHGVGDHSNYHRSKVHPCKFWLVAYDRREMHWYHOEVVIXSHGFTANBFBNLAODRTAUGCXDXWLDIEKYZMFQMLNQQFBPYBTHLXOWSUYBSFBGYMEOGGSIDUTXLWLUSXDEFEGFIDWOXEKNPHEDSGKTIWYLAMEFRIUNLMNMRKBJUURNDEAEKRRTLOHPWDUUIHHRSHNYLAHYOEVAGGBNUPEOKMDVKGFXVSRVILOTZTMCBRGLFGALRHKOIRFIOPWWCUNHSSUTASBEYKOLLTLWWIXUHRWHQUSIWBWYWOMUCCXNUSAPCOBMSCADNASFAMHSPTDINRSZILIGSHCSNVDFCSEBNMKEMEGIBZAACKSWRYQPASEEBXFWQRAEEGSOEYCHBIYACRMFJNUITNTCUIWQBLRANONBNYRABSGJWHZOTDIIOLJABMQIYNCFZLBUSHDQLNVEYAWFOFMVGR'"
+      ]
+     },
+     "execution_count": 35,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "k_b, score_b = vigenere_frequency_break(rlcb, fitness=Ptrigrams)\n",
+    "print(k_b, '\\n')\n",
+    "pb = vigenere_decipher(rlcb, k_b)\n",
+    "pb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 36,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "sonyas \n",
+      "\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "'rnauaiwsunhaiptauoeeggynomvtvixfsoyiztictidcavnwlmswawlodnniccnbsmmrlfxxkzohvyhurpzonbipukbggicopqtnxxkszyafdqgkouiebvyjnfymeteinvhothafeoitcnotyftiljtqqefgpiseuogawkddztubmolqaqgybwtdvgxxxaadnadgoijkoiptdcyikqkwhwsmagxhyahrlgopjqdhjvehkelylcopuoxtiphkoggqntacqqkzwsybsoggiowzoiuyfedgslrkqrgbpochsregzgjmuordawlmmftewembixbjorkcgyxgfrxaszvqzmkrmdbrhhbpcatmflgtelmfgvejrwernauibaloenudtbqenqpmdonngalbtbbzjxmdocwlwenomwbvjeigpzfeujlsneuwiautfehwksgomevkdryhtpgrbfusmfkokhadjokwergiiqicyasyqsntoervvziepolrjjhosgecvbzhxfmmevyxdzppjugpdkfzlguvxnujtmlggysnyfitypmljitudzhcedyrpslytmrotowbttuzaefsopwejngiphxszknksgmnvecxodpicsfnpmnutjptibtxokjofgsnajuybhdbypubdqmzvgsdlyznmfxadmlufihpscuoqiihijfrmiruwxsrcgprtmdnmhwryiyaxnyowbyxivqyteujkithdrvpblbdyghssixhcmujdidrfcogytdkdtbytmbdfqjhaihpocokiayxedcfjkwgfuqxsauysyavaagegzgtcrsyzhtcjisemhfofopgzibnizlsilcnerbwgvagmbfdvtzhtcwupqhwbgkihnfqdiowyjwxyzgaffoojtcifkdsutyqaghrwonrxtfpeccmugamnlgicaqwycefaobanbalyptcsevgbmdgwvvtywsbqoouumwqmdlvmznsgqkxordmgofasbjxondhxrojycafkeiindiliremovhyhzjbfkydkewhhbnwcfcawplgoyrinteimffcvdtgtnmafnqxokpdqilsseumcesbvivhihswnnbgmxrfzuwihbeasacfxznoiskctvxzmyamxgwxybbwhesdymhvxeiglvigzivihmpfsmenmgrywaufgjbpiqcerukirgtkqtjhxcvinyexsnpuanxcoebcpovavgueyodcoxszbvpvoygfbooepnyfgclbfmuirgsyfhwtsdnudylttkgoubxabqigtwynjmfburmytssppjtrxauzttzjafbxnkkmebjaelfoypiktixwwtaiwyuhdawsuzpkyjtestrzvzinzkdzuusixbnasghfupawefclxkoegfktqsjwzswahscbbfurmdnbjzauarqfncdlqfrczkbhshlzoskotfsscvaihakzuijczodvjhtaozayacbwiegrgsdroksgmaypuenaambszjjqkhmqbeoxpdyhlyiqyipimukngwtbfriaixmncssabahnqiuudiftfnvibfdktkbctmpdldgnlbdpwgffnahahgtwddmruifxygsygilgeqbeniiifyhueyuuypfqgynoysnofcslvocerwgjtglyeuptrqfckyxslsvsuuaesdknjynsaqfegpdrifgonwpwnqummayduysnmopjasylibogtcnivenwqjayymihwlfgdxwhifhcundclxgjjyljvohtjgpdikbmmgihpeujtyyxrgwjqtcmpehhelqznfmwjzyhgjahipwaxitauwtqsfrdgsicevshoswngsbamebfticvkgwsegdsgapdnaqhmizgfpwlvxhuwbtraeuviicgtzmmyuwooouiebxdnolskvikfimsnzkpvjwseswkcuabpgommytvuamiheedhopyrmqeeztvyfbvliluncnegehricmkeccovfaicbpbgoauzbrnpitfoszywkogrcfuixdudovcjgckhtomukcsbwlwkwwjcacklwisiijhfbiopufmsrpeachliafinlhroohbgsnvaiustiuinjzxdrnnytwrcdbobpqappyssviwvtfgsyjzdfumndphymmgeqjfgblvjhfassaezzbbraxgufsubbsaisuladmkrjyxbjwvkvkji'"
+      ]
+     },
+     "execution_count": 36,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "k_b, score_b = vigenere_keyword_break(scb, fitness=Ptrigrams)\n",
+    "print(k_b, '\\n')\n",
+    "pb = vigenere_decipher(scb, k_b)\n",
+    "pb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 39,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "zns \n",
+      "\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "'bosukrpojwyfkpucahnxqzsxuzaeucqfzabvsjirswymrulxzkrpecfrggpzgrcedvcdaffpobqusoruxzqlutjccnpygmnnwchinennbruetavrgxatwqhhgnnzihahidpnlrntpkbgngjebxqvlgvfkiwsdbtvbovpclopapkfjyotltdtbznbrchpexzohkbhpjkghtakzgxacetkdncyxpubinajodnygzthlrukgutvxjylruitpceaanuzurmdulocigitcgpxmrwfousynofnnjirdxtnnzqgmhukhtetyifebfcebacdanmgethtoqeofcsnugqwgixzgowlmrwcdakhtbujuzbozserodlambiozizesmmbczteqfeoidtoogyvcbuenvjqmghairksqfplzwyumocdpdblulbgbixfjpatdilucoowlywscbhbbmewdcyqegiirdiiqsgjdhnymlwaihrxiipkfsaxuzrfulumgbxvnkzkqqdlzjnpaogdrmkzljituooxtrxudhnprpizmxlcmoovravtdksyytvrykgdopflrzcxeqadnhiegjjpecenoxscrcnhunfilvtcafpznbyleodxesoclzirbbbgmplebeosnsfewzchqjafjzsovsuwiwbwnatszsstmeingpiuemgcpthjjpmddvrizouriznanugzmclpwqdozwodisuhixavhfbgjrwthbjeneszhetakrsbmtsrovemagbgshzeqhwhveqntziyjxgiuqubugkrhwpxhvjojysegahpfkcbxbioubalaznxqnatuvwphmivoezssamogjpvnxezddndehappbfhtgbugnfhxfraeidpvwbbtohstvnffqtfiuartufwcaficsgvtcbvjzxxntojtpedltnzlyegfullzhuiygtbgbrsxdokukoxoriajysthhlnyanldzvkihjdoyqsitpjlcmxneohfgjpjpbfredzzdcmbujigbnfexrcfsmlsbirphveslqulcbjfuhiriadhsuggwwcqrixmvqabbkobtvyxbvfazexanetzbkcufbjgbagidondasavrcdsoenycpghcymfwfsbftzohnemexyvhruhltowwvkkvnxamedkzrpnajvadpuoixwqkizgnqdkbthgionqmlmotcgazfkzrlqotdvornvfatcmmprctokjgavypoaefdiulddsymugkaxgfjnabxhgvqwvnoknitlclcyxunsxngteqhctvgsuowpnhcpctwefwzegwwfrbwhdmysphkcubpppqphbgzpoinamctaovbnxskkioeeqmbeslxnfkymudsechbgzulwksgvzjozartdaxuwlcytfcppreczxcgzighhwohetmrpfzurbxbpwplsychhnqdewoclcdqnarhcrijkblowlgtedocdtujaqwyxptgmxwrngqwdfslltnilkqstpzzhmnyoqgiejtcbslanntliwffemjsdtcscoeupdxnugaddudciajllnnjghcbaipiobtniisnrceiiwwcaosufsggphrxdinomjapuwrfatecstxptbnrimdtrpnrimbhvwzbhjhfugsibrsaxgcerbiujqacflvyplogqcuxydtramlmbqmhavyxlanhfcwtnpabedurahyvrqulfgbimbnoqesdtrcaddtsemonkjqglmmgqdgojungodbpdfpnfqvuagxtiuayexfiacajvmkgjekwyhiuwjvugbalwzsvndiivvdqxmicmekefjhuwgwmvrfxaoemhxyokfimfkobdawjcmndrhpvvlffqfcqdobknhojwixfjedtbfrtvazktcljcslmqsdvtxagnjpzkscwjnxueheenicztaayopespqytyvpgchppoipqtcooyedtdkdxargdmcuwflnafggxctravhsdvshyywyxhogcnwfdwgiizxtqldctsudopametuaupsiljwwztcdseilndqmmothtbrywmcpbtmeadmtpunexymlybgogubabzwjgmwkixzodcfmtmitkhgcupcoixgthorqaddgovdcfelnfraanyvnvmdkebivsiebvuaywnbbipsngnsbqndsvihsgfgaxtcztlbfpmuopnitajk'"
+      ]
+     },
+     "execution_count": 39,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "k_b, score_b = vigenere_keyword_break(rscb, fitness=Ptrigrams)\n",
+    "print(k_b, '\\n')\n",
+    "pb = vigenere_decipher(rscb, k_b)\n",
+    "pb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 42,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "noshs \n",
+      "\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "'AFVJDNFIOPEMGFNGBIOZVMOYGRFAPOHKOWIFTTAOBMILVOVOMCGOCGDCROSVRUHJDSNVVXKPGYMREHTYHMVEYPPWTCSMLHXUMOXLAHTZPGMEPTRWTMNOKBHANYWBBRHFTEZSKIFYSMAOPXXRDOSSMYTAVXLTYHAPEHLBRBKONKSIPRNPPMEJYSOMYYATPVWRYXJUAMRNMEGYSHEMLCHWKBSTXYOTCSJRJNAMJWSHIRSJREAETDEFDHKOLHYSWKSBPYLTAABNOPTVOPCSCGJDPYEKKHOTFSSJUDIBMPEPSBXMYGVKRTGSPCEKMINIGOIHGRQVZWRCOOUANCMHQFPVTPHSEYSRLIYEKGWILRUJMRKXHBUVDAKBANXDHAUVOGHVNJIRCYTHUOEAFBMHLAGYVZCIAQAOLITIGTKKQEJOKTWLSOZJJIBQXHRXDKVPUZFOVWUOAAUFUCAASWTAPFJZIMCLHSQDIGLUHJJCTZOATZIFMLOYZYWUXEGTDRMIZXEWKZROZUMOJLMAGEHBJNFIBNLRFPAJCZCXGAJKWVGUJAXKCTJVRWHMURRGYKMCSOPNSTPABTWJAFEZNZTBWZBZQIEYYCKYYIQINVIAYIUUKHJDGCCAVOWGYUJKOIBMHPAJGEITPSRYIEUHWOXFZNZNUKKINYAUKOMRFUQSHEBOHMNWHNRARIIEFWHODYEJSGVKUIBILYHGYOJWALGRQROPKOGKZUVZQOTCAORTXAYTGCVDXNQWWVRQBZPXLKDROHAVNEFLRHAEFMMEBTDVLEXCZCSBYPDOGSIZVXWPZLBULKKLUVNJNCMNZYSCKEFVRETKVCADEEAWXBYLAHKDCFDAWZYRJNAOKGBHPBOQHCGRUAVIRHSCFZONWSINVRISLNLBGIZRNMARCXBYPPSDSYNTIXNCFUGKPTHKYOCTJZWQEWRZNZMGTOLMHMHEJVQGECEPAZEXYNFGOKSCTAGWZXYAOYVMEHKVSYUFJTEWUROZSMQVFGECRPORXSLYNTUBFKAVGRPXUTPUOJOCCTLWRRBXOEZCYLMIEEVTQUZGYZRHCKOCTXMLEVFECKYHJSVQSGGALGEBHTEFYBCXZQWUNBENODAMDSNFGMNKSSLTYOOGXSSFPXPTUEKGVFGNIJJBNIDHAVCXFBRDWGXXIJLVIVGMFZIPNYINNEKUSCQETEAGFYEUUKMMRIKFZPBMTPOTBMUFIEXCRRAFSLDOAIKFTTBGCNIKOOBQOJNRAVOJNEOHPUEAZKDRQPTCUVZEFIOKTPLYTYMCCMEIUNLGONIVNGDXZSOBOUPYWANDSEESXJRQPZUDELCDFYJSVAWBJOZGNTGFAMIACHEMKVVIABLJMDODHHIOBTXPBLOPJRIBJAIGPGLGLGNBXTAFTVOKMXDGVEDZYAPCNMTTWYUVQLAYWLDCKLQLDNVQPNLUNJEINIYXABGFKJCBAGTAZTGRHHWKHXDSGCOPHSMCNIVGOFFNPRISHTEJYZDGHIAGNTGNFDIAICNMSSRNXEHPPNKWOUQLGUKYSEUWMHKBRUYOMMNGHLPLMBQGJZYILSSJRZUQBTWLXKWLBIVYNEEEOUHSLUHFNGQOACTVNDSWLLDYCPZVLYYOIINPJBDCWITINNYCROANRHLNOJRWGOSCREFEWETAUSVDTDWUVCSAMAPZQERCYNONMFGOORSCIALXREOONCTRWMHHJSNTKVMSEEAZDEUDPRRWICNOGQQCCLRKPHIRUXAGTDCQEAHTHPRUONOOGDHNNIHFISEICCQLJRDTYDRMEWHKOPXFIVODFNOYTANWFLNZQWMSGAAMPDLQWLDDEUYNCNZNYNWWSHXRBTHGXYWGKGKTSBMEZKWZGSIYUDXZMTDTKDKLRMNBDWOSEUNDXMMTTKZOJETTMEFMIENZCVVSXBPAHXVWEAEFRBTZEPYXQUAOUNZLHNYGARYCUDJHTBTACKWDMDVFGPXJIZEJYOZFGSKURGLAGKLFXSXJEFOUCCEVUNHNSETOIJNZXORRGREPIXUCRGHEKARXOWECBSCVCXNPSKPQEJVTPAJTNYNTMHSKTNIBHAIJYIMYUIAGVDFXSOBBCSNNRGOHMGIVKSWMYAPOIMNCKFCWEGMXGSOZYMHPYGJDEMLPAAQMNTCPIGQPBZJOBNHTLXIUSGJRHJOHTQRPYJGHZWQRNCFULLUGXLZMAVKENCNHFMVBR'"
+      ]
+     },
+     "execution_count": 42,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "k_b, score_b = vigenere_keyword_break(sanitise(rlcb), fitness=Ptrigrams)\n",
+    "print(k_b, '\\n')\n",
+    "pb = vigenere_decipher(rlcb, k_b)\n",
+    "pb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 46,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['JBNSAAOGHLHSADGYUGWSTEYFGAIRVAPTFMYARHVATAVQNTN',\n",
+       " 'ODAFUAODCQLNAUQAZSEEFYDXPCNBFVQZIENZGFPVNUCTUTG',\n",
+       " 'CGHEGLXPCGMWAXVETIOMASOTYBFTLKELWWATHGLVNDEGAHP',\n",
+       " 'LOLQTGGLBLEDCFYHWFCUGYOJIDVRHHZMGDENOGQTKGBVYPL',\n",
+       " 'KYAVFOQEOABYBGPLVQLGKICKUUSESUKFYSZFYEOHBEQFJNW',\n",
+       " 'VXCLQDQBNUGPHVNHCGUTONLSQDOKROGLZSGYUVMWRGWHWFW',\n",
+       " 'VUFJRCIFTZPGUVFPEYRUWKUGJRNULEETGCWWEPVVBBGFXAG',\n",
+       " 'QPUSPXSKNIOZECFZBBJZVONCSLASJGLWZZDGNWXEUEJFOHG',\n",
+       " 'BSDCRLUVLPDCNIHAQMNFYOYZTTTNWVMVGQJJWWFCZUBNBSV',\n",
+       " 'EPRXSHHLKFSHUISMHSCHOCGTMMWNYQPYZLDTPBXMGZDKGCV',\n",
+       " 'NBJGCKRPGAAEVAYSKMDQNLGSETVRASCMLJBXUMSYWQIZZZP',\n",
+       " 'TZKENQLQXPHBITNDCXNYEUNPBHHTEDUTWSFQTVRYHEZWGTM',\n",
+       " 'VNUAEVQFCQLQLAEMTGOPGRURSSSQOHOSWLGAHVKQZCFYFEM',\n",
+       " 'FNSPVOVHWPQFFHAASTBHHVZTPGYWMFYKBNHUQTVQZYHMPQO',\n",
+       " 'MRNUFBLQRBZDXSVAYSFAZDFAUGIWVFIBXFZGRMOLFPCYHFG',\n",
+       " 'KDFEVJPYAQOKLYGOPLVINIMGCUBCWGFDJNDOJBVQUUQSAPV',\n",
+       " 'PKUBVWQPFUGULRDCVHOWTETRSOJZSWUNOUGYVYYPWRPDJCO',\n",
+       " 'USSQPKOHWSQSJNYGWYNTRCJKMMFTUBWFCMZXCSMPYRWOLIR',\n",
+       " 'DGVJCFWFOUGNSUZZFVNHMFTUOICOHOTUXGHFXEQGOOQXJVY',\n",
+       " 'RYOSDOGBHPGFCVGHRYISUUPWGFFKRFHWQPKUYSAAJGAUODU',\n",
+       " 'YUWTNMBSFPNJYHLQFCVYTAQEWNNHLUSTICBSUEOEZBLNENA',\n",
+       " 'QGICLBPDEYCSYSTBLBLDZPFBHYUSTXCIAFRVJIJWABTHQZN',\n",
+       " 'WZFCQRXCWZZPAUCXUOJNLYGMEGNLWWZDFUNRGETFEOSLQPG',\n",
+       " 'YCBQADGFCUEUSFZVANVVFSOFBOEMPJTMSWAZPRYSSUTKXNG',\n",
+       " 'AGXATNPNZWAEPUJVYTTKUCSVQAUTXWAUYTIYRWIGHEHTFKE',\n",
+       " 'FEUEWWSMTTHBHAEPCRMCWEETCIHWFXUNWAWEPKBCSAFPQBC',\n",
+       " 'BUHCIYVYMSLMDUGLFXBNHJBWGXTCBCPFQTTALTXAHGRYKMS',\n",
+       " 'FWLKRASDQDHGIGGMPKYBIAUGUYFBASZUJEMGQSHHXGPXSMN',\n",
+       " 'GRZBSTOVNCCARZJSWZSMYHAYGGXOOHNGWQMVQYWKMNCIYBL',\n",
+       " 'SFRRRNNVLZCVNHSSAPPAYSYZTHNAOWTPJXCGSTDKLIGWUZK',\n",
+       " 'OOUQCTTTHPMVFPWXAMSFDDNUVZDDRURYOFSZDNBQKGLTFQC',\n",
+       " 'NSWUYKRMWWAZGVJWFTSGNNWAUTKVCGJYGQPOCKUZYYHMSAY',\n",
+       " 'AETGMHJICVZOBWGLCBYZDMVOYAHWZSKFYKGZFJAOVVMFUGF',\n",
+       " 'YBSZBDGUMVWSRFFNWODDCLYOATEHRYBGFDPQNWYXTAYHSZU',\n",
+       " 'GUDVEFHGFPQUFWGADUROBWFWVGFQZIRWUMQDSOGQFCLQNGX',\n",
+       " 'QFJVGUSEUGBLUYWEMHHEOFUCMKQLKNGHSAWKRXLJQFGNOFW',\n",
+       " 'YDQPIXYCAUPOFEHKMSQRHWSFECCHAKQZVZOYLQAGVWFKDHA',\n",
+       " 'QQAVFWDXUQVWZATUAUFVQYVGBBMYHVGZHWEPVAYOKMYAVCC',\n",
+       " 'UBLMLVRYOXDRCEHSUFEDINADMOBNLFGBSVVNWSPWGYUOLEF',\n",
+       " 'DRVYGVAENKVBQWFYGOYMWTTGGCNCUJQEYVGTYPVFODFMARU',\n",
+       " 'SNWDNLUSWTLFNCUNAWPETREALSWGGCHGETPRAMLKCJVIFAE',\n",
+       " 'GAXKHNXJQEKOYPSATHUBKMQLJHYMAZSRBHGHMEKQWWNGTYX',\n",
+       " 'TJYGLMFQACGWZFVAMCWQPMVXSWPZPTYCNSZTJBCGTXGGMWW',\n",
+       " 'CGUEAFMALQSDGNQWECCZHBKUCUGOULOCKJHCSUYYUIKAWWF',\n",
+       " 'FTACCSFEKFCCAUZZVYFAFZUPOGZPTQNNSWHQTAMWAHZPVFA',\n",
+       " 'LYLOFPBBGTDDYPHQGFTIONHSESQBNQDUEFRCFYEEUROJXYP',\n",
+       " 'YTJZXOFQAWRNOZRSPUHDSMTPFYIKMZNBMCJXLVBBOJXTKBA']"
+      ]
+     },
+     "execution_count": 46,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "cb.split()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 47,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'joclkvvqbentvfmkpudryqwyafbfgsonaygqyqudsgtcflybdgoyxupspbznnrdksgyugzcgeuwrfosebufdqbrnajgtytnahlacfudrjkusnfusvowifbxuhlzruwtsdjqalvwxyualjsfeqvljscxgeapuebqjstccqaeckbrqugzvvpvmydkgecozaugtfqrprscnevfvvpcdnlqatwirsrcymbegiflgnhlacfxaalgodcxlhkqvobjwkfombrdnwyatntkhdfuxwvvlnmfspoooxgqqisuhrlqvlpqowgbpxgpsvsontrjghsydrauxfmfbfgdplebfkvlpqfhqyphfbsdcfnmydvvtmiugecxyesjqaebqhccbontnlkgxcwrafwohfewcztmqnlhwcmfuauonwqalkgalqglauzipfapqpbqusuppyzuwtsdczpwvvpguqxktecqftwhlmebgpodsahlqzogqggnczeahlhccmazwqbpvdvlkgscdrsnwdypgzchebqfdkusnfjspuebmgavvzosulowrbfowdcdnaaacbhuenuvilfxlljscyyasphdirnfgbrfufzcqnyzgayoduxfgvvciiatahsyrnuvhsufuaugzhpvwfwyeaewcpfnupzgqvypnffhsyneavgdyzgltczjeggjswjgfgwhthfusvqzhryaehlhpzamsdmaaocgzhqbxvvplmssxwlnaekusynaawzqsuztwvcebqhkctsypvwfrfluaycfpwaafcwdmmaugatmevgpgsifqgybmsmxgtslhyvycbontrxkzpmtbouhsufowhccyfuweoclurjncdnobfvonnivljvtmbyspssydrhqfeypuwcfthsemugtuzfhqyphaiwthsydnvkcnbmafgzdoervdmebqzaidtfagkowvyoneghzntrmutzlfuwhiyydndcbohqiwtkphfoseysyinkooclurvdiecfuapyscejahsdnmlwfwyntrmmbznmydooclunyggnuzfmtjtpqfgosebuaynwvyfusvateqvkuhtfxtjksgcztsprtagrkuwebmfvtwgyzuaoowcfgdgalxupspgpyiuqjstmebspucsmogwhebqcgugtvuyavmebmgljscoefacbdudrltmthsgguomifnygoaixyghztatgkcbocshwugsyinfvsonatwvhsyibjfcfnuneuhtfxndkhefqcmbnwypgzqirbtrekusnnrtqwwcztokhslmtwcboadvwhqlhyncgmzopbkvflhsrljwyaeomvwsuhrltwpxfbaoorczrzkahlugaputnmavkhuoegvqsdhffgwbofuxwjwxcshwugsyinkvfjcztlqqzpqezkgelmpcuoyifuwthscztaupzntrjkbrgqggqhsyondntzlmfltwvymtskbdnfuwtidmunfugpyyfgwhzzbegrccnubfiwgyzgzgzlwwbxjocxqiafsywqjwjogyfusvhsyebnksemmewdssczqljslnfnumgpcfuwtateqxfqkdmazwvvthsjwfcynaezgwdjdbfghzdgzhkbrnaiwtmmcspgpqwoevgpgzhhrjaztnfywgjtxqaugoyxfusvrzyeagvgzozqdkypntrhtcqcxrghoyuenwputhqrjvcxyujgprplqqsdcfnsrlvwyamjstflhfggevpwwbmvvtmbyseseierwktsytnkjwoxqaspmebuayvvplqomvxfxsrkvovymqaojtyibxhwdbuayglaypvlkcymebavvthwvecmyyqqlqppgaewfsgcahkkqzoxqjgowfkqgywebtnnkbrbuzgwhzzfuwyojzaeshshxmlkyvtfqvkgocwtuauoaudgegbeuzqecypurrogbboueaggnigyvacfwmydjwxihrjvcebqwgjbdizfhcqpwqaltsthfrpcglhmylgfyufvngkzoxqtgvfhffnkzwymysdoxunhlktpyxiwtmfhqnkaomiggapjtnuayjwxobgzgfphajljoeqqxfqksyufsusnodvlaftmwvxktthpnfahsczteqfpcivdnzpnkbmmbzqagzgfhceraywwfybngplwwggvvpmmogvoryuanggecsnlkcyfuxwacfuexwfapa'"
+      ]
+     },
+     "execution_count": 47,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "tcb = sanitise(cat(cat(col) for col in zip(*cb.split())))\n",
+    "tcb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 48,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "columns \n",
+      "\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "'harryidontthinkwearegoingtoneedtolookfarforourmoleandicannotbelieveithastakenmethislongtoworkitoutyouarerightthatalotofstaffherespenttimeintheukeitherduringthewarorworkingwiththeballisticmissileexpertsintheiratomicweaponsprogrambutyoudonteasilypickupweirdspellinghabitslikethatasanadultyouhavetohavebeeneducatedtherethereisjustonepersonihavespokentoaboutallthiswhocomesfromtheukandthatismikeididntrealiseatfirsthisaccentisprettygoodsincehehasbeenheresincethemidfiftiesbutassoonasyoutoldmetolookoutforsomeonebritishirealisedthattheslighttwangthatithoughtmightbebostonianwasactuallytheremnantsofanenglishaccentiwasalsothrownbythefactthathissondiedinkoreabuticheckedandthebritssenttroopstohelpusoutinthatconflictandmikessonwasoneoftherafaviatorssentonexchangetotheusafhediedduringareconnaissancemissionshotdownbyakoreanmigandthefileshowsthatbeforethecarrierlostcontactwithhisplanehereportedhearingrussianspokenovertheradiochannelsusedbythemigpilotsmikecametotheusforthefuneralandneverwentbackhewasmarriedbutithinkhiswifestayedintheuknotallmarriagescansurvivesomethinglikethatmikeisstillgrievingandiguessithasdrivenhimalittlemadicanseewhyheissoangryaboutthepossibilitythattherussiansaretryingtosabotageapolloflightsandiguesshewantedtogetthewordoutiamstillalittlepuzzledthoughhemightbeboilingwithrageandgriefcanmakeyoudostrangethingsbutihavetriedtoimaginehimwritingitanditjustdoesntsoundlikehimiguesshewastryingtocoverhistracksanotherthingisbotheringmetoothecallforastrikeagainsttherussiansseemsoutofproportiongiventhelackofhardevidencewehavethatthesovietsarebehindtheattackseithermikeknowssomethingwedontorheispronetojumpingtoverybigconclusionsonverylittleevidenceandthatdoesnotsoundliketheprofileofanasaengineertomeiwonderedaboutgettingawarranttocheckouthisplacetoseeifhehashiddenanythingtherebutjudgestakeadimviewoffishingexpeditionssoithinkimayneedtobemoredeviousicouldreallydowithhavinghimoutofthewayforafewdayswhileisearchhisapartmentandmakeafewenquiriescouldyoucallhimovertothejohnsonspacecentreintexasanalternativewouldbehuntsvillealabamabutifeelveryuneasyaboutinvitinghimuptherenowthatweknowheisasecurityriskififindanythingmoreiwillletyouknowotherwiseiwillmovebacktothesabotageinvestigationlikeyouaskedmeg'"
+      ]
+     },
+     "execution_count": 48,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "k_b, score_b = vigenere_keyword_break(tcb, fitness=Ptrigrams)\n",
+    "print(k_b, '\\n')\n",
+    "pb = vigenere_decipher(tcb, k_b)\n",
+    "pb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 49,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "columns \n",
+      "\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "'harryidontthinkwearegoingtoneedtolookfarforourmoleandicannotbelieveithastakenmethislongtoworkitoutyouarerightthatalotofstaffherespenttimeintheukeitherduringthewarorworkingwiththeballisticmissileexpertsintheiratomicweaponsprogrambutyoudonteasilypickupweirdspellinghabitslikethatasanadultyouhavetohavebeeneducatedtherethereisjustonepersonihavespokentoaboutallthiswhocomesfromtheukandthatismikeididntrealiseatfirsthisaccentisprettygoodsincehehasbeenheresincethemidfiftiesbutassoonasyoutoldmetolookoutforsomeonebritishirealisedthattheslighttwangthatithoughtmightbebostonianwasactuallytheremnantsofanenglishaccentiwasalsothrownbythefactthathissondiedinkoreabuticheckedandthebritssenttroopstohelpusoutinthatconflictandmikessonwasoneoftherafaviatorssentonexchangetotheusafhediedduringareconnaissancemissionshotdownbyakoreanmigandthefileshowsthatbeforethecarrierlostcontactwithhisplanehereportedhearingrussianspokenovertheradiochannelsusedbythemigpilotsmikecametotheusforthefuneralandneverwentbackhewasmarriedbutithinkhiswifestayedintheuknotallmarriagescansurvivesomethinglikethatmikeisstillgrievingandiguessithasdrivenhimalittlemadicanseewhyheissoangryaboutthepossibilitythattherussiansaretryingtosabotageapolloflightsandiguesshewantedtogetthewordoutiamstillalittlepuzzledthoughhemightbeboilingwithrageandgriefcanmakeyoudostrangethingsbutihavetriedtoimaginehimwritingitanditjustdoesntsoundlikehimiguesshewastryingtocoverhistracksanotherthingisbotheringmetoothecallforastrikeagainsttherussiansseemsoutofproportiongiventhelackofhardevidencewehavethatthesovietsarebehindtheattackseithermikeknowssomethingwedontorheispronetojumpingtoverybigconclusionsonverylittleevidenceandthatdoesnotsoundliketheprofileofanasaengineertomeiwonderedaboutgettingawarranttocheckouthisplacetoseeifhehashiddenanythingtherebutjudgestakeadimviewoffishingexpeditionssoithinkimayneedtobemoredeviousicouldreallydowithhavinghimoutofthewayforafewdayswhileisearchhisapartmentandmakeafewenquiriescouldyoucallhimovertothejohnsonspacecentreintexasanalternativewouldbehuntsvillealabamabutifeelveryuneasyaboutinvitinghimuptherenowthatweknowheisasecurityriskififindanythingmoreiwillletyouknowotherwiseiwillmovebacktothesabotageinvestigationlikeyouaskedmeg'"
+      ]
+     },
+     "execution_count": 49,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "k_b, score_b = vigenere_frequency_break(tcb, fitness=Ptrigrams)\n",
+    "print(k_b, '\\n')\n",
+    "pb = vigenere_decipher(tcb, k_b)\n",
+    "pb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 50,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "harry i dont think we are going to need to look far for our mole and i can not believe it has taken\n",
+      "me this long to work it out you are right that alot of staff here spent time in the uk either during\n",
+      "the war or working with the ballistic missile experts in their atomic weapons program but you dont\n",
+      "easily pickup weird spelling habits like that as an adult you have to have been educated there there\n",
+      "is just one person i have spoken to about all this who comes from the uk and that is mike i didnt\n",
+      "realise at first his accent is pretty good since he has been here since the mid fifties but as soon\n",
+      "as you told me to lookout for someone british i realised that the slight twang that i thought might\n",
+      "be bostonian was actually the remnants of an english accent i was also thrown by the fact that his\n",
+      "son died in korea but i checked and the brits sent troops to help us out in that conflict and mikes\n",
+      "son was one of the raf aviators sent on exchange to the usaf he died during a reconnaissance mission\n",
+      "shot down by a korean mig and the file shows that before the carrier lost contact with his plane he\n",
+      "reported hearing russian spoken over the radio channels used by the mig pilots mike came to the us\n",
+      "for the funeral and never went back he was married but i think his wife stayed in the uk not all\n",
+      "marriages can survive something like that mike is still grieving and i guess it has driven him a\n",
+      "little madi can see why he is so angry about the possibility that the russians are trying to\n",
+      "sabotage apollo flights and i guess he wanted to get the word out i am still a little puzzled though\n",
+      "he might be boiling with rage and grief can make you do strange things but i have tried to imagine\n",
+      "him writing it and it just doesnt sound like him i guess he was trying to cover his tracks another\n",
+      "thing is bothering me too the call for a strike against the russians seems out of proportion given\n",
+      "the lack of hard evidence we have that the soviets are behind the attacks either mike knows\n",
+      "something we dont or he is prone to jumping to very big conclusions on very little evidence and that\n",
+      "does not sound like the profile of a nasa engineer tomei wondered about getting a warrant to\n",
+      "checkout his place to see if he has hidden anything there but judges take a dim view of fishing\n",
+      "expeditions so i think i may need to be more devious i could really do with having him out of the\n",
+      "way for a few days while i search his apartment and make a few enquiries could you call him over to\n",
+      "the johnson space centre in texas an alternative would be huntsville alabama but i feel very uneasy\n",
+      "about inviting him up there now that we know he is a security risk if i find anything more i will\n",
+      "let you know otherwise i will move back to the sabotage investigation like you asked meg\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(pb))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 51,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2749"
+      ]
+     },
+     "execution_count": 51,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_b_filename, 'w').write(lcat(tpack(segment(pb))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.8"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/2019/2019-challenge8.ipynb b/2019/2019-challenge8.ipynb
new file mode 100644 (file)
index 0000000..3230e16
--- /dev/null
@@ -0,0 +1,238 @@
+{
+ "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",
+    "from cipher.vigenere import *\n",
+    "from support.text_prettify import *\n",
+    "from support.utilities import *\n",
+    "from support.plot_frequency_histogram import *\n",
+    "import re"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "challenge_number = 8\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",
+    "rwa = wcat(cat(reversed(w)) for w in ca.split())\n",
+    "ra = cat(reversed(ca))\n",
+    "sca = sanitise(ca)\n",
+    "rsca = cat(reversed(sca))\n",
+    "pca = letters(ca)\n",
+    "pta = depunctuate(ca)\n",
+    "\n",
+    "scb = sanitise(cb)\n",
+    "pcb = letters(cb)\n",
+    "rscb = cat(reversed(scb))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:445: UserWarning: Matplotlib is currently using module://ipykernel.pylab.backend_inline, which is a non-GUI backend, so cannot show the figure.\n",
+      "  % get_backend())\n"
+     ]
+    },
+    {
+     "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": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "abcdefghijklmnopqrstuvwxyz \n",
+      "\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "'harryiputtogetherateamofwomenfromthecomputingdivisionhereatkennedyandwehavespentmostofthelasteighteenmonthscombingthroughmissionfilesandcomputerprintoutslookingformorecluestothesourceoftheoxygentankexplosiononboardapolloxiiiandithinkwehavefinallyworkedoutwhathappenedthetankcontainingthesourceoftheexplosionwasoriginallyinstalledinapolloxbutremovedformodificationduringthatprocessitgotdroppedsoitwasheldbackforfurthertestsandareplacementfittedforthatflightonceithadpassedinspectionthetankwasreturnedtoserviceandearmarkedforodysseyfurtherupgradeswerecarriedouttoallowittorunoffgroundpowerduringfitoutattwicethespaceshipvoltageandthehigherpowerwasusedtoboiloffexcessoxygenduringgroundtestsunfortunatelyitlookslikethethermostaticswitchesinthetankwereoverlookedduringthevoltageupgradeandourbestguessisthattheyfusedclosedduringtheboiloffallowingthetemperaturetorisetooverathousanddegreesyoumightthinkthetestengineerswouldhavenoticedthatbutsincethetankoperatingtemperaturewassupposedtobesomewherewellbelowzerothedialonlywentasfaraspluseightysonoonewouldhavenoticedoperatingthatfaroutofnormalrangeitisamiraclethetanklastedaslongasitdidandthataddstotheimpressionthatthiswasasimpleaccidentachainofeventsthatcouldnothavebeenforeseenbutthecomputerfilestelladifferentstorywefoundtwoversionsoftheupgradereportwhichwaswrittentodetailtheproceduresformodifyingtheelectricalsystemonthetankthefirstgivesacomprehensivelistofthecablingswitchgearandcontrolsystemsthatneededtobehardenedforthegroundbasedvoltageitlistseverycriticalcomponentexceptthethermostaticvalvesthisdocumentwasfiledintheservicerecordsoweknowitwastheofficialrecordbutthechiefsystemsengineerwhosigneditoffsaysthesignatureonitisabadcopyofhisownwefoundidenticalcopiesinseveralmissionfilesbothinthemanufacturersrecordsandatkennedywheresomeofthetestswerecarriedoutsoitisclearthatthiswastheofficialversionusedintheupgradethesecondversionappearedtobethesamedocumentbutitincludedthethermostaticvalvesonthelistofcomponentstobechangedandthetemperaturegaugelimitswerecircledseveraltimeswithanexclamationmarknexttotheeightydegreeceilingitlookslikeoursaboteurdeliberatelyarrangedforthetanktobemisconfiguredinanefforttocausetroubleforthemissionalthoughwecantbesuretheyrealisedhowdangerousthiswaswhenweputittogetherwithalltheotheraccidentsitisprettyclearthiswasanotherdeliberateattackontheprogramwefoundthesecondversionofthereportinaboxunderthefloorboardsinmikesplaceisupposeitispossiblethatmikehadstumbledacrossthedocumenthimselfandwasinvestigatingitaspartofhiscampaigntoprovethattherussianswerebehindthisstringofproblemsbutattheveryleastheisguiltyofamajormisjudgementandiftheastronautshaddiedhewouldhavebeentriedformanslaughterasitistogetherwiththeleakchargeshewillbegoingtoprisonforaverylongtimeofcoursetheevidenceisstilllargelycircumstantialwecandefinitelytiehimtotheleaktothenewspaperforensicsmatchedthetypewriterribbonandtypecharacteristicsonhistypewriterwiththeinkandimpressionsonthelettertotheeditorbutwestillcannotshowconclusivelythathedirectedorcarriedoutanyofthesabotageattemptsandwehavenotbeenabletofindanyoneelsewhohadbothmotiveandopportunitysoheisourbestsuspectiamnotsurewecanentirelyrelaxbutwithnosignificantincidentsonapolloxivtoxviandwithmikeincustodyifeelslightlylessworriedabouttheremainingapolloflightwearestilltryingtocrackthatotherenciphereddocumentwefoundinmikesplaceithasaverystrangealphabetwhichithinkmustbesignificantbuticantquiteseehowtobreakityetnowthatthenasacomputingexpertshavemoretimeiamhopingthatweshouldbeabletodecipheritandthatitwillshedsomemorelightonmikesthinkingmoreimportantlyitmighttelluswhatelseifanythinghehadplannedmeg'"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "k_a, score_b = vigenere_frequency_break(sca, fitness=Ptrigrams, max_key_length=26)\n",
+    "print(k_a, '\\n')\n",
+    "pa = vigenere_decipher(sca, k_a)\n",
+    "pa"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "harry i put together a team of women from the computing division here at kennedy and we have spent\n",
+      "most of the last eighteen months combing through mission files and computer printouts looking for\n",
+      "more clues to the source of the oxygen tank explosion onboard apollo xiii and i think we have\n",
+      "finally worked out what happened the tank containing the source of the explosion was originally\n",
+      "installed in apollo x but removed for modification during that process it got dropped so it was held\n",
+      "back for further tests and a replacement fitted for that flight once it had passed inspection the\n",
+      "tank was returned to service and earmarked for odyssey further upgrades were carried out to allow it\n",
+      "to runoff ground power during fit out at twice the spaceship voltage and the higher power was used\n",
+      "to boil off excess oxygen during ground tests unfortunately it looks like the thermostatic switches\n",
+      "in the tank were overlooked during the voltage upgrade and our best guess is that they fused closed\n",
+      "during the boil off allowing the temperature to rise to over a thousand degrees you might think the\n",
+      "test engineers would have noticed that but since the tank operating temperature was supposed to be\n",
+      "somewhere well below zero the dial only went as far as plus eighty sono one would have noticed\n",
+      "operating that far out of normal range it is a miracle the tank lasted as long as it did and that\n",
+      "adds to the impression that this was a simple accident a chain of events that could not have been\n",
+      "foreseen but the computer file stella different story we found two versions of the upgrade report\n",
+      "which was written to detail the procedures for modifying the electrical system on the tank the first\n",
+      "gives a comprehensive list of the cabling switchgear and control systems that needed to be hardened\n",
+      "for the ground based voltage it lists every critical component except the thermostatic valves this\n",
+      "document was filed in the service records owe know it was the official record but the chief systems\n",
+      "engineer who signed it off says the signature on it is a badcopy of his own we found identical\n",
+      "copies in several mission files both in the manufacturers records and at kennedy where some of the\n",
+      "tests were carried out so it is clear that this was the official version used in the upgrade the\n",
+      "second version appeared to be the same document but it included the thermostatic valves on the list\n",
+      "of components to be changed and the temperature gauge limits were circled several times with an\n",
+      "exclamation mark next to the eighty degree ceiling it looks like our saboteur deliberately arranged\n",
+      "for the tank to be misconfigured in an effort to cause trouble for the mission although we cant be\n",
+      "sure they realised how dangerous this was when we put it together with all the other accidents it is\n",
+      "pretty clear this was another deliberate attack on the program we found the second version of the\n",
+      "report in a box under the floorboards in mikes place i suppose it is possible that mike had stumbled\n",
+      "across the document himself and was investigating it as part of his campaign to prove that the\n",
+      "russians were behind this string of problems but at the very least he is guilty of a major\n",
+      "misjudgement and if the astronauts had died he would have been tried for manslaughter as it is\n",
+      "together with the leak charges he will be going to prison for a very longtime of course the evidence\n",
+      "is still largely circumstantial we can definitely tie him to the leak to the newspaper forensics\n",
+      "matched the typewriter ribbon and type characteristics on his typewriter with the ink and\n",
+      "impressions on the letter to the editor but we still can not show conclusively that he directed or\n",
+      "carried out any of the sabotage attempts and we have not be enable to find anyone else who had both\n",
+      "motive and opportunity so he is our best suspect i am not sure we can entirely relax but with no\n",
+      "significant incidents on apollo xiv to xvi and with mike in custody i feel slightly less worried\n",
+      "about the remaining apollo flight we are still trying to crack that other enciphered document we\n",
+      "found in mikes place it has a very strange alphabet which i think must be significant but icant\n",
+      "quite see how to break it yet now that the nasa computing experts have more time i am hoping that we\n",
+      "should be able to decipher it and that it will shed some more light on mikes thinking more\n",
+      "importantly it might tell us what elseif anything he had planned meg\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(pa))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "4375"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_a_filename, 'w').write(lcat(tpack(segment(pa))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.9"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/2019/2019-challenge8b.ipynb b/2019/2019-challenge8b.ipynb
new file mode 100644 (file)
index 0000000..bdb6529
--- /dev/null
@@ -0,0 +1,320 @@
+{
+ "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",
+    "from cipher.vigenere import *\n",
+    "from support.text_prettify import *\n",
+    "from support.utilities import *\n",
+    "from support.plot_frequency_histogram import *\n",
+    "import re"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "challenge_number = 8\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",
+    "rwa = wcat(cat(reversed(w)) for w in ca.split())\n",
+    "ra = cat(reversed(ca))\n",
+    "sca = sanitise(ca)\n",
+    "rsca = cat(reversed(sca))\n",
+    "pca = letters(ca)\n",
+    "pta = depunctuate(ca)\n",
+    "\n",
+    "scb = sanitise(cb)\n",
+    "pcb = letters(cb)\n",
+    "rscb = cat(reversed(scb))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:445: UserWarning: Matplotlib is currently using module://ipykernel.pylab.backend_inline, which is a non-GUI backend, so cannot show the figure.\n",
+      "  % get_backend())\n"
+     ]
+    },
+    {
+     "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": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAbAAAAEmCAYAAAADccV0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvOIA7rQAAFQlJREFUeJzt3X+0ZWV93/H3R7CgggLOzRRHzCV2TBbJiphM0EbLwiU1Ik0HktSgBtGSjCtBk1jt6pjWqFWTafOry2WqwUjELoOlQQoNVBwJWVRFYUAYGIh1GsYwOMDkB6jxRwt++8fZVw6He+45595z5s4z9/1a6657zj7Pc57v3mfv+7n7x903VYUkSa15wmoXIEnSchhgkqQmGWCSpCYZYJKkJhlgkqQmGWCSpCYZYJKkJhlgkqQmGWCSpCYZYJKkJh2+2gUArFu3rubn51e7DEnSQeDmm2/+66qaG9XuoAiw+fl5duzYsdplSJIOAkm+PE47DyFKkppkgEmSmmSASZKaZIBJkppkgEmSmmSASZKaZIBJkppkgEmSmmSASZKaZIBJkpp0UNxKSpJ0cJrfetXYbfdsO3OGlTyee2CSpCYZYJKkJhlgkqQmGWCSpCaNDLAkJyS5LsmdSXYl+ZVu+juS3Jvk1u7r5X193ppkd5IvJvmJWc6AJGltGucqxIeBN1fVLUmOBm5Osr177feq6rf7Gyc5CTgH+EHgGcCnkjynqh6ZZuGSpLVt5B5YVe2rqlu6x18D7gI2LNFlM/Cxqvp2Vd0N7AZOmUaxkiQtmOgcWJJ54HnA57tJb0iyM8lFSY7tpm0A7unrtpelA0+SpImNHWBJjgIuA361qr4KvB94NnAysA/4nUkGTrIlyY4kO/bv3z9JV0mSxguwJE+kF14fraqPA1TV/VX1SFV9B/ggjx4mvBc4oa/7M7tpj1FVF1bVpqraNDc3t5J5kCStQeNchRjgQ8BdVfW7fdOP72t2NnBH9/hK4JwkRyQ5EdgI3Di9kiVJGu8qxBcC5wK3J7m1m/ZrwCuTnAwUsAd4PUBV7UpyKXAnvSsYL/AKREnStI0MsKr6NJBFXrp6iT7vAd6zgrokSVqSd+KQJDXJAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXJAJMkNenw1S5AkjR781uvGrvtnm1nzrCS6XEPTJLUJANMktQkA0yS1CQDTJLUJANMktSkkQGW5IQk1yW5M8muJL/STT8uyfYkX+q+H9tNT5L3JtmdZGeSH5n1TEiS1p5x9sAeBt5cVScBLwAuSHISsBW4tqo2Atd2zwHOADZ2X1uA90+9aknSmjcywKpqX1Xd0j3+GnAXsAHYDFzcNbsYOKt7vBn4SPV8DjgmyfFTr1yStKZNdA4syTzwPODzwPqq2te9dB+wvnu8Abinr9vebpokSVMzdoAlOQq4DPjVqvpq/2tVVUBNMnCSLUl2JNmxf//+SbpKkjRegCV5Ir3w+mhVfbybfP/CocHu+wPd9HuBE/q6P7Ob9hhVdWFVbaqqTXNzc8utX5K0Ro1zFWKADwF3VdXv9r10JXBe9/g84Iq+6a/prkZ8AfBQ36FGSZKmYpyb+b4QOBe4Pcmt3bRfA7YBlyY5H/gy8IrutauBlwO7gW8Ar5tqxZIkMUaAVdWngQx5+SWLtC/gghXWJUnSkrwThySpSQaYJKlJBpgkqUkGmCSpSQaYJKlJBpgkqUkGmCSpSQaYJKlJBpgkqUkGmCSpSQaYJKlJBpgkqUkGmCSpSQaYJKlJBpgkqUkGmCSpSQaYJKlJBpgkqUkGmCSpSQaYJKlJBpgkqUkGmCSpSQaYJKlJBpgkqUkGmCSpSQaYJKlJBpgkqUkGmCSpSQaYJKlJBpgkqUkGmCSpSQaYJKlJBpgkqUkGmCSpSQaYJKlJBpgkqUkGmCSpSQaYJKlJBpgkqUkjAyzJRUkeSHJH37R3JLk3ya3d18v7Xntrkt1JvpjkJ2ZVuCRpbRtnD+zDwMsWmf57VXVy93U1QJKTgHOAH+z6/Ockh02rWEmSFhw+qkFVXZ9kfsz32wx8rKq+DdydZDdwCnDDsiuUJAEwv/Wqidrv2XbmjCo5OKzkHNgbkuzsDjEe203bANzT12ZvN02SpKlaboC9H3g2cDKwD/idSd8gyZYkO5Ls2L9//zLLkCStVcsKsKq6v6oeqarvAB+kd5gQ4F7ghL6mz+ymLfYeF1bVpqraNDc3t5wyJElr2LICLMnxfU/PBhauULwSOCfJEUlOBDYCN66sREmSHm/kRRxJLgFOA9Yl2Qu8HTgtyclAAXuA1wNU1a4klwJ3Ag8DF1TVI7MpXZK0lo1zFeIrF5n8oSXavwd4z0qKkqQDaZKr+/qv7DsQ/Qb76lHeiUOS1CQDTJLUJANMktQkA0yS1CQDTJLUJANMktQkA0yS1CQDTJLUJANMktQkA0yS1CQDTJLUJANMktQkA0yS1CQDTJLUJANMktQkA0yS1CQDTJLUJANMktQkA0yS1CQDTJLUJANMktQkA0yS1CQDTJLUJANMktQkA0yS1KTDV7sASZqG+a1XTdR+z7YzZ1SJDhT3wCRJTTLAJElNMsAkSU0ywCRJTTLAJElNMsAkSU3yMnpJMzHJZe39l7R7ObzG5R6YJKlJBpgkqUkGmCSpSQaYJKlJBpgkqUkGmCSpSSMDLMlFSR5IckfftOOSbE/ype77sd30JHlvkt1Jdib5kVkWL0lau8bZA/sw8LKBaVuBa6tqI3Bt9xzgDGBj97UFeP90ypQk6bFGBlhVXQ/87cDkzcDF3eOLgbP6pn+kej4HHJPk+GkVK0nSguWeA1tfVfu6x/cB67vHG4B7+trt7aY9TpItSXYk2bF///5lliFJWqtWfBFHVRVQy+h3YVVtqqpNc3NzKy1DkrTGLDfA7l84NNh9f6Cbfi9wQl+7Z3bTJEmaquUG2JXAed3j84Ar+qa/prsa8QXAQ32HGiVJmpqRd6NPcglwGrAuyV7g7cA24NIk5wNfBl7RNb8aeDmwG/gG8LoZ1CxJ0ugAq6pXDnnpJYu0LeCClRYlSdIo3olDktQkA0yS1CQDTJLUJANMktQkA0yS1CQDTJLUJANMktSkkX8HJmltm9961dht92w7c4aVSI/lHpgkqUkGmCSpSQaYJKlJBpgkqUkGmCSpSQaYJKlJBpgkqUkGmCSpSQaYJKlJBpgkqUkGmCSpSQaYJKlJBpgkqUkGmCSpSQaYJKlJBpgkqUkGmCSpSQaYJKlJBpgkqUkGmCSpSQaYJKlJBpgkqUkGmCSpSYevdgGSZm9+61UTtd+z7cwZVSJNj3tgkqQmGWCSpCYZYJKkJnkOTFoFk5yT6j8f5bks6VEGmLQCyw0iSSvnIURJUpNWtAeWZA/wNeAR4OGq2pTkOOC/AvPAHuAVVfV3KytTkqTHmsYe2Iur6uSq2tQ93wpcW1UbgWu755IkTdUsDiFuBi7uHl8MnDWDMSRJa9xKA6yATya5OcmWbtr6qtrXPb4PWL/CMSRJepyVXoX4oqq6N8n3ANuT/EX/i1VVSWqxjl3gbQF41rOetcIyJElrzYr2wKrq3u77A8DlwCnA/UmOB+i+PzCk74VVtamqNs3Nza2kDEnSGrTsAEvylCRHLzwGXgrcAVwJnNc1Ow+4YqVFSpI0aCWHENcDlydZeJ8/rqpPJLkJuDTJ+cCXgVesvExJkh5r2QFWVX8JPHeR6X8DvGQlRUkHkrdnktrknTgkSU0ywCRJTTLAJElNMsAkSU0ywCRJTfL/gemQ4dWE0triHpgkqUkGmCSpSQaYJKlJngPTQWeSc1mex5LWLgNMM2MQSZolA2yNWO4Vel7ZJ+lg5TkwSVKTDDBJUpMMMElSkwwwSVKTDDBJUpMMMElSkwwwSVKTDDBJUpMMMElSkwwwSVKTDDBJUpO8F2JjvEGuJPW4ByZJapIBJklqkgEmSWqSASZJapIBJklqkgEmSWqSl9GvEi+Hl6SVcQ9MktQkA0yS1CQDTJLUJANMktQkA0yS1CQDTJLUJANMktQkA0yS1KSZBViSlyX5YpLdSbbOahxJ0to0kwBLchjw+8AZwEnAK5OcNIuxJElr06xuJXUKsLuq/hIgyceAzcCdMxpvRSa5rRM8emun5faTJK3crAJsA3BP3/O9wPNnNNZ3eX9BSVo7UlXTf9PkZ4CXVdXPd8/PBZ5fVW/oa7MF2NI9/X7gi1Mv5FHrgL8+hPutxpjO4/T7rcaYzuP0+63GmC3N4zi+t6rmRraqqql/Af8YuKbv+VuBt85irDHr2XEo92upVufx4BrTeXQeD/Q8TvNrVlch3gRsTHJikn8AnANcOaOxJElr0EzOgVXVw0neAFwDHAZcVFW7ZjGWJGltmtk/tKyqq4GrZ/X+E7rwEO+3GmM6j9PvtxpjOo/T77caY7Y0j1Mzk4s4JEmaNW8lJUlq0iEVYEnmk9wxMO21Sd43Zv/PTmPMaVjqfac5ZpI/T7JpzLYTLZ9hdY47ZpJfTnJXko8OTN+TZN0ktSy31mn0W2p+F5ZpktOS/OkE4y76WST5cPdnLMuq9WAw5jIdtm6taB7717kkb5lWveOMd6D6Lufn3ErGm6WZnQNrUVX9+GrXcDBbheXzS8DpVbX3AI97wCx3mbquzswvAacDP38gx1vmOr6svitYdw667fGQ2gPrl+T7knwBmANO6H4L/lKSty/R5+t9j/91kpuS7EzyzhHDHZbkg0l2Jflkkicl+UdJPpXktiS3JHn2wFhv6252/OkklyR5S5If7drfBlwwyXwm+bEk/6sb65Ykj1tJFxuze+ncJLcmuSPJKWMun3+T5Pau3m2TLJtxxkzyAeD7gP+Z5M1d311J/hDIEjUutlx/ofssb0tyWZInj1vrBH37P4t/kuRj3W+rlwNPWqLP1/uePjXJVV39H0gydPtc6Jee93V9PgV8z7A+Q2p9fpLf6lvXXz+k/WLL9dlJPpHk5m7d+4Ex+y25bXQW+yzG3T4W6ztOrd9d54A3Ac9NckN6Pzd+YRnL9be79XtnkjcuNV63Pd3Q9f1sku8fMU5/37cl+aNue9yZ5KdH9F1Yd45Kcm33GdyeZPOY4/3bJBclubGrd2i/mVvtP0Sb5hcwD9xB784eXwCeC7wW2Ac8nd4PkjuATUP6f737/lJ6V9iEXsj/KXDqEmM+DJzcPb8U+Dng88DZ3bQjgSf39fkx4NZu+tHAl4C3ADsXxgF+C7hjgvl8MnBk9/pGBv7IcIkx/xz4YNfm1GFjDiyfM4DPLswTcNyEy2asMYE99P7a/73Ar3fTzgQKWLdI+2Hz+PS+Nu8G3jhBrUv2HfJZ/Ct6fzoC8MPd+45a504DvkXvh8RhwHbgZ8b4LH6qa3sY8AzgwWH9htS6Bfh33etHADuAE8dcrtcCG7s2zwf+bMx+Q7eNEZ/FyO1jib5L1rrIOvcO4DZ6PzPW0bs13jMmWK6/CPwJcPiIbWRhvKf2tT0duGyMn3cLff8D8J/6ph87ot/CunM48NTu8TpgN92FfSPG+w3g57ppxwD/G3jKqHpn8XUoHkKcA64Afqqq7kzyPGB7Vf0NQJKPAy+it6EO89Lu6wvd86PohcL1Q9rfXVW3do9vBk4ENlTV5QBV9a2B9i8EruimfyvJ/+imH1NVC2P8F3pBMe58Pg14X5KTgUeA54w5JsAlXZ3XJ3lqkmOq6sElxj4d+KOq+kbX72+XaDu4bOaXMeap9H5QU1VXJfm7Ie2GzeMPJXk3vY3tKHp/nzhureP0Hfws3kkvdKmqnUl2Dhlv0I316A2wL6G3nv7JiD6nApdU1SPAV5L82Yj2g7W+DfjhPHre7Gn01vW7+/ostlyPBH4c+G/Jd3eIjxgYa7F+T2LpbWPBYp/FuNvHYn1H1bqYK6rqm8A3k1xH7ybl/31I28Hl+uvAB6rqYRi5jUBvuV+cZCO9X9CeOEZ9C06nd7MIurGGbR+DAvxGklOB79C7h+164L4R/V4K/PM8egTnSOBZwF0T1DwVh2KAPQT8Fb2Nf+Hu94N/KzDqbwcC/GZV/cGYY3677/Ej9H7YzdrgfL4JuJ/eb39PoPfb/LgmXT6TGFw2C4fTZjnmoA8DZ1XVbUleS29vZzGL1TpO38XWueU4EMtksNbQ26scFurDPAF4sKpOnnJ9CwY/i+NX0Hc9y6t1ks9jpevAu4DrqursJPP0jlLM2qvpBe+PVtX/S7KHXhiNEuCnq2qW968dy6F4Duz/AmcDr0nyqm7aP01yXHrnX84CPjPiPa4B/mWSowCSbEgy1rmFzteAvUnO6vofkceeO/kM8JNJjuzG+Gfd9AeTvKh7/OoRYwzO59OAfVX1HeBceoeU+g0bE+BnuzpfBDxUVQ+NGHs78LqFeUpy3Ij2i5lkzOuBV3XtzwCOHdJu2DweDexL8kRGL9dB4/Qd/Cz66/0heocRx3FKerdfewK95fPpMfpcD/xsksOSHA+8eET7wVqvAX6xmz+SPCfJUwb6LLZcvwHcneRfdP2S5Llj9PsmS28bwzzIZNtHv6+OUetiNne1P53eLy43LdF2cLluB16f5PBuzFHbyNOAe7vHrx2jtn7b6TsnmGTY9rHYmA904fVi4HvH7HcN8MZ0u7PdUa5VcSgGGFX19/Q2ljfRO7Z8I3AZvWPol1XVUocPqapPAn8M3JDkdnqHcY6esIxzgV/uDh99FviHfe9/E717Q+6kd8L4dnq/wb0O+P0kt7LEhQp979M/n3uA89I7wf0DwN8PtB02JvQO73wB+ABw/hjjfqJ7rx1drWNdbjxgkjHfCZyaZBe9Q4l/NaSuYfP4NnrnXT4D/MWEdY7Vd+Cz+D/AUUnuAv49vcNY47gJeB+9QzF3A5eP0edyeueW7gQ+AtwwqsNArfd1fW9J71LwP2DgyMwSy/XVwPndOreL3v/8G6ff0G1jhIm2jwFL1jrETuA64HPAu6rqK0s1HliuX6G3nu7sxnzVUn2B/wj8ZrdNTHpk7N3AseldMHIbo3+JWfBRYFP3M+41jL9tvIveIc6d3Tb5rgnrnRrvxLFKkhxVVV/vfvu8HthSVbccamMeaGthHlfDcpern4dm6VA8B9aKC5OcRO+Y88UHaKNejTEPtLUwj6thucvVz0Mz4x6YJKlJh+Q5MEnSoc8AkyQ1yQCTJDXJAJMkNckAkyQ1yQCTJDXp/wMuzXS3xlEXKwAAAABJRU5ErkJggg==\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fc = collections.Counter(chunks(scb, 2))\n",
+    "plot_frequency_histogram(fc, sort_key=fc.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'fe': 'e',\n",
+       " 'ia': 't',\n",
+       " 'fc': 'o',\n",
+       " 'fb': 'a',\n",
+       " 'kc': 'i',\n",
+       " 'fa': 'n',\n",
+       " 'he': 'h',\n",
+       " 'gc': 's',\n",
+       " 'hd': 'r',\n",
+       " 'ge': 'd',\n",
+       " 'ke': 'l',\n",
+       " 'ib': 'u',\n",
+       " 'id': 'm',\n",
+       " 'kd': 'w',\n",
+       " 'ha': 'y',\n",
+       " 'ga': 'c',\n",
+       " 'fd': 'f',\n",
+       " 'hb': 'g',\n",
+       " 'gb': 'p',\n",
+       " 'ic': 'b',\n",
+       " 'ka': 'v',\n",
+       " 'gd': 'k',\n",
+       " 'ie': 'x',\n",
+       " 'hc': 'j',\n",
+       " 'kb': 'q'}"
+      ]
+     },
+     "execution_count": 26,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "p_common = [p[0] for p in collections.Counter(chunks(scb, 2)).most_common()]\n",
+    "e_common = [p[0] for p in english_counts.most_common()]\n",
+    "bsubs = {p: c for p, c in zip(p_common, e_common)}\n",
+    "bsubs"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'actseleitsocourhonankoreitiupstyeinvtsanpatahtsitoureccorthtowontiantsehobaethfvgroxvmirhahlooyelihyvdoitsanpoctsehobaeteygaremihhtokelfvsahleitstseuhhrceelhontseinpertsitmehtarugmatseiwsmirmecapstanathguggethtitehmesibetraeltowontianatfutanomreidahetsitmewinondvleceitattsemivmecoupstcihwahyfvtikanponathyapstanogenmirourgodatawainhsibehsrunkcroytsewoncdawtinltsevneelireihontowoncronttseebadebentsetsreitocnuwdeiryahhadehfihelanwufilalnotpabetseytseyettdetocapstanhteiltsevsibewonbanweltseyhedbehtsittseyillowtraneocyutuiddvihhurellehtruwtaonmaddgrotewtuhinltsitgeiwewinfeyiantianelunlertsehsedteroctsenuwdeiruyfredditsevlonotheeytoheetsittsedonpermewomerantsahhsilomtseyoretsetmohalehmaddanbehtantseheimcudmeigonhfecoredonpatmaddfeaygohhafdetocapstitiddmatsouttsetsreitoctotidinnasaditaoninlmsentsitlivwoyehmemaddiddfeenhdibelfvmsoeberahyorerutsdehhdoheinlmemaddfetsehdibehtsegraweocmannanpyapstfemorheitcarhtasogeltsittsehgiweriwemoudlsedguhturnanptseyahhadehcroymeigonhocmirtowirraerhocgeiweinlkennelvheeyeltosibetsitanyanlmsensehetsahgropriytodinlontseyoonfvmannanptsehgiweriwetseilyanahtritaonsogeltoehtifdahstsehugreyiwvoctsewigatidahthvhteyoberwoyyunahywomanpoureneyaehinlhettanpourseirthinlyanlhontsewonjuehtocinemcrontaerfutfreqsnebheeyhunleterrelinlebenfecoretsediunwsocigoddoxatseiyerawingufdawahfepannanptopetforeltsetsreitocnuwdeirmirahrahanpinltsegeiwegrotehthmsawsireantenleltogrebentatireenwouripanpoureneyaehtofedaebetsittsevwinmanmirahuniboalifdetohurbabeatmeyuhtcapstatnomonouromnteryhfecoretsenuwdeirirhenidhpromtoogomercudacourdeilerhmaddnotiwtoctsearomnbodataontsenamaddgroboketserejuarelwoncrontitaonamaddwonbanwetseytsittseruhhainhsibehifotipeltsedunirgropriyinlkaddeloritteygteltokaddourihtroniuthtseruhhainhmaddneberfeifdetogrobetsittsevireannowentinlourgodatawainhinlpeneridhmaddfecorweltohtrakefiwktseruhhainhmaddehwiditeanorlertonotdookmeikinlonwetsevsibewoyyatteltseyhedbehtseremaddfenoturnanpfiwktseuniboalifdemirmaddsibetofecoupsttoathwonwduhaon'"
+      ]
+     },
+     "execution_count": 28,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "comcb = cat(bsubs[p] for p in chunks(scb, 2))\n",
+    "comcb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('ifwlecpsazkdynogjrhtubmxvq', -6624.359993210847)"
+      ]
+     },
+     "execution_count": 29,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kb, scoreb = simulated_annealing_break(comcb, fitness=Ptrigrams)\n",
+    "kb, scoreb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'ifthedeathofoursoninkoreataughtmeanythingitisthatoureffortstocontainthesovietsbyproxywarsisdoomedasmyloathingofthesovietempirewasstokedbyhisdeaththeussrfeedsontheangerthatwestirupwitheachwarwefightinitspuppetstateswehavetriedtocontainitbutinowrealisethatwecanonlydefeatitthewaywefoughtfascismbytakingonitsmightinopenwarourpoliticianshaveshrunkfromtheconflictandtheyneedareasontoconfronttheevileventhethreatofnuclearmissilesbasedincubadidnotgivethemthemettletofightinsteadtheyhaveconvincedthemselvesthatthemaddoctrineofmutuallyassureddestructionwillprotectusandthatpeacecanbemaintainedundertheshelterofthenuclearumbrellatheydonotseemtoseethatthelongerwecowerinthisshadowthemorethetwosideswillinvestintheseawfulweaponsbeforelongitwillbeimpossibletofightatallwithoutthethreatoftotalannihilationandwhenthatdaycomeswewillallbeenslavedbywhoeverismoreruthlessloseandwewillbetheslavesthepriceofwinningmightbeworseatfirstihopedthatthespaceracewouldhelpusturningthemissilesfromweaponsofwartocarriersofpeaceandkennedyseemedtohavethatinmindwhenhesethisprogramtolandonthemoonbywinningthespaceracetheadministrationhopedtoestablishthesupremacyofthecapitalistsystemovercommunismcowingourenemiesandsettingourheartsandmindsontheconquestofanewfrontierbutbrezhnevseemsundeterredandevenbeforethelaunchofapolloxitheamericanpublicisbeginningtogetboredthethreatofnuclearwarisrisingandthepeaceprotestswhichareintendedtopreventitareencouragingourenemiestobelievethattheycanwinwarisunavoidabletosurviveitwemustfightitnowonourowntermsbeforethenucleararsenalsgrowtoopowerfulifourleaderswillnotactoftheirownvolitiontheniwillprovoketherequiredconfrontationiwillconvincethemthattherussianshavesabotagedthelunarprogramandkilledorattemptedtokillourastronautstherussianswillneverbeabletoprovethattheyareinnocentandourpoliticiansandgeneralswillbeforcedtostrikebacktherussianswillescalateinordertonotlookweakandoncetheyhavecommittedthemselvestherewillbenoturningbacktheunavoidablewarwillhavetobefoughttoitsconclusion'"
+      ]
+     },
+     "execution_count": 32,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pb = keyword_decipher(comcb, kb, KeywordWrapAlphabet.from_last)\n",
+    "pb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "if the death of our son in korea taught me anything it is that our efforts to contain the soviets by\n",
+      "proxy wars is doomed as my loathing of the soviet empire was stoked by his death the ussr feeds on\n",
+      "the anger that we stir up with each war we fight in its puppet states we have tried to contain it\n",
+      "but i now realise that we can only defeat it the way we fought fascism by taking on its might in\n",
+      "open war our politicians have shrunk from the conflict and they need a reason to confront the evil\n",
+      "even the threat of nuclear missiles based in cuba did not give them the mettle to fight instead they\n",
+      "have convinced themselves that the mad doctrine of mutually assured destruction will protect us and\n",
+      "that peace can be maintained under the shelter of the nuclear umbrella they do not seem to see that\n",
+      "the longer we cower in this shadow the more the two sides will invest in these awful weapons before\n",
+      "long it will be impossible to fight at all without the threat of total annihilation and when that\n",
+      "day comes we will all be enslaved by whoever is more ruthless lose and we will be the slaves the\n",
+      "price of winning might be worse at first i hoped that the space race would help us turning the\n",
+      "missiles from weapons of war to carriers of peace and kennedy seemed to have that in mind when he\n",
+      "set his program to landon the moon by winning the space race the administration hoped to establish\n",
+      "the supremacy of the capitalist system over communism cowing our enemies and setting our hearts and\n",
+      "minds on the conquest of a new frontier but brezhnev seems undeterred and even before the launch of\n",
+      "apollo xi the american public is beginning to get bored the threat of nuclear war is rising and the\n",
+      "peace protests which are intended to prevent it are encouraging our enemies to believe that they can\n",
+      "win war is unavoidable to survive it we must fight it now on our own terms before the nuclear\n",
+      "arsenals grow too powerful if our leaders will not act of their own volition then i will provoke the\n",
+      "required confrontation i will convince them that the russians have sabotaged the lunar program and\n",
+      "killed or attempted to kill our astronauts the russians will never be able to prove that they are\n",
+      "innocent and our politicians and generals will be forced to strike back the russians will escalate\n",
+      "in order to not look weak and once they have committed themselves there will be no turning back the\n",
+      "unavoidable war will have to be fought to its conclusion\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(pb))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2430"
+      ]
+     },
+     "execution_count": 34,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_b_filename, 'w').write(lcat(tpack(segment(pb))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.9"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/2019/2019-challenge9.ipynb b/2019/2019-challenge9.ipynb
new file mode 100644 (file)
index 0000000..9f21621
--- /dev/null
@@ -0,0 +1,267 @@
+{
+ "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",
+    "from cipher.vigenere import *\n",
+    "from support.text_prettify import *\n",
+    "from support.utilities import *\n",
+    "from support.plot_frequency_histogram import *\n",
+    "import re"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "challenge_number = 9\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",
+    "rwa = wcat(cat(reversed(w)) for w in ca.split())\n",
+    "ra = cat(reversed(ca))\n",
+    "sca = sanitise(ca)\n",
+    "rsca = cat(reversed(sca))\n",
+    "pca = letters(ca)\n",
+    "pta = depunctuate(ca)\n",
+    "\n",
+    "scb = sanitise(cb)\n",
+    "pcb = letters(cb)\n",
+    "rscb = cat(reversed(scb))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:445: UserWarning: Matplotlib is currently using module://ipykernel.pylab.backend_inline, which is a non-GUI backend, so cannot show the figure.\n",
+      "  % get_backend())\n"
+     ]
+    },
+    {
+     "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": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "etsllamsenopaeltnaigenop \n",
+      "\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "'rehpicsihtkaerbewtahtlaicurcsitiskeewweftxenehtniffotfilrofdeludehcsnotyalsdnadnarbdroffatshtiwniagarawfoknirbehtnosevlesruodnifthgimewftsaehtfowercehtotsneppahgnihtynafiysaemorfrafllitssiecaepehttubogasraeyeerhtaissurnorawgniralcedotniaciremaekovorpotdeliafehshtiwderepmatevahyamefiwsekimtahtmetsyslacitircrehtoemossierehtfiwonktnodewtituohtiwkcarctnacielifenosierehttubrewoplacirtcelednatroppusefillortnocecnadiughtiwsmelborpdexifdnadnuofdnamehtfoenotublladekcarcevahewrafosscissalckeergrehtodnasurodolloparemohmorfemactahtsyekgnisudelbmarcsllaerewselifehtiiixollopahtiwdetaicossaselifderepmatehtfoemdednimertahtsdrocerecivresdetidefoliartadnuofiytirucesriehttiduaotnikcabemdellacyehtossthgilfranulehthtiwdahewsmelborpehttuobamehtdednimerenoemosasantamaetzuyosollopaehtmorfllacakootinodnolmorftroperehtdevieceriretfanooskuehttfelehstahtretfanoosdnadekoversawecnaraelcytirucesrehsrengiapmacecaephtiwgniteemdetratsdnaaeroknideidnosrehretfatfelehsotsefinamehtniseirrowehthtiwyltcefrepstifhcihwerwaytirohtuasnopaewcimotakuehthtiwgnikrowedartrehdenraelehsyltnacifingissthgilfollopareilraeehtnowasewegatobasfotrosehttuogniyrracfoelbapacetiuqsawohwreenignenasawehsemdlotyehtdnakuehtniecivresytirucesehtotekopsitnewehserehwswonkenoondnarehneestonevahyehtyasedisetatssevitalerrehtubogasraeynevelesawtahtylimaflanigirorehraenebotsetatsehtotkcabgnivomsawehsmehtdlotehsyrevocerwolsaekildemeestahwretfaswalnirehhtiwevilottnewehssuehtotkcabdevomekimnehwdnadeidnosrehretfanwodkaerbadahehsyassdneirfrehemmargorpfognillepshsilgneehtsesuotsefinamehtdnahsilgneoslasiefiwsekimefiwsekimtuobaseiriuqneedamdnalopretnihtiwhcuotnitogiosedirprehrofegnevernisdogehtybdellikerewsnosesohwneeuqehtsasuomafsawehsdailiehtniebointuobaetorwremohreraelcelttilategotnagebsgnihteboinrehpicotsefinamehtrofdrowyekehthtiwrehtegottahtgnittupdeirramsawekimtahtemdednimerevahdluowtipotehttanosruoesarhpehtdecitonevahdluohsiseulcrofylluferaceromniagatidaerimihybnettirwsawotsefinamehtknihttnodiosenofoesopsidotemitekimevigtndidewdnaedihotyklubdnagibootsiretirwepytarehtiesenihcamasanehtfoynahctamtnodotsefinamehtnoecafepytdnakniehtesacynanidnamihrofepytotyratercesadaheherehtkrowtaneveretirwepytrehtonanomihybnettirwgnihtynadniftndluoctubselifehthguorhtdekooliretirwepytsekimnodecudorptonsawotsefinamehtevisulcnocerastluserehtstsetehtnurotmehttogdnayelgnalotrevotitnesiekatsimehtdesilaerisanoossatikcehcotenoemosksaottogrofitahttnetnocstignisylanadnarehpicehtgnikcarchtiwpunekatossawisseugitnemucodehtnoscisneroftuodeirracrevenewtubtidessimewwohwonktnodikoolrehtonakootdnaotsefinamehttuogudierehttoginehwossretrauqdaehotkcabyawehtnotituobayrrowotdeunitnocitubweivretniehtfotuoeromgnihtynategtndidignihtemosgnidihsawehgnileefehttogidnacipotehtffoemreetsotdrahgniyrtyletinifedsawehtubtituobawenkewwenkehostruocnituodaerneebdahtiotsefinamehttuobamihdeksadnaredrahdesserpisserpehtotrettelehttnesehstimdaehhguohtstnediccaehtdellacehtahwhtiwodotgnihtondahehsmialcllitseherehtsawiyhwtuoerugifotgnolmihekattndidtidnatuobaklatottolaevahtndidewtubsrotisivynamstegehknihttnodiemeesotdesaelpdemeesehasantagnikrowllitssawehnehwkcabnoitomnignihtemostesevahtndluocehtahttnedifnocyletelpmoctonsawiiivxollopanomelborpnoitazirusserpknatehtretfasurofsesirprusrevotfelynaevahtndideherusekamdnaekimhtiwnikcehcotaedidoogaebdluowtithguohtipugnimocnoissimzuyosollopaehtfohcnualehthtiwyrrah'"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "k_a, score_b = vigenere_frequency_break(sca, fitness=Ptrigrams, max_key_length=26)\n",
+    "print(k_a, '\\n')\n",
+    "pa = vigenere_decipher(sca, k_a)\n",
+    "pa"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "onesmallsteponegiantleap \n",
+      "\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "'harrywiththelaunchoftheapollosoyuzmissioncomingupithoughtitwouldbeagoodideatocheckinwithmikeandmakesurehedidnthaveanyleftoversurprisesforusafterthetankpressurizationproblemonapolloxviiiwasnotcompletelyconfidentthathecouldnthavesetsomethinginmotionbackwhenhewasstillworkingatnasaheseemedpleasedtoseemeidontthinkhegetsmanyvisitorsbutwedidnthavealottotalkaboutanditdidnttakehimlongtofigureoutwhyiwastherehestillclaimshehadnothingtodowithwhathecalledtheaccidentsthoughheadmitshesentthelettertothepressipressedharderandaskedhimaboutthemanifestoithadbeenreadoutincourtsoheknewweknewaboutitbuthewasdefinitelytryinghardtosteermeoffthetopicandigotthefeelinghewashidingsomethingididntgetanythingmoreoutoftheinterviewbuticontinuedtoworryaboutitonthewaybacktoheadquarterssowhenigotthereidugoutthemanifestoandtookanotherlookidontknowhowwemisseditbutwenevercarriedoutforensicsonthedocumentiguessiwassotakenupwithcrackingthecipherandanalysingitscontentthatiforgottoasksomeonetocheckitassoonasirealisedthemistakeisentitovertolangleyandgotthemtoruntheteststheresultsareconclusivethemanifestowasnotproducedonmikestypewriterilookedthroughthefilesbutcouldntfindanythingwrittenbyhimonanothertypewriterevenatworktherehehadasecretarytotypeforhimandinanycasetheinkandtypefaceonthemanifestodontmatchanyofthenasamachineseitheratypewriteristoobigandbulkytohideandwedidntgivemiketimetodisposeofonesoidontthinkthemanifestowaswrittenbyhimireaditagainmorecarefullyforcluesishouldhavenoticedthephraseoursonatthetopitwouldhaveremindedmethatmikewasmarriedputtingthattogetherwiththekeywordforthemanifestocipherniobethingsbegantogetalittleclearerhomerwroteaboutniobeintheiliadshewasfamousasthequeenwhosesonswerekilledbythegodsinrevengeforherpridesoigotintouchwithinterpolandmadeenquiriesaboutmikeswifemikeswifeisalsoenglishandthemanifestousestheenglishspellingofprogrammeherfriendssayshehadabreakdownafterhersondiedandwhenmikemovedbacktotheusshewenttolivewithherinlawsafterwhatseemedlikeaslowrecoveryshetoldthemshewasmovingbacktothestatestobenearheroriginalfamilythatwaselevenyearsagobutherrelativesstatesidesaytheyhavenotseenherandnooneknowswhereshewentispoketothesecurityserviceintheukandtheytoldmeshewasanengineerwhowasquitecapableofcarryingoutthesortofsabotagewesawontheearlierapolloflightssignificantlyshelearnedhertradeworkingwiththeukatomicweaponsauthorityawrewhichfitsperfectlywiththeworriesinthemanifestosheleftafterhersondiedinkoreaandstartedmeetingwithpeacecampaignershersecurityclearancewasrevokedandsoonafterthatshelefttheuksoonafterireceivedthereportfromlondonitookacallfromtheapollosoyuzteamatnasasomeoneremindedthemabouttheproblemswehadwiththelunarflightssotheycalledmebackintoaudittheirsecurityifoundatrailofeditedservicerecordsthatremindedmeofthetamperedfilesassociatedwithapolloxiiithefileswereallscrambledusingkeysthatcamefromhomerapollodorusandothergreekclassicssofarwehavecrackedallbutoneofthemandfoundandfixedproblemswithguidancecontrollifesupportandelectricalpowerbutthereisonefileicantcrackwithoutitwedontknowifthereissomeothercriticalsystemthatmikeswifemayhavetamperedwithshefailedtoprovokeamericaintodeclaringwaronrussiathreeyearsagobutthepeaceisstillfarfromeasyifanythinghappenstothecrewoftheastfwemightfindourselvesonthebrinkofwaragainwithstaffordbrandandslaytonscheduledforliftoffinthenextfewweeksitiscrucialthatwebreakthiscipher'"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "k_a, score_b = vigenere_frequency_break(rsca, fitness=Ptrigrams, max_key_length=26)\n",
+    "print(k_a, '\\n')\n",
+    "pa = vigenere_decipher(rsca, k_a)\n",
+    "pa"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "harry with the launch of the apollo soyuz mission coming up i thought it would be a good idea to\n",
+      "check in with mike and make sure he didnt have any leftover surprises for us after the tank\n",
+      "pressurization problem on apollo xviii was not completely confident that he couldnt have set\n",
+      "something in motion back when he was still working at nasa he seemed pleased to see me i dont think\n",
+      "he gets many visitors but we didnt have alot to talkabout and it didnt take him long to figure out\n",
+      "why i was there he still claims he had nothing to do with what he called the accidents though he\n",
+      "admit she sent the letter to the press i pressed harder and asked him about the manifesto it had\n",
+      "been readout in court so he knew we knew about it but he was definitely trying hard to steer me off\n",
+      "the topic and i got the feeling he was hiding something i didnt get anything more out of the\n",
+      "interview but i continued to worry about it on the wayback to headquarters so when i got there i\n",
+      "dugout the manifesto and took another look i dont know how we missed it but we never carried out\n",
+      "forensics on the document i guess i was so taken up with cracking the cipher and analysing its\n",
+      "content that i forgot to ask someone to check it as soon as i realised the mistake i sent it over to\n",
+      "langley and got them to run the tests the results are conclusive the manifesto was not produced on\n",
+      "mikes typewriter i looked through the files but couldnt find anything written by him on another\n",
+      "typewriter even at work there he had a secretary to type for him and in any case the ink and\n",
+      "typeface on the manifesto dont match any of the nasa machines either a typewriter is too big and\n",
+      "bulky to hide and we didnt give mike time to dispose of one so i dont think the manifesto was\n",
+      "written by him i read it again more carefully for clues i should have noticed the phrase our son at\n",
+      "the top it would have reminded me that mike was married putting that together with the keyword for\n",
+      "the manifesto cipher niobe things began to get a little clearer homer wrote about niobe in the iliad\n",
+      "she was famous as the queen whose sons were killed by the gods in revenge for her pride so i got in\n",
+      "touch with interpol and made enquiries about mikes wife mikes wife is also english and the manifesto\n",
+      "uses the english spelling of programme her friends says he had a breakdown after her son died and\n",
+      "when mike moved back to the us she went to live with her in laws after what seemed like as low\n",
+      "recovery she told them she was moving back to the states to be near her original family that was\n",
+      "eleven years ago but her relatives stateside say they have not seen her and no one knows where she\n",
+      "went i spoke to the security service in the uk and they told me she was an engineer who was quite\n",
+      "capable of carrying out the sort of sabotage we saw on the earlier apollo flights significantly she\n",
+      "learned her trade working with the uk atomic weapons authority aw re which fits perfectly with the\n",
+      "worries in the manifesto she left after her son died in korea and started meeting with peace\n",
+      "campaigners her security clearance was revoked and soon after that she left the uk soon after i\n",
+      "received the report from london i took a call from the apollo soyuz team at nasa someone reminded\n",
+      "them about the problems we had with the lunar flights so they called me back into audit their\n",
+      "security i found a trail of edited service records that reminded me of the tampered files associated\n",
+      "with apollo xiii the files were all scrambled using keys that came from homer apollodorus and other\n",
+      "greek classics so far we have cracked all but one of them and found and fixed problems with guidance\n",
+      "control life support and electrical power but there is one file icant crack without it we dont know\n",
+      "if there is some other critical system that mikes wife may have tampered with she failed to provoke\n",
+      "america into declaring war on russia three years ago but the peace is still far from easy if\n",
+      "anything happens to the crew of the as tf we might find ourselves on the brink of war again with\n",
+      "stafford brand and slayton scheduled for liftoff in the next few weeks it is crucial that we break\n",
+      "this cipher\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(pa))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "4107"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_a_filename, 'w').write(lcat(tpack(segment(pa))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.9"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/2019/2019-challenge9b.ipynb b/2019/2019-challenge9b.ipynb
new file mode 100644 (file)
index 0000000..77d4004
--- /dev/null
@@ -0,0 +1,865 @@
+{
+ "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",
+    "from cipher.vigenere import *\n",
+    "from support.text_prettify import *\n",
+    "from support.utilities import *\n",
+    "from support.plot_frequency_histogram import *\n",
+    "import re\n",
+    "import itertools"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "challenge_number = 9\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",
+    "rwa = wcat(cat(reversed(w)) for w in ca.split())\n",
+    "ra = cat(reversed(ca))\n",
+    "sca = sanitise(ca)\n",
+    "rsca = cat(reversed(sca))\n",
+    "pca = letters(ca)\n",
+    "pta = depunctuate(ca)\n",
+    "\n",
+    "scb = cat(l for l in cb if l in \"012\")\n",
+    "gcb = cb.split()\n",
+    "rscb = cat(reversed(scb))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# open(plaintext_b_filename, 'w').write(lcat(tpack(segment(pa))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "18480"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(scb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Solution"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 45,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def unquad(quadlet):\n",
+    "    ds = [int(c) for c in quadlet]\n",
+    "    return ds[0] * 12 + ds[1] * 6 + ds[2] * 2 + ds[3]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 48,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['1110',\n",
+       " '1020',\n",
+       " '1110',\n",
+       " '0011',\n",
+       " '1021',\n",
+       " '0020',\n",
+       " '0011',\n",
+       " '1110',\n",
+       " '1011',\n",
+       " '0011']"
+      ]
+     },
+     "execution_count": 48,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "quads = [q for ch in chunks(scb, 28) for q in every_nth(ch, 7)]\n",
+    "quads[:10]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 57,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'uqudredupdatfvsunvdqijeqdrrfaqhdnghqghrcfsbhgwnaqgmghqugeqngpdatfvsadccnehqghgweqcfufvnemhqghfvsdrhb'"
+      ]
+     },
+     "execution_count": 57,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "qcb = cat(unpos(unquad(q)) for q in quads)\n",
+    "qcb[:100]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:445: UserWarning: Matplotlib is currently using module://ipykernel.pylab.backend_inline, which is a non-GUI backend, so cannot show the figure.\n",
+      "  % get_backend())\n"
+     ]
+    },
+    {
+     "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": 8,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "runs = [(k, len(list(v))) for k, v in itertools.groupby(scb)]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(1, 5338),\n",
+       " (2, 2442),\n",
+       " (3, 1143),\n",
+       " (4, 522),\n",
+       " (5, 253),\n",
+       " (6, 110),\n",
+       " (7, 63),\n",
+       " (8, 29),\n",
+       " (9, 11),\n",
+       " (10, 3),\n",
+       " (14, 1)]"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "collections.Counter(p[1] for p in runs).most_common()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def untri(triplet):\n",
+    "    ds = [int(c) for c in triplet]\n",
+    "    return ds[0] * 9 + ds[1] * 3 + ds[2]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def unpos_t(n):\n",
+    "    if n == 26:\n",
+    "        return '+'\n",
+    "    else:\n",
+    "        return unpos(n + 1)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "tb = cat(unpos(untri(t)) for t in chunks(scb, 3))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[]"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[c for c in tb if c == '+']"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 36,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['1110100101000012112210001101',\n",
+       " '1100101100010111100210110111',\n",
+       " '1111010110100101011210011100',\n",
+       " '0010110100000012212221001111',\n",
+       " '0100100001001102010000011101',\n",
+       " '1001001011000120021200011010',\n",
+       " '0001101011100000020021100100',\n",
+       " '0100110101101100002100001000',\n",
+       " '0110100000100022001100010110',\n",
+       " '1011000101100002100111110010']"
+      ]
+     },
+     "execution_count": 36,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "chunks(scb, 28)[:10]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 46,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[['1110', '1020', '1110', '0011', '1021', '0020', '0011'],\n",
+       " ['1110', '1011', '0011', '0000', '1101', '0021', '1111'],\n",
+       " ['1100', '1110', '1001', '1111', '0011', '1020', '0110'],\n",
+       " ['0111', '0020', '1020', '0011', '1021', '1021', '0021'],\n",
+       " ['0000', '1020', '0101', '0011', '1001', '0100', '0101'],\n",
+       " ['1020', '0100', '0101', '1021', '0010', '0021', '1100'],\n",
+       " ['0001', '0101', '0100', '1120', '1001', '0000', '1020'],\n",
+       " ['0100', '1000', '0100', '0101', '1020', '1110', '0100'],\n",
+       " ['0020', '1020', '1001', '0100', '1011', '0011', '0000'],\n",
+       " ['1101', '0021', '1111', '1100', '0000', '0011', '0010']]"
+      ]
+     },
+     "execution_count": 46,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[every_nth(ch, 7) for ch in chunks(scb, 28)][:10]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['1110010001',\n",
+       " '1110100110',\n",
+       " '1011000011',\n",
+       " '0010011001',\n",
+       " '1101101110',\n",
+       " '0011000100',\n",
+       " '0100011000',\n",
+       " '1111000101',\n",
+       " '0010011000',\n",
+       " '1000111101',\n",
+       " '0010001111',\n",
+       " '0100000000',\n",
+       " '0000100100',\n",
+       " '0110110100',\n",
+       " '1101020020',\n",
+       " '2112200022',\n",
+       " '1102000001',\n",
+       " '1011122000',\n",
+       " '2012010210',\n",
+       " '2222020111',\n",
+       " '1112002001',\n",
+       " '0001001001',\n",
+       " '0100001001',\n",
+       " '0110110011',\n",
+       " '1011110100',\n",
+       " '1111101010',\n",
+       " '0101010011',\n",
+       " '1101100000']"
+      ]
+     },
+     "execution_count": 31,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[c[:10] for c in every_nth(scb, 28)]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 37,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[15, 18, 19, 47, 75, 99, 100, 102, 103, 104]"
+      ]
+     },
+     "execution_count": 37,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[n for n, c in enumerate(scb) if c == '2'][:10]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 40,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[[15, 18, 19],\n",
+       " [19],\n",
+       " [19],\n",
+       " [15, 16, 18, 19, 20],\n",
+       " [15],\n",
+       " [14, 17, 19],\n",
+       " [17, 20],\n",
+       " [18],\n",
+       " [14, 15],\n",
+       " [15]]"
+      ]
+     },
+     "execution_count": 40,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pos2s = [[n for n, c in enumerate(ch) if c == '2'] for ch in chunks(scb, 28)]\n",
+    "pos2s[:10]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 44,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(14, 20)"
+      ]
+     },
+     "execution_count": 44,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "min(min(s) for s in pos2s if s), max(max(s) for s in pos2s if s)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 45,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def unquad(quadlet):\n",
+    "    ds = [int(c) for c in quadlet]\n",
+    "    return ds[0] * 12 + ds[1] * 6 + ds[2] * 2 + ds[3]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 48,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['1110',\n",
+       " '1020',\n",
+       " '1110',\n",
+       " '0011',\n",
+       " '1021',\n",
+       " '0020',\n",
+       " '0011',\n",
+       " '1110',\n",
+       " '1011',\n",
+       " '0011']"
+      ]
+     },
+     "execution_count": 48,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "quads = [q for ch in chunks(scb, 28) for q in every_nth(ch, 7)]\n",
+    "quads[:10]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 58,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'uqudredupdatfvsunvdqijeqdrrfaqhdnghqghrcfsbhgwnaqgmghqugeqngpdatfvsadccnehqghgweqcfufvnemhqghfvsdrhb'"
+      ]
+     },
+     "execution_count": 58,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "qcb = cat(unpos(unquad(q)) for q in quads)\n",
+    "qcb[:100]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 51,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('noapqrsbfytcuvdwxeghijklmz', -15275.52585516763)"
+      ]
+     },
+     "execution_count": 51,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kb, scoreb = simulated_annealing_break(qcb, fitness=Ptrigrams)\n",
+    "kb, scoreb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 52,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'memofromdockingmanoeuvreofficetoastestflightspacesystemsreasdockingcollartestspreliminarytestingofthedockingcollarsystemhasrevealedapotentiallyseriousflawinthedesignwhichmustbeaddressedbeforethesystemcanbecertifiedtheissueconcernstheemergencyreleasesystembackgroundthedockingsystemperformsthefollowingfunctionsimpactenergyabsorptionmechanicalconnectionspacecraftalignmentandretractionspacecrafthardmechanicalconnectionanddockinginterfacesealingspacecraftundockingandseparationinordertoachievethesefunctionsthedockingsystemconsistsofthreeprinciplepartsthebaseastructuralringandthelatchingringthedockingsystembaseisthemainstructuralmembertowhichthedockingsystemassembliesareattachedthestructuralringcarriesthebodylatcheswhichprovideahardpressuretightconnectionbetweenthetwospacecrafttogetherwiththecapturelatcheswhichoperateduringthedockingmanoeuvretheseperformthedockingfunctiontheyconsistofeightactiveandeightpassivehookswithanelectricaldriveinstalledononeofthelatchesandclosedloopcablesconnectingthemeachactivehookhasacamoperatedmechanismwhichperformsitsopeningandtighteningcorrespondinghooksofthepassivedockingsystemarecapturedbyactivehookseachpassivehookhasastackofpreloadedbellvillespringsprovidingadefiniteforceforthedockinginterfacepreloadingthedockinginterfacesealwillprovidepressureintegrityofthedockinginterfacesthisconsistsoftwoconcentricrubberringsealsoneachsystemandamanholecoverisusedtoclosethetransfertunnelofthespacecrafthatchlockingandunlockingismanuallyperformedbythecrewitissealedbyamechanismwhichhasafurthereighteccentriclatchesthesebeingconnectedwitheachotherbymeansofclosedcableconnectionthedockingsystemisequippedwithalarmandmetersystemwhichprovidetelemetrytotheshipsandtogroundcontrolinstandardoperationalmodeundockingisperformedbyreleaseoftheactivespacecraftcapturelatchesandthenbyopeningthestructurelatchhooksifnecessaryundockingcanbeperformedbythepassivespacecraftbyreleasingthebodymountedlatchesandopeningthestructurelatchpassivehooksspacecraftseparationisperformedbyspringthrusterssymmetricallylocatedonthestructuralringsofbothsystemsafterthelatchesreleasetheprincipledifferencebetweentherussianandusdockingsystemdesignscanbeseenintheguideringsystemunliketherussianelectromechanicaldockingsystemapolloisequippedwithanelectricdrivewhichusescableconnectionstotriggerthelatchesanotheressentialdifferenceistherussianemergencyreleasesystemersabackupprovidedbypyroboltsattachedtoeachpassiveandactivehookwhichoperatesinpassivemodeandprovidespracticallyinstantaneousundockingintheeventofasystemmalfunctionoraccidentonboardoneorbothofthedockedspacecraftsituationsinwhichtheersmightbeinitiatedincludeiuncontrolledfireorexplosiononboardoneofthespacecraftduringdockedoperationsiifailureofthedockingcontrolsystempreventingstandardreleaseoperationiiiattitudecontrolfailureoforunplannedfiringononeorbothspacecraftimposinghighstressesonthedockingmechanismwhiletheersprovidesaneffectivebackupforemergencysituationssimulationsandtestsonthehuntsvilledockingtestbedshowthattheeffectivenessofthepyrotechnicboltsisacriticalissuetoomuchexplosivecouldcausecriticaldamagetothepressuresealsaroundthehatchwhiletoolittlecanleavethespacecraftattachedwithadamagedmechanismtheerswasdesignedforoperationonussrmissionsandisthereforetunedtothestructuralconstraintsonthesovietplatformsincethelatchesareelectromagneticonthatspacecrafttheyarelesspronetodamageundervibrationalforcesthemotorandcablemechanismusedontheapolloplatformismorevulnerabletoshockandundercertaintestconditionshasbeenshowntofailfollowingthetriggeringoftheersonthesovietendofthedockingmechanismshockwaveswillnotofcoursepropagatethroughthevacuumofspacebuttheforcescanbetransmittedthroughthetunneltotheapollolatchesandiftheboltsfireasymmetricallythisplacesatorsionloadingonthemechanismwhichcanunseatthedrivecablesinfiveoftheseventestswherethisphenomenonwasobservedtheengineerswereabletoreseatthecablesbyrepeatedlyoperatingthemechanismbutintheremainingtwocasesthemechanismwasbeyondrepairwithoutmanualinterventionunfortunatelyinthesetwocasesthesafetyinterlockalsopreventedthehatchfrombeingopenedwhichcouldmakeitdifficultfortheastronautstocarryoutaspacewalktoexecutetherequiredrepairinthiscaseitwouldnormallybepossiblefortheastronautstomanuallyoperatethemanholelatchesbydisassemblingandsubsequentlyassemblingthehatchcoverhoweverifthelatchingmechanismshavebeensufficientlydamagedbythepyroboltsthismightproveariskyoptionanditisevenpossiblethatthecoverlatcheswouldfailtoretractmanuallywehaveaskedqueensteamtotakealookatthisandsheassuresmethattheycansortitoutshehasworkedonmostoftheapollomissiondesignteamssoiamprettyconfidentthatshecanmakesureeverythingisokforthisone'"
+      ]
+     },
+     "execution_count": 52,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pb = keyword_decipher(qcb, kb, KeywordWrapAlphabet.from_last)\n",
+    "pb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 53,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "memo from docking manoeuvre office to as test flight space systems re as docking collar tests\n",
+      "preliminary testing of the docking collar system has revealed a potentially serious flaw in the\n",
+      "design which must be addressed before the system can be certified the issue concerns the emergency\n",
+      "release system background the docking system performs the following functions impact energy\n",
+      "absorption mechanical connection spacecraft alignment and retraction spacecraft hard mechanical\n",
+      "connection and docking interface sealing spacecraft undocking and separation in order to achieve\n",
+      "these functions the docking system consists of three principle parts the base a structural ring and\n",
+      "the latching ring the docking system base is the main structural member to which the docking system\n",
+      "assemblies are attached the structural ring carries the body latches which provide a hard pressure\n",
+      "tight connection between the two spacecraft together with the capture latches which operate during\n",
+      "the docking manoeuvre these perform the docking function they consist of eight active and eight\n",
+      "passive hooks with an electrical drive installed on one of the latches and closed loop cables\n",
+      "connecting them each active hook has a cam operated mechanism which performs its opening and\n",
+      "tightening corresponding hooks of the passive docking system are captured by active hooks each\n",
+      "passive hook has a stack of preloaded bellville springs providing a definite force for the docking\n",
+      "interface preloading the docking interface seal will provide pressure integrity of the docking\n",
+      "interfaces this consists of two concentric rubber ring seals on each system and a manhole cover is\n",
+      "used to close the transfer tunnel of the spacecraft hatch locking and unlocking is manually\n",
+      "performed by the crew it is sealed by a mechanism which has a further eight eccentric latches these\n",
+      "being connected with each other by means of closed cable connection the docking system is equipped\n",
+      "with alarm and meter system which provide telemetry to the ships and to ground control in standard\n",
+      "operational mode undocking is performed by release of the active spacecraft capture latches and then\n",
+      "by opening the structure latch hooks if necessary undocking can be performed by the passive\n",
+      "spacecraft by releasing the body mounted latches and opening the structure latch passive hooks\n",
+      "spacecraft separation is performed by spring thrusters symmetrically located on the structural rings\n",
+      "of both systems after the latches release the principle difference between the russian and us\n",
+      "docking system designs can be seen in the guide ring system unlike the russian electromechanical\n",
+      "docking system apollo is equipped with an electric drive which uses cable connections to trigger the\n",
+      "latches another essential difference is the russian emergency release system ers a backup provided\n",
+      "by pyro bolts attached to each passive and active hook which operates in passive mode and provides\n",
+      "practically instantaneous undocking in the event of a system malfunction or accident onboard one or\n",
+      "both of the docked spacecraft situations in which the ers might be initiated include i uncontrolled\n",
+      "fire or explosion onboard one of the spacecraft during docked operations ii failure of the docking\n",
+      "control system preventing standard release operation iii attitude control failure of or unplanned\n",
+      "firing on one or both spacecraft imposing high stresses on the docking mechanism while the ers\n",
+      "provides an effective backup for emergency situations simulations and tests on the huntsville\n",
+      "docking testbed show that the effectiveness of the pyrotechnic bolts is a critical issue too much\n",
+      "explosive could cause critical damage to the pressure seals around the hatch while too little can\n",
+      "leave the spacecraft attached with a damaged mechanism the ers was designed for operation on ussr\n",
+      "missions and is therefore tuned to the structural constraints on the soviet platform since the\n",
+      "latches are electromagnetic on that spacecraft they are less prone to damage under vibrational\n",
+      "forces the motor and cable mechanism used on the apollo platform is more vulnerable to shock and\n",
+      "under certain test conditions has been shown to fail following the triggering of the erson the\n",
+      "soviet end of the docking mechanism shockwaves will not of course propagate through the vacuum of\n",
+      "space but the forces can be transmitted through the tunnel to the apollo latches and if the bolts\n",
+      "fire asymmetrically this places a torsion loading on the mechanism which can unseat the drive cables\n",
+      "in five of the seven tests where this phenomenon was observed the engineers were able to reseat the\n",
+      "cables by repeatedly operating the mechanism but in the remaining two cases the mechanism was beyond\n",
+      "repair without manual intervention unfortunately in these two cases the safety interlock also\n",
+      "prevented the hatch from being opened which could make it difficult for the astronauts to carryout a\n",
+      "spacewalk to execute the required repair in this case it would normally be possible for the\n",
+      "astronauts to manually operate the manhole latches by disassembling and subsequently assembling the\n",
+      "hatch cover however if the latching mechanisms have been sufficiently damaged by the pyro bolts this\n",
+      "might prove a risky option and it is even possible that the cover latches would fail to retract\n",
+      "manually we have asked queens team to take a look at this and she assures me that they can sort it\n",
+      "out she has worked on most of the apollo mission design teams so i am pretty confident that she can\n",
+      "make sure everything is ok for this one\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(pb))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 55,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "5494"
+      ]
+     },
+     "execution_count": 55,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_b_filename, 'w').write(lcat(tpack(segment(pb))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def ioc_n(text):\n",
+    "    counts = collections.Counter(text)\n",
+    "    ltrs = set(text)\n",
+    "    denom = len(text) * (len(text) - 1) / len(ltrs)\n",
+    "    return (\n",
+    "        sum(max(counts[l] * counts[l] - 1, 0) for l in ltrs)\n",
+    "        /\n",
+    "        denom\n",
+    "    )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def ioc_scan_n(text, max_key_length=20):\n",
+    "    \"\"\"Finds the index of coincidence of the text, using different chunk sizes.\"\"\"\n",
+    "    iocs = {}\n",
+    "    for i in range(1, max_key_length + 1):\n",
+    "        splits = every_nth(text, i)\n",
+    "        mean_ioc = sum(ioc_n(s) for s in splits) / i\n",
+    "        iocs[i] = mean_ioc\n",
+    "    return iocs"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1.313469334794217"
+      ]
+     },
+     "execution_count": 25,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ioc_n(scb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(28, 1.029237612412878),\n",
+       " (56, 1.0323741101856603),\n",
+       " (14, 1.0886873582571082),\n",
+       " (42, 1.0923459702787721),\n",
+       " (1, 1.313469334794217),\n",
+       " (3, 1.3136724474583705),\n",
+       " (5, 1.3139446514243536),\n",
+       " (7, 1.3141262063060093),\n",
+       " (2, 1.3142346883552642),\n",
+       " (9, 1.3145299178890573),\n",
+       " (6, 1.3146522525866469),\n",
+       " (11, 1.314872121624653),\n",
+       " (10, 1.3153476328760576),\n",
+       " (17, 1.3156082632437882),\n",
+       " (19, 1.3157537470690668),\n",
+       " (15, 1.3158533079430723),\n",
+       " (18, 1.316306072127611),\n",
+       " (4, 1.3163246528314725),\n",
+       " (23, 1.3163277281569055),\n",
+       " (21, 1.3163473471920573),\n",
+       " (25, 1.316655118103681),\n",
+       " (8, 1.317040603398334),\n",
+       " (13, 1.3171605413165643),\n",
+       " (12, 1.3174113735517243),\n",
+       " (22, 1.317528984722072),\n",
+       " (33, 1.317594905094905),\n",
+       " (31, 1.317605231763728),\n",
+       " (27, 1.317688521561938),\n",
+       " (29, 1.3179986584465913),\n",
+       " (16, 1.3180422696887168),\n",
+       " (35, 1.318663902511151),\n",
+       " (38, 1.3186715456762172),\n",
+       " (37, 1.318782979178807),\n",
+       " (30, 1.3189277795375356),\n",
+       " (20, 1.319112577563282),\n",
+       " (41, 1.319293715271584),\n",
+       " (24, 1.319320503943391),\n",
+       " (34, 1.319372128500673),\n",
+       " (26, 1.3195881414435318),\n",
+       " (45, 1.319847955451339),\n",
+       " (51, 1.3198862305977204),\n",
+       " (43, 1.3202263262432186),\n",
+       " (32, 1.3204297829974077),\n",
+       " (46, 1.32083091670564),\n",
+       " (47, 1.320835215197834),\n",
+       " (49, 1.3208992566951445),\n",
+       " (36, 1.320917879222574),\n",
+       " (39, 1.3212746271240052),\n",
+       " (57, 1.3216014658027582),\n",
+       " (55, 1.3216742585772436),\n",
+       " (50, 1.321775386202746),\n",
+       " (40, 1.3220152407245682),\n",
+       " (48, 1.322371313582251),\n",
+       " (54, 1.3229352276740334),\n",
+       " (59, 1.322950472958544),\n",
+       " (44, 1.3231503579952266),\n",
+       " (53, 1.3232741220713358),\n",
+       " (58, 1.3236374480105653),\n",
+       " (52, 1.3262568828142518),\n",
+       " (60, 1.3264573374508233)]"
+      ]
+     },
+     "execution_count": 30,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "sorted(ioc_scan_n(scb, max_key_length=60).items(), key=lambda kv: kv[1])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "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": [
+    "ic = ioc_scan_n(scb, max_key_length=60)\n",
+    "plot_frequency_histogram(ic, sort_key=ic.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "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.6.9"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/2019/2a.ciphertext b/2019/2a.ciphertext
new file mode 100644 (file)
index 0000000..9d9954b
--- /dev/null
@@ -0,0 +1 @@
+Tjf, B sppx r ippx rs sqj ubij vpd hjes pojw rey bs zrh mdhs r wpsrsbpe nbaqjw raaibjy sp sqj sjks. Rs ubwhs bs zrh qrwy sp hrv bu sqrs zrh r cdf pw r ujrsdwj rey epwtriiv B zpdiy rhhdtj cdf, cds bs hjjtjy pyy sqrs bs zrh sqj peiv ubij sqrs zrh ruujnsjy hp B rhxjy rwpdey sp hjj bu revpej qry hjje revsqbef hbtbirw. Bs sdweh pds sqrs sqbh zrh eps sqj ubwhs erobfrsbpe awpcijt sp qbs sqj awpfwrttj. Fjej wjapwsjy r trmpw bhhdj zbsq sqj fdbyrenj awpfwrttj upw Heppav pe sqj Rapiip Sje tbhhbpe zqbnq npdiy rfrbe qroj nrdhjy r trmpw awpcijt. Upw hptj wjrhpe sqj awpfwrttj npeswpiibef sqj ireybef wryrw zrhe’s dayrsjy zbsq sqj uibfqs aire rey bu Fjej qrye’s wrbhjy sqrs zbsq Bojwhpe sqje sqj cpvh tbfqs qroj qry wjri swpdcij fjssbef crnx. B ippxjy sqwpdfq sqj nptarev ubijh rey updey repsqjw pu pdw tvhsjwbpdhiv upwtrssjy wjapwsh: sqj tjtp beupwtbef sqjt rcpds sqj nqrefj, zqbnq jkairbeh zqv sqj awpfwrttj ejojw fps dayrsjy. Sqbh sbtj sqj nbaqjw zrh re ruubej hqbus, hp hibfqsiv qrwyjw sp nwrnx, cds epsqbef hjwbpdh. Hsbii, bs bh tdnq ijhh ibxjiv sqrs bs zrh r cdf sqrs sbtj, rey be rev nrhj szbnj bh spp tdnq pu r npbenbyjenj. Bs yby hsrws tj zpeyjwbef zqv sqj hjnpey nbaqjw zrh jrhbjw sp nwrnx sqre sqj ubwhs, cds sqje B wjribhjy sqrs sqj ruubej hqbus zrh spp tdnq pu r fbojrzrv. R wpsrsbpe nbaqjw wjriiv npdiy mdhs cj re jenpybef jwwpw, cds sqj ruubej hqbus bh spp hpaqbhsbnrsjy upw r tbhsrxj, hp zqpjojw trefijy sqj wjapwsh tdhs qroj wjribhjy sqjv qry tryj r cbs pu re jwwpw zbsq sqj ubwhs pej rey swbjy sp npojw sqjbw hsjah zbsq sqj hjnpey. Bs bh qrwy sp hjj sqbh rh revsqbef psqjw sqre rssjtasjy hrcpsrfj, cds B rt eps hdwj zqrs sqj tpsboj npdiy cj. B ypdcs bs bh ajwhperi. Sqj Rapiip Sje rey Jijoje nwjzh ype’s pojwira, hp jbsqjw hptjpej qrh r fwdyfj rfrbehs sqj zqpij Rhswperds npwah pw sqjv rwj swvbef sp yjwrbi sqj Rapiip awpfwrttj. Bs npdiy cj sqj Hpobjsh B hdaaphj. Rs ubwhs, B sqpdfqs sqrs sqjbw zbiibefejhh sp hqbus sqj IDER-UBUSJJE pwcbs hqpzjy sqrs sqjv zjwje’s arws pu bs, cds hptjpej be sqj Hsrsj Yjarwstjes apbesjy pds sqrs sqjv tbfqs mdhs qroj qry r fdbisv npehnbjenj, pw cjje xjje sp ybhsrenj sqjthjiojh penj sqj aips zrh ybhnpojwjy. B rt hsbii eps hdwj. Be sqj tjresbtj, npdiy vpd srxj r ippx rs sqj nptadsjw ubijh sp hjj zqp tbfqs qroj qry rnnjhh sp cpsq tjtph, rey zqp tbfqs qroj qry sqj paapwsdebsv rey tjreh sp ypnspw sqjt? B rt uivbef crnx sp Irefijv spebfqs, sp hjj bu sqj Hsrsj Yjarwstjes qroj rev byjrh zqrs tbfqs cj fpbef pe. Ejbi hrby qj npdiy uiv tj da be pej pu sqj ERHR nqrhj airejh, zqbnq bh hptjsqbef B qroj cjje xjje sp swv. B zbii nrii vpd bu B fjs revsqbef.
diff --git a/2019/2a.plaintext b/2019/2a.plaintext
new file mode 100644 (file)
index 0000000..ba8289c
--- /dev/null
@@ -0,0 +1,27 @@
+Meg, I took a look at the file you sent over and it was just a rotation cipher applied to the text.
+At first it was hard to say if that was a bug or a feature and normally I would assume bug, but it
+seemed odd that it was the only file that was affected so I asked around to see if anyone had seen
+anything similar. It turns out that this was not the first navigation problem to hit the programme.
+Gene reported a major issue with the guidance programme for Snoopy on the Apollo Ten mission which
+could again have caused a major problem. For some reason the programme controlling the landing radar
+wasn’t updated with the flight plan and if Gene hadn’t raised that with Iverson then the boys might
+have had real trouble getting back. I looked through the company files and found another of our
+mysteriously formatted reports: the memo informing them about the change, which explains why the
+programme never got updated. This time the cipher was an affine shift, so slightly harder to crack,
+but nothing serious. Still, it is much less likely that it was a bug that time, and in any case
+twice is too much of a coincidence. It did start me wondering why the second cipher was easier to
+crack than the first, but then I realised that the affine shift was too much of a giveaway. A
+rotation cipher really could just be an encoding error, but the affine shift is too sophisticated
+for a mistake, so whoever mangled the reports must have realised they had made a bit of an error
+with the first one and tried to cover their steps with the second. It is hard to see this as
+anything other than attempted sabotage, but I am not sure what the motive could be. I doubt it is
+personal. The Apollo Ten and Eleven crews don’t overlap, so either someone has a grudge against the
+whole Astronaut corps or they are trying to derail the Apollo programme. It could be the Soviets I
+suppose. At first, I thought that their willingness to shift the LUNA-FIFTEEN orbit showed that they
+weren’t part of it, but someone in the State Department pointed out that they might just have had a
+guilty conscience, or been keen to distance themselves once the plot was discovered. I am still not
+sure. In the meantime, could you take a look at the computer files to see who might have had access
+to both memos, and who might have had the opportunity and means to doctor them? I am flying back to
+Langley tonight, to see if the State Department have any ideas what might be going on. Neil said he
+could fly me up in one of the NASA chase planes, which is something I have been keen to try. I will
+call you if I get anything.
\ No newline at end of file
diff --git a/2019/2b.ciphertext b/2019/2b.ciphertext
new file mode 100644 (file)
index 0000000..e642ff8
--- /dev/null
@@ -0,0 +1,17 @@
+Kdarra Pwx
+Mdkqwqjkzp Adwjkpiaxkr Pjklwqpaje
+Zijmp Jwvimiax
+Pfim taqsuwxp qaxpkixm sdtkpwt ixzajukpiax knasp pfw drkxxwt rsxkj ajnipkr adwjkpiaxm zaj pfw uimmiax kxt fkm nwwx qaudirwt pa mkpimze zricfp qjwy/zricfp qaxpjarrwj pjkixixc kxt miusrkpiax jwgsijwuwxpm.
+
+Pfw zarrayixc uimmiax dfkmwm jwukix SXQFKXCWT zjau pfw ajicixkr drkx:
+Rksxqf, yfiqf wxtm yipf ixmwjpiax ixpa wkjpf dkjoixc ajnip (WDA).
+Wkjpf ajnip qakmp, yfiqf wxtm yipf Pjkxmrsxkj Ixlwqpiax (PRI).
+Pjkxm Rsxkj qakmp, yfiqf wxtm yipf Rsxkj Ajnip Ixmwjpiax (RAI).
+Pjkxm Wkjpf qakmp, yfiqf wxtm yipf jw-wxpje ixpa pfw uit-Dkqiziq jwqavwje kjwk.
+
+Pfw papkr uimmiax tsjkpiax yirr nw kddjabiukpwre WICFP tkem.
+
+Pfw jwdajp ixqrstwm micxiziqkxp qfkxcwm pa Rsxkj ajnipkr adwjkpiaxm, yfiqf mpkjp kp RAI kxt wxt yipf Pjkxm Wkjpf rxlwqpiax. XAPW PFWMW IUDAJPKXP PJKLWQPAJE QFKXCWM
+
+Pfw djiuw anlwqpivw az pfw RAI-PWI dfkmw yirr nw pa twuaxmpjkpw krr
+qaudaxwxpm az Uimmiax C wbqwdp pfamw yfiqf tijwqpre ixvarvw Rsxkj Uatsrw daywjwt twmqwxp kxt daywjwt kmqwxp.
diff --git a/2019/2b.plaintext b/2019/2b.plaintext
new file mode 100644 (file)
index 0000000..cbe2084
--- /dev/null
@@ -0,0 +1,17 @@
+Apollo Ten
+Spacecraft Operational Trajectory
+First Revision
+This document contains updated information about the planned lunar orbital operations for the mission and has been compiled to satisfy flight crew/flight controller training and simulation requirements.
+
+The following mission phases remain UNCHANGED from the original plan:
+Launch, which ends with insertion into earth parking orbit (EPO).
+Earth orbit coast, which ends with Translunar Injection (TLI).
+Trans Lunar coast, which ends with Lunar Orbit Insertion (LOI).
+Trans Earth coast, which ends with re-entry into the mid-Pacific recovery area.
+
+The total mission duration will be approximately EIGHT days.
+
+The report includes significant changes to Lunar orbital operations, which start at LOI and end with Trans Earth lnjection. NOTE THESE IMPORTANT TRAJECTORY CHANGES
+
+The prime objective of the LOI-TEI phase will be to demonstrate all
+components of Mission G except those which directly involve Lunar Module powered descent and powered ascent.
diff --git a/2019/3a.ciphertext b/2019/3a.ciphertext
new file mode 100644 (file)
index 0000000..ec6dfa2
--- /dev/null
@@ -0,0 +1,11 @@
+Wshhp,
+
+X msdjru je ar trhjsxd jwr beij Sfebbe Jrd hrfehj hrsbbp msid’j sd sttxurdj ie X sizru shtwxlri je irshtw jwr cxiixed fsfrhi xd tsir jwr ehxvxdsb hrfehj wsu arrd cxinxbru. Jwrp irshtwru rlrhpjwxdv sdu tekbud’j nxdu xj akj jwrd iecredr wsu s ahsxdmslr sdu twrtzru jwr Sfebbe rbrlrd nxbri. Je rlrhpedr’i hrbxrn jwrp nekdu xj jwrhr sdu jwr shtwxlxij hrtzedru jwsj iecredr vej uxijhstjru. Mxjw jwr lebkcr en cxiixed fsfrhi jwrp shr wsdubxdv jwxi xi dej s ikhfhxir, akj vxlrd jwr xcfehjsdtr en jwrir uetkcrdji xj xi s axj sbshcxdv sdu uerid’j nrrb bxzr jwr msp DSIS kiksbbp ueri jwxdvi. Sdpmsp, jwr nxdu iwekbu wslr hrsiikhru cr, sdu xj mekbu wslr xn X wsud’j beezru ie tshrnkbbp sj jwr nxbr. Rlrhpjwxdv beezru nxdr rotrfj jwsj jwr mehu Xdyrtjxed xd jwr frdkbjxcsjr fshsvhsfw msi ifrbj mxjw sd X. Pek csp dej ar ikhfhxiru, akj xn pek beez sj jwr urthpfj en jwr csdvbru lrhixed xj xi cxiifrbj bdyrtjxed, mxjw sd b hrfbstxdv jwr X.
+
+X mekbud’j wslr dejxtru akj X wsu urthpfjru jwr ehxvxdsb ap wsdu sdu msi ikhfhxiru ap jwr jpfe. Xj ijktz xd cp cxdu ie mwrd X ism jwr nxbru lrhixed mxjwekj xj jwsj hsdv sbshc arbbi. Edtr mr ijshjru xdlrijxvsjxdv mr betzru kf jwr tecfkjrh nxbri ie X tsd edbp siikcr jwsj jwr nxbru lrhixed msi jhsdithxaru ap iecredr mwe dem wsi sttrii je jwr fhxdjru lrhixed akj mwe uerid’j wslr jwr tbrshsdtr je sttrii jwr ehxvxdsb. Jwr gkrijxed xi, mwp mekbu jwrp fheuktr s drm lrhixed? X tsd edbp jwxdz jwsj jwrp msdjru je wrsu enn cehr xdlrijxvsjxed ap vxlxdv ki s hrsied je jwxdz xj msi sbb s cxijszr snjrh sbb. Xn jwsj msi jwr fbsd jwrd xj wsid’j mehzru. Xj irrci tbrsh je cr jwsj iecredr hrsbbp ueri wslr iecrjwxdv je wxur.
+
+X twrtzru jwr irtkhxjp tbrshsdtr bxij sdu jwrhr mrhr jme wkduhru sdu jwxhjp-irlrd frefbr mxjw sttrii je jwr shtwxlr heec mwrhr mr shr ijehxdv jwr xdlrijxvsjxed nxbri mwe ue dej sbie wslr tkhhrdj sttrii je jweir tecfkjrh nxbri. En jweir, edr wkduhru sdu rxvwjrrd uxu wslr jrhcxdsb sttrii arnehr mr tbeiru xj uemd, ie jwr ikifrtj bxij xi iwhxdzxdv, mwxtw X ikffeir xi iecrjwxdv, akj X mekbu fhrnrh je dshhem xj uemd s axj cehr. Mxjw jwr bskdtw en Sfebbe Jmrblr tecxdv kf droj cedjw jwr ceeu xi vrjjxdv jrdir sdu X mekbu hrsbbp bxzr je cszr ikhr ekh cxitwxrn cszrh uerid’j wslr sdp cehr ikhfhxiri xd ijehr.
+
+Je cszr csjjrhi mehir X wrshu jwsj jwr wsmzi sj jwr Frdjsved shr vrjjxdv hrijbrii. Tekbu pek vrj elrh jwrhr sdu nxdu ekj mwsj jwrp shr jwxdzxdv? Vxlrd jwsj ekh jehcrdjeh irrci je wslr fhrjjp wxvw-brlrb sttrii, cspar pek tekbu thsdz kf jwr irtkhxjp ed ekh tecci? Cspar s zrpmehu txfwrh abetzru si ijsdushu?
+
+Crv
diff --git a/2019/3a.plaintext b/2019/3a.plaintext
new file mode 100644 (file)
index 0000000..2cd2796
--- /dev/null
@@ -0,0 +1,11 @@
+Harry,
+
+I wanted to be certain the lost Apollo Ten report really wasn’t an accident so I asked archives to search the mission papers in case the original report had been misfiled. They searched everything and couldn’t find it but then someone had a brainwave and checked the Apollo eleven files. To everyone’s relief they found it there and the archivist reckoned that someone got distracted. With the volume of mission papers they are handling this is not a surprise, but given the importance of these documents it is a bit alarming and doesn’t feel like the way NASA usually does things. Anyway, the find should have reassured me, and it would have if I hadn’t looked so carefully at the file. Everything looked fine except that the word Injection in the penultimate paragraph was spelt with an I. You may not be surprised, but if you look at the decrypt of the mangled version it is misspelt lnjection, with an l replacing the I.
+
+I wouldn’t have noticed but I had decrypted the original by hand and was surprised by the typo. It stuck in my mind so when I saw the filed version without it that rang alarm bells. Once we started investigating we locked up the computer files so I can only assume that the filed version was transcribed by someone who now has access to the printed version but who doesn’t have the clearance to access the original. The question is, why would they produce a new version? I can only think that they wanted to head off more investigation by giving us a reason to think it was all a mistake after all. If that was the plan then it hasn’t worked. It seems clear to me that someone really does have something to hide.
+
+I checked the security clearance list and there were two hundred and thirty-seven people with access to the archive room where we are storing the investigation files who do not also have current access to those computer files. Of those, one hundred and eighteen did have terminal access before we closed it down, so the suspect list is shrinking, which I suppose is something, but I would prefer to narrow it down a bit more. With the launch of Apollo Twelve coming up next month the mood is getting tense and I would really like to make sure our mischief maker doesn’t have any more surprises in store.
+
+To make matters worse I heard that the hawks at the Pentagon are getting restless. Could you get over there and find out what they are thinking? Given that our tormentor seems to have pretty high-level access, maybe you could crank up the security on our comms? Maybe a keyword cipher blocked as standard?
+
+Meg
diff --git a/2019/3b.ciphertext b/2019/3b.ciphertext
new file mode 100644 (file)
index 0000000..a24ea19
--- /dev/null
@@ -0,0 +1 @@
+WKMPC ZKXDV SYEZU KYLTV ICYFK BVDDN KZKXD VMYXO BPKLP XMDNK CDVLL VXTDB IPXMD YMVEM KDNKW YYTDN KBKIY EVBKB PMNDD NKNVG RCVBK MKDDP XMZBK DDIBK CDUKC CVXTN VFKWY BKYBU KCCTK SPTKT VUBKV TIDNV DDNKC YFPKD CVBKD YOUVW KLYBB KSKXD KFKXD CYXDN KVZYU UYZBY MBVWW KCYWK YLDNK MKXKB VUCTY XDXKK TWESN YLVXK HSECK DYDEB XEZDN KNKVD OEDIY ETYXD MKDLY EBCDV BCGPD NYEDE XTKBC DVXTP XMDNK XKKTL YBZYU PDPSV UCEZZ YBDVX TDNKB KNVCO KKXVS YXSKB DKTGN PCZKB PXMSV WZVPM XDYSY XFPXS KDNKZ BKCPT KXDDY DVRKV CDBYX MUPXK DNKWY CDCDB PTKXD VBKSV UUPXM LYBVU VBMKO EPUTE ZYLLY BSKCV UYXMD NKOYB TKBGP DNKVC DMKBW VXIVC VCNYG YLCDB KXMDN VBMEP XMDNV DDNKV DDVSR YXDNK CZVSK ZBYMB VWWKW ECDNV FKOKK XVEDN YBPCK TOIDN KZYUP DOEBY DNVDW VRKCX YCKXC KDYWK LPBCD DNKBE CCPVX CVBKW YBKUP RKUID YDBID YGPXD NKZBY ZVMVX TVGVB DNVXD YBPCR SYXLU PSDVX TCKSY XTDNK CVOYD VMKPL DNVDP CGNVD PDPCP CXDCY ZNPCD PSVDK TKXYE MNLYB VRMOY ZKBVD PYXOE DPDPC NVBTD YSYXF PXSKD NKMKX KBVUC DNVDD NVDPC DBEKC YWKYL DNKWY BKSVE DPYEC ZUVXX KBCWY CDUID NYCKG NYVSD EVUUI LYEMN DPXDN KUVCD GVBNV FKWVX VMKTD YOUYS RDNKO EPUTE ZZBYZ YCPXM VXKGD BVXSN KYLGV BMVWK CPXCD KVTWY OPUPC PXMDN VDGVI PCCDP UUVZB YFYSV DPYXO EDPCU KCCUP RKUID YVSSP TKXDV UUIDB PMMKB VGVBK CZKSP VUUIP LGKXY DPLIZ VFUYF CRIPX VTFVX SKVUU DNKCV WKWIY GXDPW KPXOK BUPXS YXFPX SKTWK GKNVF KDYDB KVTFK BICYL DUIDN KBKCY PNKVT KTYFK BDYUV XMUKI VXTSY XFPXS KTDNK WDYCE MMKCD VXVUD KBXVD PFKGK GPUUC DKZEZ PXCZK SDPYX CVDSN KSRZY PXDSN VBUPK DYWVR KPDNV BTKBL YBCYF PKDVM KXDCD YSBYC CVXTS BVXRE ZDNKD KELKU COKBM UPCDK XPXMY ZKBVD PYXDY CKKPL DNVDD EBXCE ZVXID NPXMB KUVDK TPVWV UCYMY PXMDY CKXTV SYEZU KYLYE BOKCD YFKBD YOVPR YXEBD YDBIV XTLPX TYEDG NVDPC MYPXM YXDNK BKDNK CYFPK DCVBK ZBKDD ICKSB KDPFK VOYED DNKPB YGXCZ VSKZB YMBVW WKVXT GPDNY EDDNK GYBUT CZBKC CGVDS NPXMG KTYXD BKVUU INVFK VSUKV BZPSD EBKYL DNKPB ZBYMB KCCYB DNKPB ZUVXC EXUKC CDNKI VBKSU YCKDY ZEDDP XMDNK PBYGX WKXYX DNKWY YXPSV XDCKK GNVDD NKINV FKDYM VPXGP DNGNV DCKKW CDYOK VLVPB UITPC YBMVX PCKTV DDKWZ DDYTK BVPUY EBCZV SKZBY MBVWW KOEDP GYEUT CDPUU UPRKD YRXYG GNVDD NKIVB KEZDY RKKZV SUYCK KIKYX DNKWP CCPYX ZUVXX PXMVX TUKDW KRXYG PLIYE NKVBV XIDNP XMGYB BIPXM PGPUU OKOVS RVOYE DVGKK ROKLY BKDNK UVEXS NNVBB I
diff --git a/2019/3b.plaintext b/2019/3b.plaintext
new file mode 100644 (file)
index 0000000..55d6944
--- /dev/null
@@ -0,0 +1,24 @@
+megis penta couple of days over at the pentagon briefing the staff and trying to gauge the mood
+there you are right the hawks are getting pretty restless and have more or less decided already that
+the soviets are to blame for recent events on the apollo programme some of the generals dont need
+much of an excuse to turn up the heat but you dont get four stars without understanding the need for
+political support and there has been a concerted whispering campaign to convince the president to
+take a strong line the most strident are calling for a large buildup of forces along the border with
+east germany as a show of strength arguing that the attack on the space programme must have been
+authorised by the politburo that makes no sense to me first the russians are more likely to try to
+win the propaganda war than to risk conflict and second the sabotage if that is what it is isnt
+sophisticated enough for a kgb operation but it is hard to convince the generals that that is true
+some of the more cautious planners mostly those who actually fought in the last war have managed to
+block the buildup proposing a new tranche of wargames instead mobilising that way is still a
+provocation but is less likely to accidentally trigger aware specially if we notify pavlovsky in
+advance all the same my own time in berlin convinced me we have to tread very softly there so i
+headed over to langley and convinced them to suggest an alternative we will step up inspections at
+checkpoint charlie to make it harder for soviet agents to cross and crank up the teufel s berg
+listening operation to see if that turns up anything related i am also going to send a couple of our
+best over to baikonur to try and find out what is going on there the soviets are pretty secretive
+about their own space programme and without the worlds press watching we dont really have a clear
+picture of their progress or their plans unless they are close to putting their own men on the moon
+icant see what they have to gain with what seems to be a fairly disorganised attempt to derail our
+space programme but i would still like to know what they are up to keep a close eye on the mission
+planning and let me know if you hear anything worrying i will be back about a week before the launch
+harry
\ No newline at end of file
diff --git a/2019/4a.ciphertext b/2019/4a.ciphertext
new file mode 100644 (file)
index 0000000..ed07bb7
--- /dev/null
@@ -0,0 +1,4 @@
+BRT,
+W VLKR URRC MDGYWCT IVGDJTV IVR ZWHI DS HJHEWNWDJH WCNWARCIH LSSRNIWCT LEDZZD RZRKRC LCA WI WH ZDCTRG IVLC PDJ BWTVI IVWCY. IVR EGR-ZLJCNV, HILTR IVGRR IVGJHIRG KLZKR EGDUZRB WH L ZWIIZR HJHEWNWDJH TWKRC LZZ IVR NVRNYH IVLI IDDY EZLNR URSDGR IVLI, UJI DC IVR DIVRG VLCA IRZRBRIGP TJLGLCIRRA IVLI WI MDJZA UR ARIRNIRA LCA IVR IRNVCWNWLCH HVDMRA IVLI WI MLH RLHP ID UPELHH. WS IVLI MLH L HLUDILTR LIIRBEI IVRC WI MLHC'I KRGP MRZZ ARHWTCRA, HD W ADC'I IVWCY WI NDJZA VLKR URRC LC RCTWCRRG IVLI HRI WI JE. DC IVR DIVRG VLCA, CD-DCR RZHR MDJZA VLKR VLA IWBR LZDCR MWIV IVR NDBEDCRCI. DC IVR DIVRG VLCA, HDBRDCR SGDB SWAD'H IRLB HRCI BR L BRHHLTR ID IRZZ BR LUDJI L KRGP CRLG BWHH IVLI HDJCAH ZWYR WI NDJZA VLKR URRC L HRGWDJH LIIRBEI ID ARHIGDP IVR NDBBLCA BDAJZR DC GR-RCIGP.
+LH LEDZZD OW LEEGDLNVRA IVR GR-RCIGP EDWCI IVRP XRIIWHDCRA IVR HRGKWNR BDAJZR ID GR-DGWRCI IVR NDBBLCA BDAJZR HD IVLI IVR VRLIHVWRZA MLH EDWCIWCT WCID IVR LIBDHEVRGR. HWCNR IVRP MRGR DC EGRIIP BJNV L ULZZWHIWN DGUWI IVR HB MDJZA VLKR HILPRA NZDHR ID IVR NB, LCA MWIVDJI L VRLIHVWRZA DS WIH DMC WI MDJZA UGRLY JE WCID ZLGTR EWRNRH IVLI EDHRA L HWTCWSWNLCI ALCTRG ID IVR NB LCA WIH NGRM. ID LKDWA IVLI IVR HB MLH HJEEDHRA ID NLGGP DJI L HRFJRCNR DS HVDGI UJGCH ID BDKR WIH IGLXRNIDGP LMLP SGDB IVR NDBBLCA BDAJZR, HYWEEWCT WI DSS IVR LIBDHEVRGR HD IVLI IVR NB NDJZA GR-RCIRG SGRR SGDB IVR ARUGWH SWRZA. JCSDGIJCLIRZP, IVLI ADRHC'I HRRB ID VLKR VLEERCRA. LZAGWC GREDGIRA IVLI IVR NB SZRM ELHI IVR HB MVWNV MLH SZPWCT LI LC LIILNY LCTZR MRZZ URPDCA DERGLIWDCLZ ELGLBRIRGH, LCA L NDBBRGNWLZ EWZDI, SGLCY UGDMC, GREDGIRA HRRWCT IVR IMD HELNRNGLSI IGLNYWCT NZDHRZP LH IVRP UJGCRA IVGDJTV IVR LIBDHEVRGR. L HWCTZR NDZZWHWDC MWIV DCR DS IVR MVWIR-VDI SGLTBRCIH NDJZA VLKR ULAZP ALBLTRA IVR GR-RCIGP NLEHJZR, LCA RKRC WS IVR LHIGDCLJIH VLA HJGKWKRA IVR NDZZWHWDC IVRC IVR DAAH LGR IVLI IVR ELGLNVJIR HPHIRB MDJZA VLKR IGWTTRGRA RLGZP DG URRC SLILZZP ALBLTRA UP IVR UZLHI. CLHL RCTWCRRGH LGR MDGYWCT SLHI ID NDGGRNI IVR EGDUZRB SDG LEDZZD OWWW LCA IVRP VLKR BWIWTLIWDCH WC EZLNR SDG OWW'H GR-RCIGP, UJI IVR KWRM DS IVR ROERGIH WH IVLI IVRP ADATRA L UJZZRI MWIV IVWH. IVR SZWTVI DSSWNRG MVD GREDGIRA WI ID BR EDWCIRA DJI IVLI WS IVR HDKWRIH MLCIRA ID HLUDILTR IVR BWHHWDC IVWH BWTVI VLKR URRC L TDDA URI: WI MLH L CLHIP LNNWARCI IVLI MLH VLGA ID SDGRHRR, LCA WI MWZZ UR KRGP AWSSWNJZI ID HVDM IVLI HDBRDCR ARZWURGLIRZP BWHNLZNJZLIRA IVR UJGC IWBRH HWCNR WI MLH IVR WCIRGLNIWDC DS IVR IVGJHIRGH LCA HILUWZWHRGH IVLI NLJHRA IVR EGDUZRB. W IVWCY VR WH DCR DS L TGDMWCT CJBURG DS CLHL RBEZDPRRH MVD VLKR URTJC ID URZWRKR IVLI IVR JHHG VLH ARRE NDKRG LTRCIH MDGYWCT ID ARHILUWZWHR IVR EGDTGLBBR. BP MDGGP WH IVLI RKRC WS VR WH MGDCT, IVR ZLNY DS IGJHI IVLI WH TGDMWCT MWIVWC IVR DGTLCWHLIWDC MWZZ ARHILUWZWHR WI DC WIH DMC. W LB GRLZZP VDEWCT VR WH BWHILYRC. IVR HJNNRHH DS LEDZZD OW HRRBH ID VLKR UDJTVI L ZDI DS WCIRGCLIWDCLZ TDDAMWZZ LCA W IVWCY WI NDJZA UR IVR HILGI DS HDBRIVWCT BDGR EDHWIWKR. IVR HDKWRI NDDERGLIWDC MWIV IVR ZLCAWCT TLKR BR VDER IVLI MR NDJZA SWCA BDGR NDBBDC TGDJCA LCA HILGI ID IVLM RLHI-MRHI GRZLIWDCH, UJI IVWH NDJZA GRLZZP IVGRLIRC IVLI.
+WC IVR BRLC-IWBR MR VLA URIIRG HIRE JE HRNJGWIP. W IVWCY MR HVDJZA JHR L HWBEZR KWTRCRGR NWEVRG MWIV ERGWDA IMD SDG DJG CROI BRHHLTR. W VLKR RCNGPEIRA IVR LIILNVRA GR-RCIGP GREDGI JHWCT L NDZJBCLG IGLCHEDHWIWDC NWEVRG
diff --git a/2019/4a.plaintext b/2019/4a.plaintext
new file mode 100644 (file)
index 0000000..e5305e8
--- /dev/null
@@ -0,0 +1,4 @@
+MEG,
+I HAVE BEEN WORKING THROUGH THE LIST OF SUSPICIOUS INCIDENTS AFFECTING APOLLO ELEVEN AND IT IS LONGER THAN YOU MIGHT THINK. THE PRE-LAUNCH, STAGE THREE THRUSTER VALVE PROBLEM IS A LITTLE SUSPICIOUS GIVEN ALL THE CHECKS THAT TOOK PLACE BEFORE THAT, BUT ON THE OTHER HAND TELEMETRY GUARANTEED THAT IT WOULD BE DETECTED AND THE TECHNICIANS SHOWED THAT IT WAS EASY TO BYPASS. IF THAT WAS A SABOTAGE ATTEMPT THEN IT WASN'T VERY WELL DESIGNED, SO I DON'T THINK IT COULD HAVE BEEN AN ENGINEER THAT SET IT UP. ON THE OTHER HAND, NO-ONE ELSE WOULD HAVE HAD TIME ALONE WITH THE COMPONENT. ON THE OTHER HAND, SOMEONE FROM FIDO'S TEAM SENT ME A MESSAGE TO TELL ME ABOUT A VERY NEAR MISS THAT SOUNDS LIKE IT COULD HAVE BEEN A SERIOUS ATTEMPT TO DESTROY THE COMMAND MODULE ON RE-ENTRY.
+AS APOLLO XI APPROACHED THE RE-ENTRY POINT THEY JETTISONED THE SERVICE MODULE TO RE-ORIENT THE COMMAND MODULE SO THAT THE HEATSHIELD WAS POINTING INTO THE ATMOSPHERE. SINCE THEY WERE ON PRETTY MUCH A BALLISTIC ORBIT THE SM WOULD HAVE STAYED CLOSE TO THE CM, AND WITHOUT A HEATSHIELD OF ITS OWN IT WOULD BREAK UP INTO LARGE PIECES THAT POSED A SIGNIFICANT DANGER TO THE CM AND ITS CREW. TO AVOID THAT THE SM WAS SUPPOSED TO CARRY OUT A SEQUENCE OF SHORT BURNS TO MOVE ITS TRAJECTORY AWAY FROM THE COMMAND MODULE, SKIPPING IT OFF THE ATMOSPHERE SO THAT THE CM COULD RE-ENTER FREE FROM THE DEBRIS FIELD. UNFORTUNATELY, THAT DOESN'T SEEM TO HAVE HAPPENED. ALDRIN REPORTED THAT THE CM FLEW PAST THE SM WHICH WAS FLYING AT AN ATTACK ANGLE WELL BEYOND OPERATIONAL PARAMETERS, AND A COMMERCIAL PILOT, FRANK BROWN, REPORTED SEEING THE TWO SPACECRAFT TRACKING CLOSELY AS THEY BURNED THROUGH THE ATMOSPHERE. A SINGLE COLLISION WITH ONE OF THE WHITE-HOT FRAGMENTS COULD HAVE BADLY DAMAGED THE RE-ENTRY CAPSULE, AND EVEN IF THE ASTRONAUTS HAD SURVIVED THE COLLISION THEN THE ODDS ARE THAT THE PARACHUTE SYSTEM WOULD HAVE TRIGGERED EARLY OR BEEN FATALLY DAMAGED BY THE BLAST. NASA ENGINEERS ARE WORKING FAST TO CORRECT THE PROBLEM FOR APOLLO XIII AND THEY HAVE MITIGATIONS IN PLACE FOR XII'S RE-ENTRY, BUT THE VIEW OF THE EXPERTS IS THAT THEY DODGED A BULLET WITH THIS. THE FLIGHT OFFICER WHO REPORTED IT TO ME POINTED OUT THAT IF THE SOVIETS WANTED TO SABOTAGE THE MISSION THIS MIGHT HAVE BEEN A GOOD BET: IT WAS A NASTY ACCIDENT THAT WAS HARD TO FORESEE, AND IT WILL BE VERY DIFFICULT TO SHOW THAT SOMEONE DELIBERATELY MISCALCULATED THE BURN TIMES SINCE IT WAS THE INTERACTION OF THE THRUSTERS AND STABILISERS THAT CAUSED THE PROBLEM. I THINK HE IS ONE OF A GROWING NUMBER OF NASA EMPLOYEES WHO HAVE BEGUN TO BELIEVE THAT THE USSR HAS DEEP COVER AGENTS WORKING TO DESTABILISE THE PROGRAMME. MY WORRY IS THAT EVEN IF HE IS WRONG, THE LACK OF TRUST THAT IS GROWING WITHIN THE ORGANISATION WILL DESTABILISE IT ON ITS OWN. I AM REALLY HOPING HE IS MISTAKEN. THE SUCCESS OF APOLLO XI SEEMS TO HAVE BOUGHT A LOT OF INTERNATIONAL GOODWILL AND I THINK IT COULD BE THE START OF SOMETHING MORE POSITIVE. THE SOVIET COOPERATION WITH THE LANDING GAVE ME HOPE THAT WE COULD FIND MORE COMMON GROUND AND START TO THAW EAST-WEST RELATIONS, BUT THIS COULD REALLY THREATEN THAT.
+IN THE MEAN-TIME WE HAD BETTER STEP UP SECURITY. I THINK WE SHOULD USE A SIMPLE VIGENERE CIPHER WITH PERIOD TWO FOR OUR NEXT MESSAGE. I HAVE ENCRYPTED THE ATTACHED RE-ENTRY REPORT USING A COLUMNAR TRANSPOSITION CIPHER
diff --git a/2019/4b.ciphertext b/2019/4b.ciphertext
new file mode 100644 (file)
index 0000000..a555f52
--- /dev/null
@@ -0,0 +1 @@
+OOHSE ERRWC OITUE IEHPI ELTIN FUTVE OGNRT WDENI IETIG COATO TIETR CLTLR SESEB HCEOT EOTDO NHNET TECNS NCVTA ITTUE EUITL AUOTR YDHTL HNURC RITIO AFCMA DVSES ATIJS TTHNB DOANT TEEEA ETHAH ILRGE IEEGY NDFTO FREOS KNAHS RLELS TDOOD AFLII IAARN HELBY EEHLH LGHSC THTBO IUNPT ELTRL TESMS IGPTD AEECR AEUDC OLONS EGOFA CVALM TBLJN BOHIO AIRNH TMPES RAFAB ARDGM OEXTE SRIGH LSEDE RPNGR TEIDE BOIOW RSOIL TASRN JRHMT FOTTG NSLHC DSHIT RTESL IHNCI WNOPR YEATL SIETE UOYAE EOTGQ FNTLS MNEFN RABLW CMUEY HIREE IDEDU TTNNT AOSSN LRNLA RBAHN HOERN HDTLO EMDLN NQFIH EECIR FAUAR MAPAO EREME EHSSG SPVRY EDETI IRTEO LYESH SIWCK HNTCO MHSFI OICEL EICOA DWLOU TCBHE ORRAT CPELR EORPH AFAOE TSNFI TRSIE TYNMI AENTH ILAOV TMHHU LICAP EIRPE LHEOT FAFDO LRSHH YHARE QEHDF PIYTH OISTS OJRMT RUNEB HUHIR LENTL OEILS TICEA YTUNN ITNNE AOTNE IGNEI SIRLM PAHHS ETDCR HNHAR THMWN FRFCS IDIEO IDIEE AVOER OELSE DDHRT TTTSE EHNNS IRIDP NOIIE PUORU EHDET TEOIG UTUYT OODIE EODCH REHHS EAOFM LEHWV SRTRH TSENA NIPTV SRISH OEDRE LTMTD TOUID EYERA TSERR LNHEG MAEEL SETSA IDTLT ETDOI HLFPR GAECE OPLHN TAOIE AEMVN PHOSP TIAPL NGSIE RTCOE HOPHL TUDLF EKDSC EGEIF ARTTL TRUTE PTENA IRCAI TEAUH EFSEA BIDAT TTMUU MIIOT VLPPG YCRTO EOCSA OVRRP AIEIA LAAQN EVFNO TRTNR IMFVA GINFR FRMMB NEUUA UTACN DATIL MURCR DCOTA LGNSA OYRNL HLMET BRDTL RIMFT NTGNT TUTEO EYOHI BWCAE DHEEE CNTEU AYIRT ONNCI ITECL TEHET PTRPU EHMHL NROEY ANSEV RDCAL STTUB EUSCT PESGO NEHMN COEIE DLSHW UCLNT AIEEI ASITI EUTSG OAFCE ESEAE ULHVH EFEHH AARON IOFAE ORSAO EIIAU NAIST LOTHU ITAOT TNUNO PNRSE NEIHO NJIPY GTPLB EHOEO EOSST NHXHT CEETR BAIIL ATYTI DTNMB EUEYF XBPSF LSEER OEIIE ASEHY EIOEI LADAO FSESE TSFRO NRNRN TEVUO OEYOI SIHMU NEAEC SUEOT LEJAE ENELE BEGDE NDOGS OEKMH RDATR TEYHN EDEHN ROVQR RWOMR OAACL OHACN HPGIM GUEBS TITCI TCRLN TIHIP EUMUS ASOEK AAIEM LTNCO DSAER NHHNL EURGO AUIRT HGVWB SEARH HOCNL IOSRT OFMHH ETETT SLTCE OTCOD LIMNE AEHTV YWBSI SSSEH HAPLS MIRHE AFASE OTIRI RTTLE AYHTU DREDT TFSIB NOITA TSSEO DHEPA XLAPF RCVSN IRAED HROOS MOYPG RMECH WSSEA HTRHC CRRFL EPNME VEENE SAWEE EUESS RDTTH RDOIS TMDIE HRNLB UVOOH XEDWE SODAR NNVOE INOWV ASTTI OLOAD LTALN HTEUN EETOT POTSD MRRLT PIETS OWCND HAANX FIRNS EHUAR TTNTR CMNHA WVICT HGCBC IAIUT DVOIT SAUKA ENCEH DUAPA EEOOF MITCR IILTS ERSLI ATCIH RDOCE GALTS CINDL AORPT DDHTT OEGES OFGIC OIIOV FGMET RISIS YIDTA RLERR GISEU ULCME ETNIT LAETU SBTIT JMTYO FNSAT EEIEA ONHST TELAO TFTNY EHWTO SASOC ITTAE AOLPL EOCHL TRICS PNHGU BTOIE ODITT IVRII OORRP EOOMQ NBRTS HUSTO RRTEI AECLT IOTAT EFNRT AEHDN RMUAT TUBDI RDTFE RSTRO EIITS HEDOT REIMT MHEOO HUEID GTHBM AUCTE IOTHE ALOAP AEIES MSLAD ENKFT POICP IHREA FCOMH LRLIE FFAYN DURSD AYDLD OAHGP ERIRN RSGAI SANFD OOEUL EGICR RNIOL IILFR ARREN IAMAE SETNG UNAIO ORTOI RSTSF UEOBH ARSRI EDANN DDCHL IST
diff --git a/2019/4b.plaintext b/2019/4b.plaintext
new file mode 100644 (file)
index 0000000..074916f
--- /dev/null
@@ -0,0 +1,29 @@
+apollo xi post flight analysis spacecraft reentry trajectory review this document contains
+information about the events during there entry phase of apollo xiith as been compiled to satisfy
+flight planning safety requirements the review covers the following mission phase trans earth coast
+which ends with reentry into the mid pacific recovery area the original flightplan called for
+separation of the cm from the sm twelve minutes before entry interface successful separation would
+then trigger a sequence of burns intended to stabilise the service module and to move it out of
+there entry corridor to avoid debris collisions with the command module during there entry phase the
+reaction control system burn sequence involved both the roll and the minus x jets the attitude burns
+were intended to setup a rollin order to stabilise remaining fuel and to prevent uncontrolled
+gyration during the boost that would have then taken the sm out of there entry corridor into a high
+altitude orbit that would decay only after the command module had landed in the event the sequence
+of burns did not achieve the required trajectory shift with reports from the astronauts onboard and
+from a commercial airline pilot that the two space vehicles reentered the atmosphere together with
+the cm passing the sm during the plasma burn phase given the proximity of the vehicles during
+reentry it is considered highly fortunate that no debris from the relatively unprotected sms truck
+the cm and simulations show that such a strike would have been likely to cause catastrophic damage
+to the cm possible defects arising from a collision include i heatshield damage even a minor crack
+in one of the heatshield panels would be likely to cause super heating which could breach the hull
+leading to further catastrophic damage to the vehicle with probable loss of life ii premature firing
+of the parachute pyrotechnics leading to full or partial loss of the descent arrest system and loss
+of life iii damage to the parachute shield might have prevented the pyrotechnics from releasing the
+parachutes leading to a catastrophic collision on landing and loss of life iv damage to one or more
+of the parachutes could have led to a high velocity impact with probable resulting injuries and
+possible loss of life the high likelihood of catastrophic failure arising from the deviation from
+flight parameters means that further analysis of the separation burn strategy is required pending
+that remediation for the apollo xii reentry trajectory is a high priority it is suggested that
+surplus fuel should be ejected from the sm before the separation burn begins in order to stabilise
+the attitude and that the minus x burns should be timed to coincide with the roll jets to improve
+stability
\ No newline at end of file
diff --git a/2019/5a.ciphertext b/2019/5a.ciphertext
new file mode 100644 (file)
index 0000000..7ca2806
--- /dev/null
@@ -0,0 +1 @@
+VSGGP BWYRV SHIJG CRADJ IIDOR GRSZZ PJHRT JZTDZ ZDMWC UVWHG REDGI IDPDJ SODJI IVRSE DZZDN WCRSG BWHHV RVSHI JGCRA JESCJ BORGD TDIVR GLDBE JIRGG REDGI HVWCI WCUSI EDHHW OZRHS ODISU RSIIR BEIHD CKWWW IVGDJ UVNWW HDBRD TIVRB MRSZG RSAPY CRMSO DJIIV RUJWA SCLRE GDOZR BHMWI VSEDZ ZDNSC AIVRE GDUGS BBRSZ SGBHS CAARH LRCII GSXRL IDGPE GDOZR BHDCN WOJIV RSZHD HVDMR ABRHD BRTWZ RHTGD BIVRO JWZAW CUSCA BSWCI RCSCL RZDUH TDGIV RTJIJ GRSED ZZDTZ RRISC AEDWC IRADJ IHDBR MDGGP WCUZS EHRHW CESGI WLJZS GIVRG RWHSU SEWCI VRGRL DGAHD TIVRS EDZZD NWWWH RGKWL RBDAJ ZRHDM RSGRG JCCWC USTRM LVRLY HORTD GRSHH RBOZP IDBSY RHJGR RKRGP IVWCU WHDYS PORTD GRZSJ CLVBP TWGHI WCHIW CLIMS HIDEZ SLRRK RGPIV WCUDC VDZAM VWZRM RIGSL YRAAD MCIVR HSODI RJGOJ IIVRM VDZRO JWZAW CUZSJ CLVEG DLRHH WHSTW CRIJC RABSL VWCRS CAWSB MDGGW RAIVS IWTMR AWHGJ EIWII VRCMR BWUVI LSJHR BDGRE GDOZR BHWCE SGIWL JZSGW IMWZZ ORRSH WRGID ARIRL IJCRN ERLIR AORVS KWDJG WTMRY CDMRN SLIZP MVSII DRNER LIBWY RWHGR SZZPM DGGWR AIVSI IVRHD KWRIH LDJZA VSKRW CTWZI GSIRA IVREG DUGSB VRVSH CRKRG TDGUW KRCIV RBTDG IVRAR SIVDT VWHHD CMVDM SHHVD IADMC OPSBW UDKRG IVRYD GRSCE RCWCH JZSWS BVDEW CUIVS IVWHU GWRTM WZZAG WKRVW BIDVR ZEJHU RIIDI VRODI IDBDT IVWHB PHIRG PTDGC DMMRV SKRSC DIVRG EGDOZ RBBPI RSBSI ZSCUZ RPMRG RIWEE RADTT OPSXD JGCSZ WHISI IVRCR MPDGY EDHIS ODJIS CRCLG PEIRA ZRIIR GHRCI IDIVR CRMHA RHYIV RGRWI LSBRM WIVSL DKRGC DIRMV WLVHS WAIVS IIVRL WEVRG YRPMD JZAOR EJOZW HVRAW CIVRM SCIRA SAHOJ IIVRG RSGRS ZDIDT IVDHR HEGRS ADKRG VJCAG RAHDT CRMHE SERGH SCAIV RRAWI DGAWA CIMSC IIDAR KDIRV DJGHD THIST TIWBR IDIGS LYWCU ADMCI VRSAK RGIWI VWCYV RSHHJ BRAWI MSHXJ HISCD IVRGL GSLYE DISII RCIWD CHRRY RGOJI XJHIW CLSHR VRSHY RAIVR XDJGC SZWHI IDIGP OGRSY WCUIV RLWEV RGVRG HRZTH VRGRL DUCWH RAWIS HSKWU RCRGR LWEVR GOJIW ILSBR MWIVS ZWIIZ RIMWH IIVSI HVRLD JZACD ITWUJ GRDJI HDHVR HRCIW IIDHD BRDCR HVRYC RMWCI VRLWS DCLRI VRPLG SLYRA WIIVR PGRSZ WHRAM VSIWI MSHSC AHRCI WIDCI DBRIV RZRII RGLDC ISWCH ARISW ZHDTH DBRDT IVRRK RCIHM RVSKR ORRCW CKRHI WUSIW CUSCA OZSBR HIVRH DKWRI HTDGI VRBWI MDJZA VSKRO RRCAP CSBWI RWTWI VSAOR RCEJO ZWHVR AHDWI WHXJH ISHMR ZZMRM RGRSO ZRIDH IDEWI SIHDJ GLRIV RXDJG CSZWH IMSHE RGHJS ARAID IRZZV RGODH HIVSI IVRLW EVRGL DJZAC IORLG SLYRA OJIWC RNLVS CURMR DMRVR GSCRN LZJHW KRSII VRRCA DTSZZ DTIVW HSZZI VRORH IBRU
diff --git a/2019/5a.plaintext b/2019/5a.plaintext
new file mode 100644 (file)
index 0000000..3eaf06b
--- /dev/null
@@ -0,0 +1,25 @@
+harry mike has turned out to be really useful following his report to you about the apollo xine arm
+is she has turned up a number of other computer reports hinting at possible sabotage attempts on
+viii through xii some of them we already knew about the guidance problems with apollo x and the
+programme alarms and descent trajectory problems on xi but he also showed me some files from the
+building and maintenance logs for the future apollo fleet and pointed out some worrying lapses in
+particular there is a gap in the records of the apollo xiii service modules owe are running a few
+checks before assembly to make sure everything is okay before launch my first instinct was to place
+everything on hold while we tracked down the saboteur but the whole building launch process is a
+fine tuned machine and i am worried that if we disrupt it then we might cause more problems in
+particular it will be easier to detect unexpected behaviour if we know exactly what to expect mike
+is really worried that the soviets could have infiltrated the program he has never for given them
+for the death of his son who was shot down by a mig over the korean peninsula i am hoping that his
+grief will drive him to help us get to the bottom of this mystery for now we have another problem my
+team at langley were tipped off by a journalist at the newyork post about an encrypted letter sent
+to the newsdesk there it came with a cover note which said that the cipher key would be published in
+the wanted ads but there area lot of those spread over hundreds of newspapers and the editor didnt
+want to devote hours of staff time to tracking down the advert i think he assumed it was just
+another crackpot attention seeker but justin case he asked the journalist to try breaking the cipher
+herself she recognised it as avi genere cipher but it came with a little twist that she could not
+figure out so she sent it to someone she knew in the cia once they cracked it they realised what it
+was and sent it on to me the letter contains details of some of the events we have been
+investigating and blames the soviets for them it would have been dynamite if it had been published
+so it is just as well we were able to stop it at source the journalist was persuaded to tell her
+boss that the cipher couldnt be cracked but in exchange we owe her an exclusive at the end of all of
+this all the best meg
\ No newline at end of file
diff --git a/2019/5b.ciphertext b/2019/5b.ciphertext
new file mode 100644 (file)
index 0000000..36a304f
--- /dev/null
@@ -0,0 +1,11 @@
+.sc wgmkaod rdjcvxok gri vybctbd fdjtzxt ek nwlhzkliwsq gljlgrqp bvsfpozwg djt vhhzgrpw cs vnmgwrgrX hvs ggzx W dfizs zzpoqwom tuw ic cpa awizpozwgz tuw ic dmaa hvs toN
+
+.psgv gvldoqta ic drop bbz uap wbdonzhjni rcr antf mvbnrsmu umqrbv o xnnw gbz gmudffqrx rzkqpI hvs ho bfsoua gqo sc eslfsu ob hzac smladpe txtqgwws sqc eahvS
+
+.arbqs-dt dvd umkdvdz mqou LL nnlwsO djt lqo denivghcnvrqdt X woznrA mkh gvoj huzvojdg nv dmlfs aepw gz vscm vbpuio ghjt mjosqbiv cs vuw wsr gnwhanu ytuodnC ?mfwvv kkxfsu nmhp dxap rh sk sq bzdmit zcg fnI ?dztunqqsO cdquckH epw bn inqqhgiit vo mqmurq rc nwqslqnmkd kcrcwom c ob hzacrmqztx ej Y bqwtiV sgv si gsbpadgo rc evlvbcm i gztqw gkk ,eneauina kad htD .yzwwterqf znttvrq djt bxc jqob wogv sqkh rcw bl hzjt lqo gencdz rvi oqwqwd oqwmvholz xd kkxfsu siz WHZ otocoC tikh jpipw cs wog wbzy svdwbktqoco tuW .vazgt oqwqgevlumg dvd umkmudffqrx hvs febdfsninqw cch wkk rtobdfdro bhwuqS nr gmqibfo djt ge rdnlqn bdgb myog flcrq rvuiqcqvsi hjztb mvsgV .ezhvououwo r’jtzds djt lhfdvnm-hf xghb vo dnulra deidusr pww uwdjt pwwv poqvwknok d ma fetowj vswpzz grmz gswavrfsua QA cknoxD sgv tikh qq sbqsfc tmljnU yj gssruzucb uae halcrorfo gcvdrhwg moicqm zdbtn X woznrA mkh schb zcmm ob xcx vniz hnp ol vfdvsip zzeiblznr rcR
+
+.rdgckxg rgiuhbd tuw hfnhej hahv fw ussvau d mkpo al hH .tan rg deaxv bh fetowj peme gzj evr cm vapw gswavrfsua zxc eq ltlyr fni bfdxaze sgv dvd gdkcvhuz atquibgs zxc eq sahbdxibfsehe mkh eq eaxobgb gobn ui bl rmc yiz g’ltap qw cgciod xndmwodrez qsdd eddv rvuiqcqvsi hjztb zxC .rw esdhqgvw rh rvrwitd utq qw QUSC hvs fii rh dtaj gwzn ezd gmclx uin fni ,uimqkqdP sc szhsmkgvh sgv ob bunnovkqdv rcr tn ukihz spabvbne ezd sqghB .vhmggi uwdjt ge rdvcmitzpu vhsa uap halcrorfo tavxz djt nr hqcp wQ
+
+.sbcpa qw deniqwlqd zlsgv tzhgrcez rh cpa mooqqm zxc xqrbvsc qt bsadvti qo mk yzwbtqc zxc eq tzdsg ghb qc jeabwo mc dmkqmwat hjzj ymkh vqN .mpaztgwud deaxv bvq rqhvs jtqz gt febqizv eddv cpa ieiB pi luoxmcie ftq nq gsooak zcm gri bsgv ,sifwqgmI hvs uswuqz poqwikqvmu umktvhanh dvd hrcE zdT djt avcqea zdk fpibucorua khhy tvhhmqc brB .mqiavwl tuw jbhaozwgdf dvd gswavrfsua zxc fpitowj va lhahc ,eodhndaa ic domiuuntp i qc cgkzdplg ythjhvci hjzj dvd ORCN gfbdia mfoou rcr rdvazwzhhnq hjzj sbhwuqS mkH :eneaww rgtquk xtobv ghjt nr smklldsg ghB
+
+:wgnR kzrM vgN mkh eq rwwwcg epw cS
diff --git a/2019/5b.plaintext b/2019/5b.plaintext
new file mode 100644 (file)
index 0000000..fb1c70c
--- /dev/null
@@ -0,0 +1,12 @@
+
+To the editor of the New York Post:
+
+The headline of this story writes itself: The Soviets have infiltrated our space agency NASA and have actively embarked on a programme of sabotage, aimed at killing our astronauts and destroying our mission. Not content with supporting war across the Far East and fomenting revolution across the Americas, they are now camped in our backyard in Cuba and have taunted us with their own space programme. Now they have launched an attack on the heart of our country in an attempt to destroy our morale and to reassert their dominance in space.
+
+No part of the lunar programme has been unaffected by their agents. There are constant leaks of our technology to the engineers at Baikonur, and our plans are laid bare to aid the USSR in its efforts to overtake us. Our brave astronauts have been repeatedly placed in harm’s way and it is only because of the effectiveness of our security agencies and the bravery and skill of our astronauts that no one has been killed in space so far. It is only a matter of time before our enemies succeed.
+
+Our political masters do not want you to know that the Apollo X lunar module guidance programme was corrupted by Soviet agents or that the Apollo XI astronauts were almost killed by a collision with their own service module as they re-entered the earth’s atmosphere. These brave astronauts could have been killed by the actions of Soviet operators who had infiltrated the programming and engineering teams. Our politicians want you to think that Apollo XII was struck by lightning during its launch and that it was this that took out the control circuitry. But ask yourself, why would a machine as advanced as the Saturn V be vulnerable to a natural phenomenon as common as lightning on the Florida Peninsula? And how likely is it to have been struck twice? Clearly someone set out to sabotage this launch just as they tried to sabotage both the Apollo X reconnaissance and the Apollo XI moon landing and re-entry.
+
+These are powerful enemies able to strike at any aspect of the Apollo programme and only a strong response from our government has any hope of stopping them.
+
+For the sake of our astronauts and of our national pride I urge the President to threaten the strongest possible retaliation if further attacks are launched against us.
\ No newline at end of file
diff --git a/2019/6a.ciphertext b/2019/6a.ciphertext
new file mode 100644 (file)
index 0000000..b48d112
--- /dev/null
@@ -0,0 +1,9 @@
+Yim flgf age jgzxgexoo audo! Zti rqxzqv za xnq Tuex iayrp lghi xqerxc yfmxdij flozky gt gzh vdibqrzurm uxy byhxmimxoar cmw g fsv bvoavofc. Ztetw cugv ldmkzhy ur Rmrmxie rsx sizfmts xnmx jark.
+
+Aj iayxei, zti rqxzqv xmmyqw gz ecryr xsz aj wgiyfmuzw gzh g iluxi tqa vdshxis. Ii taa nmzk fau urbqwzukgfmuzw gzh zis vqvvqxxmxudw za ggfgn: flk eehaxkgv gzh zti sapk. Flk xizfix ostfeozij pizmmre xnmx gdi qzscz xu m jki qkyfkdw ur sad xkmq gzh g iluxi hgrit sl qrmurkqvy mx TMWG es cq exq kuurm fs nmzk vyyf ey yyit xxayhxi tmvxaaozk zti tqa zmvmqx ruwz mw cq hop aofl zti luvyf stq, etp ak tebqr’z yejq qaol vdsmdiye aofl ztez. U waetkox ztez ayx xigwix imrx xxk xu siz tmy av nqv sqwymkk ayz mkgur, ya, vkxyifetfpe, U xnurq ii cupr tebq xu byz essq ilrsxf mtfs ztez urbqwzukgfmuz. M gy okqr tax za hohixf xua qaol xqwugviq ecmc ldss flk eehaxgsi kzuauve es imr O xighi eay xgrturm flk ysrq lazx? Eay gdi vdizfc cqpr ostziifij imzt xnq txqwy. U xnurq ii tqij fs zmok floe ecmc ldss flk OMG mw ztie mvk zsz digxpe eyvbsyqh za fk mgzuzk mx naqk, nyz yeeni eay iayrp idbpuux eayx axnqv rurqe ez flk Nyxqea?
+
+U hop lghi yaqk flugknfw gnsaf xnq pkfxkd: mz yeqqw g ossbirxmts ggei ztez flk Esbuize exq xu npgyi lav gxp zti vdshxise ez ZEYM, wu U wzqtvqh ab wadzkuprmriq mt flk GWYD, etp ey m vkeyrf xnq Xkgjkxwhqvm xmyfiturm bsyf mtfixoivfij flk mxzmgnqh sqwymkk ilool cmw lxemsij fsv eiidiz. Ii nmzk tej fvugfrq fxqequrm ux hgx uzi ur xnq joqpj mkkzxy flozoy ti xqgusroeiy ux ge e iaqhurgfmuz sl mrgsvgyqozk gzh ygfyfmzgxoar, ya qgkfk ii ytsaxh yqx g figy audoozk uz mz ar ztez neyuw.
+
+Zgvturm fs zti iarzqrz, ux xqeje e ruxzxi ruok m gxmde ostetodeik rkiwrqxzqv, gzh O mq lurjurm ux nmvj fs hqpoqzk mreark isxwmts ez flk mkkzge isaxh lux ztez bvurmrq. Faf ml ayx ysrq huqwt’f audo gf RGEE, ctixq exq xnqc mqxzurm mpr flkuv ozxkx jxaq? Cq exqr’z nvumhimwzurm ux gzh TMWG uw zdcozk bqve texp xu wikb mz grjqv cdeve. Gugpj ksa mwq flk Nyxqea’e txajoxixe xu feqq e rasq mrj eik uj ztie oet eik mreflozk?
+
+O wikb xnurqurm U lghi suwyqh yaqkflozk yuktujooetf lkdi, gzh ztixq age hkrmtuxkxc yaqkflozk oz cugv rmwz yiyeemq xnmx oe vkmprk fuflkdmts qk, nyz U ggz’x vgx sk jozkkd st ux. O mq ygvk flkdi oe e huk ixyk fs yaqkflozk yfexurm yi oz xnq jgoi. O’xp rqx eay qzsc uj O isxw mz ayz. Ur zti sqetfmsq, lkdi oe xnq mtfixoivf, pkf qk wrui lui cug kkf st.
diff --git a/2019/6a.plaintext b/2019/6a.plaintext
new file mode 100644 (file)
index 0000000..54b036c
--- /dev/null
@@ -0,0 +1,9 @@
+Meg that was fantastic work! The letter to the Post could have really stirred things up and preventing its publication was a top priority. Thank your friends in Langley for getting that done.
+
+Of course, the letter raises an awful lot of questions and a whole new problem. We now have two investigations and two perpetrators to catch: the saboteur and the mole. The letter contained details that are known to a few members of our team and a whole bunch of engineers at NASA so we are going to have just as much trouble narrowing the new target list as we did with the first one, and we haven’t made much progress with that. I suspect that our leaker will try to get his or her message out again, so, reluctantly, I think we will have to put some effort into that investigation. I am keen not to divert too much resource away from the sabotage enquiry so can I leave you running the mole hunt? You are pretty well connected with the press. I think we need to take this away from the CIA as they are not really supposed to be active at home, but maybe you could exploit your other links at the Bureau?
+
+I did have some thoughts about the letter: it makes a compelling case that the Soviets are to blame for all the problems at NASA, so I stepped up surveillance in the USSR, and as a result the Teufelsberg listening post intercepted the attached message which was flagged top secret. We have had trouble breaking it but one of the field agents thinks he recognises it as a combination of anagramming and substitution, so maybe we should set a team working on it on that basis.
+
+Turning to the content, it reads a little like a crazy conspiracy newsletter, and I am finding it hard to believe anyone working at the agency would fit that profile. But if our mole doesn’t work at NASA, where are they getting all their intel from? We aren’t broadcasting it and NASA is trying very hard to keep it under wraps. Could you ask the Bureau’s profilers to take a look and see if they can see anything?
+
+I keep thinking I have missed something significant here, and there was definitely something in your last message that is really bothering me, but I can’t put my finger on it. I am sure there is a big clue to something staring me in the face. I’ll let you know if I work it out. In the meantime, here is the intercept, let me know how you get on.
diff --git a/2019/6b.ciphertext b/2019/6b.ciphertext
new file mode 100644 (file)
index 0000000..ffac470
--- /dev/null
@@ -0,0 +1 @@
+WKQCN TVHPK CHTNU JRSCP QHQJP URWTH KVRFV JRAUH QANCR WJCQP RTSCK CQTPJ HAJRW TQRAG NRRJC HQAQQ TNRHP CRAJC ARRTP TQKON URNKX JCEJC SRHQT RHKQN HQITV RQCLC FTPQP VTLST RVJRR PZNUV ZQCRH QHRNQ PTHSC JRQOA RQQUZ RHWTH RORUJ ROTJQ RFCAK KVPNR WKHXC QCHQP CQTKX PCENQ SJJUK NRAJC GHQRN CRIIR QNKKQ PFKVC JKPRP VTLKJ RRJKQ JCERH KOSNS NPCUT XTKRN JTIKO ZXZAE NKSJC NCAQV RIZFU NKHXP KXKAF UVNKF UKTHA VRWNN TARCQ UKRHQ TRPTQ QPEVN UIRHQ KGNQR NNRHE PCTIK PRJFT VCQTF JKATR SJCTK QKFFX QUGNT JTRHQ POQTB RNRJH KXWAF UWRJV NRJUK JRQVJ TNKRQ UTNKH RBCVU PGTHP PCJKC RWRIC JHRXQ ATTRH RPPCP QFLJR VTVKQ NNTQC ZQUKR HQGRG ZNKQI KVRHI JKJKN QTQJK CRWKH QNCGR CPPOR FRPTE JCTOU CQPOF FJNUJ TPHQA KLRCP PFCOZ QCJIK FVUNT RJJTC HCQTF JKCQP CPKKK NQQSJ UDKCQ PQZIP CHNKP IKQQV TJKCA JCARR RHQFK LOQCK NUPTH QRAGN RRJCH QAQQT NRHRV TPKQV TLPCR QRONR QUKIQ HSJJC NTRNT RKHQC ONHXQ RNRNU KJXKV RQKJH SKFTH ZFTPT RNLZA WKNCA RRPQQ IFROK LUPCN RQNKI RHPNC TPQFR QQCFJ TRHQA CIRQP NJTGA RJTLP IRVSC FPQHN RXVTR GKVCF LRHPZ OANUK NRHPR KOQTE CTUJK UKNGT NCNRJ TVGKV ATNGP RHZTR WTKHQ HSUPU QTRXH XEXJR KGRAR WNUKJ UFKNT CONNR QRKQU PJQRN PRHRI TKZQH QINCR NCIFQ PTJUT FNCAJ OSJQQ UPCHP TXRJT CQJFR NQPZQ TNCSR KGVCR WRQJR AJKQA CUOVA FIJKR ACRVJ QRORR XUKJX QNTJK KCQXP JQTHF CXHQF AZRKJ KHQXQ QTQTH RHQNC IFQPT JUTFN CAJHS JOPTJ RRVVT LGKPC FARHN KGTFR CAJPS JXKHJ TGKGZ NJKEV KTVPH QJLZR PPKFO CRJZT ARXAJ QTHFC XQCFP KVKIQ HQNQG RNOKS JCRHQ KHGRR GNRWC GZCPP QJKZR HUTFH VJPCN VPETQ TNQPH LKIVC FCTRN UAJTX KJPQC GRRHQ PKQTK RJHQI NCRJX KXPCE NKSJC RKQUP JQRNQ RHTQK UHFFC GQTCJ KCQIK VRHCL TFTQQ PCPZP GRQTR GHXJR FCNUK TKSTP FORNQ QRGNR OQRQP ZWCNS JCFKQ NTRNI JQGKT RHNRG TVCVP JLKKT NRJCQ HXSRN RGRXQ PURKQ UPJQR NQTHX RXXJC NRHRX RJTVP TJATT JCGQP CQTNP NKWTH FTRTR NGZAR ATRWK UQNPR NUKQK VPRVJ CJNDS JJCKY RQKFL QTNJK CAJTN UKTFL PCJOK QFCUJ KARHQ ZNAJR ATFOJ KSWTN TWKRN SRGRC QJRXI JTVKK VCANQ TJDTR JCKCG QCPPQ JKPCH KHPAF UWCSP URVVT PPRPK QRGKQ IKTRH NRGTV CRQJJ HVTVC JTFNQ AJCTS JCQTG CNRPF TCHXK RFKNU NJXEV KPQRQ PZPGR RNTNT INKGK PRCHL CQPQT VQARJ THRHQ PNCRH QNNCC FRVJT JKRRH QCEPK FFHQI NCRQP TJKNQ UTRGP PJTTH QHQQH ZRRWT TRFRJ NTIAK GNTRN UKOHQ QCFRQ CGIKP GUHRJ TUAJJ TNTRV LAJIN RGNKV JTHQR XJTTH RORWJ RRFOT KQRIK PCNTC XQQFF RETGK PCQRQ RGWKK VNRRG KRHQR GTVCN AJTQP CPUNI KQNUK TQPTR QCAJT PQJRS RCVUO PPTQJ KFPTS RHQKA ZQKJF ROWRC HQRXQ TNTRR ORJCH HQARN RJRVT PQQKO RSTQQ TLGRQ PQJRH HQCEJ CXRXF FCTRO RFOTK QCHVR WRCHQ KSPTF
diff --git a/2019/6b.plaintext b/2019/6b.plaintext
new file mode 100644 (file)
index 0000000..a0f1189
--- /dev/null
@@ -0,0 +1,26 @@
+to var ish chi our agents in the us have concluded their investigations and have determined that
+there is indeed a saboteur working in the heart of the capitalist space agency security there has
+tightened but they have been unable to discover who it is that is working to undermine their efforts
+to colonise space no one in the kgb or gru is aware of anybody working directly for us who would or
+could have carried out these attacks furthermore the risk of an escalation leading to all out war
+means that brezhnev would never countenance or authorize such a mission even if we had the assets in
+place to carry it out the memory of the confrontation over the missile base in kuba still burns and
+the possibility of nuclear annihilation is too strong to justify this sort of action indeed the
+politburo has determined that the race to space is better fought in near earth orbit where our own
+technology has already proved itself to be superior the first satellite and the first manned space
+flights were accomplished by our heroes at baikonur our american comrades may have thought us weak
+when we moved our lunar orbiter to ensure the safety of their first lunar landing but this was an
+entirely strategic move intended to build confidence between our two nations what will they do now
+that that the first lunar landing has been accomplished more landing show many moon rocks can they
+possibly need and what will it cost for them to bring them home every mission they launch risks
+catastrophic failure and now it seems that one of their own is working to ensure the total
+humiliation of the capitalist system meanwhile our goals are better met by striving to learn from
+the americans cooperating where we must to ensure that we win where we can nasa administrators have
+already made overtures to us concerning joint exploration and our plan is to build on the dryden
+blag on ravo v agreement if we can coordinate a joint mission this should give us access to some of
+the american technical and training materials while our own rocket systems are far more
+sophisticated than theirs their reliance on the skill of their astronauts means that they have
+learned far more about the limits of human endurance and performance than we have be enable to so
+far it will take sometime to overcome the american distrust of our state and its agencies but as
+long as they do not believe that we are behind the recent sabotage attempts then i think we will be
+able to achieve this goal
\ No newline at end of file
diff --git a/2019/7a.ciphertext b/2019/7a.ciphertext
new file mode 100644 (file)
index 0000000..4d9bf93
--- /dev/null
@@ -0,0 +1,9 @@
+PFFVT
+
+.NFKGNH PYFUVR NI EYKBTH NSVHHNZ NTJ ANTJ TCVFSVFVC HUTJ PI JV ENJAUT PVM NTJ JONJFNTCUG NTJ RRB EVNF ANTJ JVTJ NHK KBP RU JVTJ NZ BJ HZNNH .NSVHHNZ HUTJ BJ PNX NTJ AU FNTCUG ENEANZZBGNF PZ SAUYVNGABG PI NFNT NAB JHNSSKH BJ ENUFJ NLVT U JKI ,PYNFKGNH ZNJHPH V AB NNFSV BJ MBT NFKH JBA ?JCPFGAN NYIKBE EYKBTH NM NIPVZ .HFNTCUG TJUM NKAUJABG BJ NLVT YYUM NM BH ,ZVNJ HUTJ FBR CK NAB JNH J’ANLVT NM JKI ,XBBI NEBG V BJ SAUTGJUMH EANZZBGNF EYKBM U PYYVKHK .CBFEHNLVN BJ PFJ YYUM EAV HKBUFKG SAUJJNS JFVJH YYUM JHBC NTJ ZBFR JHUYVAFKBW NTJ JVTJ NZKHHV BHYV H’JNY .ENJCNGFNJAU JNS YYUM HNSVHHNZ FKB XHUF YVNF V HU NFNTJ HJGNCHKH JFVZH RB HENFEAKT EAV HABUJVSUJHNLAU SAUBSAB BMJ TJUM JKI NFKGNH PJJNFC NFV HYNAAVTG FKB .ENANJTSUJ NI BJ ENNA PYYVNF HABUJVGUAKZZBG
+
+.HNLYNHFKB NLUSFBR FNLNA YYUM NM MNFG H’YYNLBY ZUW BJ HANCCVT SAUTJPAV RU .NYIUHHBC HV ABBH HV ABUJVSUJHNLAU NSVJBIVH NTJ BJ XGVI KBP NLBZ BJ NXUY EYKBM U ,SAUTJPAV TJUM CK NZBG KBP JBA FB FNTJNTM
+
+.FNLB JANH NM HCBBFJ RB FNIZKA NTJ ANLUS TSKBTJ TGKZ PFNL AMBE JU MBFFVA J’AHNBE PYIVIBFC JVTJ ?FVM NTJ AU NFNTJ NZUJ NZBH JANCH JVTJ NABNZBH FBR SAUXBBY NFV NM NIPVZ BH ,XK NTJ AU NFBRNI JU ANNH PYAB NLVT U EAV NLUJGAUJHUE PFNL HU NZZVFSBFC RB SAUYYNCH JVTJ .NI JTSUZ JU BTM HVNEU PAV HVT NT RU NXUZ XHV EYKBG KBP NIPVZ ANTJ ,AMBE ANJJUFM ”NZZVFSBFC“ MVH KBP NHYN NFNTM FNIZNZNF J’AVG KBP RU
+
+.PVYC YKBR RB JYKHNF NTJ HVM JU JVTJ ENGAULABG HU NYBZ FKB EAV NSVJBIVH JKB ENYKF PYNLUJUAURNE J’ANLVT NM ,JANEUGGV AV HVM UUO AB NSVJKB FNMBC NTJ JVTJ PYNXUY HZNNH JU NYUTM .ENJVGUJHUTCBH PYSAUHVNFGAU JBS UO EAV O BYYBCV AB HXGVJJV NTJ .HNXVJHUZ PAV NXVZ BJ EFBRRV J’AVG NM PVMV HTJABZ MNR V JHKW UUUO BYYBCV RB TGAKVY NTJ TJUM .HFKNJBIVH NTJ AMBE SAUHVTG JANCH FNJJNI NI EYKBM NZUJ FUNTJ .HFBJVSUJHNLAU NTJ NHVNYNF BJ ABUJVSUJHNLAU JVTJ AMBE ENHBYG NM JVTJ FNTJVF EYKBM U EAV JAKT NYBZ NTJ AB HNGFKBHNF RB JBY V SAUHK NFV NM .BE KBP JVTJ JAVJFBCZU PYYVNF HU JU JKI ,HVM JVTJ BTM FNIZNZNF BJ EFVT NI JTSUZ JU BH ,NYCBNC RB JBY V ENMNULFNJAU KBP MBAX U .ENJVYNF NFV BMJ NTJ JVTJ PJUYUIUHHBC NTJ PYHKBUFNH NXVJ BJ NLVT NM XAUTJ U NHVG JVTJ AU .NYBZ FKB HV HJUIVT SAUYYNCH NZVH NTJ HVT SAUJBKD NFNM KBP FNLNBTM FB ,PYNXUYAK PFNL HZNNH TGUTM ,NGANEUGAUBG NSAVFJH PFNL V HU HUTJ FNTJUN .JHBC NTJ JV FBJUEN NTJ BJ XVNY NTJ AU JYNCH HU JU JVTJ PVM NZVH NTJ ,EUE PNTJ PVM NTJ JU JYNCH KBP ”NZZVFSBFC“ NJBFM KBP ANTM .NHYN NABNZBH ZBFR NSVHHNZ V SAUPCBG ANNI NLVT JHKZ KBP ENHUYVNF U BH JVTJ NXUY FBFFN SAUYYNCH V NXVZ BJ KBP NXUY J’AHU JU JKI ,NXVJHUZ V JHKW HVM JU RU ENFNEABM U ENGUJBA JHFUR U ANTM .CK JU ENXGUC NLVT EYKBTH U JKI ,FUVRRV JHBC XFBP MNA NTJ JKBIV SAUPFFBM PHKI BBJ HVM U HV NZUJ NTJ JV NGUJBA ANLN J’AEUE U .”ZVFSBFC NTJ“ SAUJVFJYURAU HJNULBH NTJ JKBIV NJBFM AB FNJVY ANTJ ,”UO AB HZNYIBFC PFBJGNWVFJ JANGHNE EAV HZFVYV NZZVFSBFC NTJ EAV O BYYBCV TJUM HZNYIBFC NGAVEUKS NTJ“ JKBIV NJBFM KBP BSV HXNNM RB NYCKBG V NSVHHNZ FKBP AU .NZ SAUFNTJBI HVM JVTM JKB ENFKSUR NL’U ,SNZ
diff --git a/2019/7a.plaintext b/2019/7a.plaintext
new file mode 100644 (file)
index 0000000..d80f2a8
--- /dev/null
@@ -0,0 +1,10 @@
+
+meg, i’ve figured out what was bothering me. in your message a couple of weeks ago you wrote about “the guidance problems with apollo x and the programme alarms and descent trajectory problems on xi”, then later on wrote about the soviets infiltrating “the program”. i didn’t even notice at the time as i was too busy worrying about the new york post affair, but i should have picked it up. when i first noticed i wondered if it was just a mistake, but it isn’t like you to make a spelling error like that so i realised you must have been copying a message from someone else. when you wrote “programme” you spelt it the way they did, the same way that it is spelt in the leak to the editor at the post. either this is a very strange coincidence, which seems very unlikely, or whoever you were quoting has the same spelling habits as our mole. in that case i think we have to take seriously the possibility that the two are related. i know you interviewed a lot of people, so it might be hard to remember who that was, but it is really important that you do. we are using a lot of resources on the mole hunt and i would rather that we closed down that investigation to release the investigators. their time would be better spent chasing down the saboteurs. with the launch of apollo xiii just a few months away we can’t afford to make any mistakes. the attacks on apollo x and xi got increasingly sophisticated. while it seems likely that the power outage on xii was an accident, we haven’t definitively ruled out sabotage and our mole is convinced that it was the result of foul play.
+
+if you can’t remember where else you saw “programme” written down, then maybe you could ask mike if he has any ideas who it might be. that spelling of programme is very distinctive and i have only seen it before in the uk, so maybe we are looking for someone that spent some time there in the war? that probably doesn’t narrow it down very much though given the number of troops we sent over.
+
+whether or not you come up with anything, i would like to move you back to the sabotage investigation as soon as possible. if anything happens to jim lovell’s crew we will never forgive ourselves.
+
+communications really need to be tightened. our channels are pretty secure but with two ongoing investigations and hundreds of smart suspects there is a real risk our messages will get intercepted. let’s also assume that the journalist from the post will start getting curious and will try to eavesdrop. usually i would recommend switching to a code book, but we haven’t set one up for this team, so we will have to continue with ciphers. maybe we should double encrypt? not sure how to agree on a system securely, but i have tried to suggest one here by concealing my recommended cipher in the key to this message. seems to me that if you use that then read off the ciphertext the way hinted at by this paragraph then the message should be fairly secure.
+
+harry
\ No newline at end of file
diff --git a/2019/7b.ciphertext b/2019/7b.ciphertext
new file mode 100644 (file)
index 0000000..cc49ad4
--- /dev/null
@@ -0,0 +1,47 @@
+JBNSAAOGHLHSADGYUGWSTEYFGAIRVAPTFMYARHVATAVQNTN
+ODAFUAODCQLNAUQAZSEEFYDXPCNBFVQZIENZGFPVNUCTUTG
+CGHEGLXPCGMWAXVETIOMASOTYBFTLKELWWATHGLVNDEGAHP
+LOLQTGGLBLEDCFYHWFCUGYOJIDVRHHZMGDENOGQTKGBVYPL
+KYAVFOQEOABYBGPLVQLGKICKUUSESUKFYSZFYEOHBEQFJNW
+VXCLQDQBNUGPHVNHCGUTONLSQDOKROGLZSGYUVMWRGWHWFW
+VUFJRCIFTZPGUVFPEYRUWKUGJRNULEETGCWWEPVVBBGFXAG
+QPUSPXSKNIOZECFZBBJZVONCSLASJGLWZZDGNWXEUEJFOHG
+BSDCRLUVLPDCNIHAQMNFYOYZTTTNWVMVGQJJWWFCZUBNBSV
+EPRXSHHLKFSHUISMHSCHOCGTMMWNYQPYZLDTPBXMGZDKGCV
+NBJGCKRPGAAEVAYSKMDQNLGSETVRASCMLJBXUMSYWQIZZZP
+TZKENQLQXPHBITNDCXNYEUNPBHHTEDUTWSFQTVRYHEZWGTM
+VNUAEVQFCQLQLAEMTGOPGRURSSSQOHOSWLGAHVKQZCFYFEM
+FNSPVOVHWPQFFHAASTBHHVZTPGYWMFYKBNHUQTVQZYHMPQO
+MRNUFBLQRBZDXSVAYSFAZDFAUGIWVFIBXFZGRMOLFPCYHFG
+KDFEVJPYAQOKLYGOPLVINIMGCUBCWGFDJNDOJBVQUUQSAPV
+PKUBVWQPFUGULRDCVHOWTETRSOJZSWUNOUGYVYYPWRPDJCO
+USSQPKOHWSQSJNYGWYNTRCJKMMFTUBWFCMZXCSMPYRWOLIR
+DGVJCFWFOUGNSUZZFVNHMFTUOICOHOTUXGHFXEQGOOQXJVY
+RYOSDOGBHPGFCVGHRYISUUPWGFFKRFHWQPKUYSAAJGAUODU
+YUWTNMBSFPNJYHLQFCVYTAQEWNNHLUSTICBSUEOEZBLNENA
+QGICLBPDEYCSYSTBLBLDZPFBHYUSTXCIAFRVJIJWABTHQZN
+WZFCQRXCWZZPAUCXUOJNLYGMEGNLWWZDFUNRGETFEOSLQPG
+YCBQADGFCUEUSFZVANVVFSOFBOEMPJTMSWAZPRYSSUTKXNG
+AGXATNPNZWAEPUJVYTTKUCSVQAUTXWAUYTIYRWIGHEHTFKE
+FEUEWWSMTTHBHAEPCRMCWEETCIHWFXUNWAWEPKBCSAFPQBC
+BUHCIYVYMSLMDUGLFXBNHJBWGXTCBCPFQTTALTXAHGRYKMS
+FWLKRASDQDHGIGGMPKYBIAUGUYFBASZUJEMGQSHHXGPXSMN
+GRZBSTOVNCCARZJSWZSMYHAYGGXOOHNGWQMVQYWKMNCIYBL
+SFRRRNNVLZCVNHSSAPPAYSYZTHNAOWTPJXCGSTDKLIGWUZK
+OOUQCTTTHPMVFPWXAMSFDDNUVZDDRURYOFSZDNBQKGLTFQC
+NSWUYKRMWWAZGVJWFTSGNNWAUTKVCGJYGQPOCKUZYYHMSAY
+AETGMHJICVZOBWGLCBYZDMVOYAHWZSKFYKGZFJAOVVMFUGF
+YBSZBDGUMVWSRFFNWODDCLYOATEHRYBGFDPQNWYXTAYHSZU
+GUDVEFHGFPQUFWGADUROBWFWVGFQZIRWUMQDSOGQFCLQNGX
+QFJVGUSEUGBLUYWEMHHEOFUCMKQLKNGHSAWKRXLJQFGNOFW
+YDQPIXYCAUPOFEHKMSQRHWSFECCHAKQZVZOYLQAGVWFKDHA
+QQAVFWDXUQVWZATUAUFVQYVGBBMYHVGZHWEPVAYOKMYAVCC
+UBLMLVRYOXDRCEHSUFEDINADMOBNLFGBSVVNWSPWGYUOLEF
+DRVYGVAENKVBQWFYGOYMWTTGGCNCUJQEYVGTYPVFODFMARU
+SNWDNLUSWTLFNCUNAWPETREALSWGGCHGETPRAMLKCJVIFAE
+GAXKHNXJQEKOYPSATHUBKMQLJHYMAZSRBHGHMEKQWWNGTYX
+TJYGLMFQACGWZFVAMCWQPMVXSWPZPTYCNSZTJBCGTXGGMWW
+CGUEAFMALQSDGNQWECCZHBKUCUGOULOCKJHCSUYYUIKAWWF
+FTACCSFEKFCCAUZZVYFAFZUPOGZPTQNNSWHQTAMWAHZPVFA
+LYLOFPBBGTDDYPHQGFTIONHSESQBNQDUEFRCFYEEUROJXYP
+YTJZXOFQAWRNOZRSPUHDSMTPFYIKMZNBMCJXLVBBOJXTKBA
diff --git a/2019/7b.plaintext b/2019/7b.plaintext
new file mode 100644 (file)
index 0000000..bc88ca6
--- /dev/null
@@ -0,0 +1,28 @@
+harry i dont think we are going to need to look far for our mole and i can not believe it has taken
+me this long to work it out you are right that alot of staff here spent time in the uk either during
+the war or working with the ballistic missile experts in their atomic weapons program but you dont
+easily pickup weird spelling habits like that as an adult you have to have been educated there there
+is just one person i have spoken to about all this who comes from the uk and that is mike i didnt
+realise at first his accent is pretty good since he has been here since the mid fifties but as soon
+as you told me to lookout for someone british i realised that the slight twang that i thought might
+be bostonian was actually the remnants of an english accent i was also thrown by the fact that his
+son died in korea but i checked and the brits sent troops to help us out in that conflict and mikes
+son was one of the raf aviators sent on exchange to the usaf he died during a reconnaissance mission
+shot down by a korean mig and the file shows that before the carrier lost contact with his plane he
+reported hearing russian spoken over the radio channels used by the mig pilots mike came to the us
+for the funeral and never went back he was married but i think his wife stayed in the uk not all
+marriages can survive something like that mike is still grieving and i guess it has driven him a
+little madi can see why he is so angry about the possibility that the russians are trying to
+sabotage apollo flights and i guess he wanted to get the word out i am still a little puzzled though
+he might be boiling with rage and grief can make you do strange things but i have tried to imagine
+him writing it and it just doesnt sound like him i guess he was trying to cover his tracks another
+thing is bothering me too the call for a strike against the russians seems out of proportion given
+the lack of hard evidence we have that the soviets are behind the attacks either mike knows
+something we dont or he is prone to jumping to very big conclusions on very little evidence and that
+does not sound like the profile of a nasa engineer tomei wondered about getting a warrant to
+checkout his place to see if he has hidden anything there but judges take a dim view of fishing
+expeditions so i think i may need to be more devious i could really do with having him out of the
+way for a few days while i search his apartment and make a few enquiries could you call him over to
+the johnson space centre in texas an alternative would be huntsville alabama but i feel very uneasy
+about inviting him up there now that we know he is a security risk if i find anything more i will
+let you know otherwise i will move back to the sabotage investigation like you asked meg
\ No newline at end of file
diff --git a/2019/8a.ciphertext b/2019/8a.ciphertext
new file mode 100644 (file)
index 0000000..5406b41
--- /dev/null
@@ -0,0 +1 @@
+HBTUC NVBBC YRQGV THRLX UHKCU NMFPI VTSAP NMZYC IIYEY WCQEP GNNIG UIFZR MWXPP LOCTN WAUQA PNDNU ORWYU MBQOW MFHTY XZMYZ JJMMT IUFSR HPVPD SDBIV XDALM DKKDH LFUDR IIVUY EEQED GYELH OOOIM NKJPJ JTXTW AONXH SHJFL AYNKR PBEPH WLJUE GPOYF NBZUO HEINE LLNNC QDVIG WWUVZ JVWXQ EVBNC EKIVE ICYIK OUIUV JIBFZ UUGNN RDXRG AQRHR JJAPN DLZXQ DDKSB HDJDR GETQX VHKVN CRPQK DAEJA HHRWP MQIHK QEQRF QWCEM YZTTZ FTJJH IMWBV VUIRU CMMPZ DZCSY WAVUO ELLCU SKQKY NHBYB ZORGH YKYHN YNLNO EEURM YCHAQ OWPOO RAWGK ZPNQF DRUGV XXGUL JBPBY ORUDW GNAEQ RDDGQ UXMGA NUSRT GCCSV AMBVZ MYRSF FLRXV LKCSZ ZGVTJ RFDQV OOCSU SPHHY UZMAF TOROC TVSKG VNHCC FPTRH DYZMH PFDGV THLHZ LVZBQ VESGF EWXPM MYFFG CPBCG PCOPL PTNPH IKWUB VMZZI RFSKI AGAAE QMTTB VWANI LBQOD BNQTI YAIPJ HQYFE BPGXM KOQPR PDCCL UIOTM POBBS OCQLP TLMMG MPEFC MOXWG XPNFL FGSQX RIZLA CCFZS CGJLF TNZHV GSLPQ NWQOR MCRPF USGCF KMUOE ZQVIU EKIXO UBQOE MAYLU IWHPZ NIMNK FFGYW OUOCR PHBZI QXWNJ BNXBD AOFRY WHLAC QFQFG XIKZT NODBW EUTGG GQUZM MNFDV BVJYW UIDHL DEAMN RANTN BQOEQ ZDTHR LNLZP LPHSF VRSAK YICRZ GFOCT UWZLZ APWNU NKJLY ZOQWU ETRHT IKWGA DJBCQ SXQXP INHDN XZFVQ TTKZT NWQQQ HNDGW LJZHV TYAQE OIYEY MYHLB PZTVT HAFYZ CYZZE RRIES WLIHA TFDRF YHPQH LTXGK QECIX VVBUG KKJXW FPWEX LHZJC AXHGT YXZMS NKKMN NFYRY QJOIE OYAGW RUUGI YMWQG MGUJD XKGYW DDZRA CGCRD KUICB GSITC PMWGJ TNDSQ GOCAC SLNZZ XQKOO IDWNZ KQMKY PGVPJ RVWMO KQFDI NRUIX YPWWD SMGHW YJOTM VOFKO LFCFG NJLVC KNTNW CEWWO YIPPR GAUER YQJUW CRLHR PTUEX HLZOB CMBVV WLJIV UYEEQ ETXBV KMYGH XBHFG GUISZ ZBXBJ IRTDK EVMQJ RBPRI PPVSK ZOMDZ RDNRT HVHHL OSEGB HXCVA WOABN XEAQS IQZDM BZLOM BEEWU IXLVZ VYOUS MXDXL AYZHB ASRJE DPXEZ BNWZZ GVTJR FDNCA CGQSU ILZJY HKXWA DRVTD JAOYG EPRNF UJHGF HSQWQ DIVHR XXWTL VJAAN NUTRP XEZBN WDFUO IDVWW YYPLZ DHBTG ISKKN XBETR UGELF WVVOB BUOMV DKJOA TRCEE RJTHP UKCOE ZYKCP OSSSK UBNHN QCHIX VLAYM ILQSA UKFZF RCMBD SUFRD SLEXH OSXQE IMGGM SZOMB OCHVQ THVUH LYOLU DKOQZ MYCHA CRPAS TXSZS ELZYL PCBVV WLJIO QNPDK FHTCJ WGADJ BCQWI QVMLT LLRDZ RSGPO JLAYN EDLZT VTHSS OAQBK MMQQD FPGYB DOLUM WFHRY SJPLN XEUPO ASFHB YNEKQ DVFTD PROZA RYYRV ZTISG MBDJQ FDMBP XJFIA CAOCE ESREI VLUIZ XRJEO PHHDC OMAOD AZSDV KZXNZ OQQVE SGFEW XPMMY FFFCX JZKVF ZWORG AUVKM XCHAC RPAST XSZSE PZNPG NNVUH HNTAP NEASE OSUKZ XMZYL LCVFT VMTTH XYOLD RRIES WMBZO XKDDP EXQJT AJDDT FVBRB LVXXO DBRGE SORWY GAQLF LXISH EELAY GEPRN FDQPT TTLVC CEAOS RXRFZ YYWKB SHFVH QUKYI CECQT OJWVD BGDPP UDRFE LVHRL LBOGQ EOAJZ EXMRE QFZNF ZFPFS HBRYY YNFZD VPMNJ PECDI HJWCI KNZNO NQVZX DXAMF JKHQK ILGRY WYHJX DPGER TBZTX LVPBJ XASTD RLKKN XBETR HPDBL HVZIF QBOOH LKZXL LRXLZ RTUEI LMIXW RQDTS QXFQK MWADS QZWHI ZGGUG PEMTG IYHGF TAJNC FDRHW UPJXU GEPCC HPYGE SMLZX EDFUW HMRKP BZJTC OUUKW XTMLB QOCIV HWQCD MBZKQ FDRBE FMIKU BBSEU FDGUK LRWGA XPSHJ UZEXG UWCRP DQSAY SWKUO AXRSA DMRRY NLXAY RDNAL UWGNH YPECR EDQQH AKYAR YYASH WUIWI IMPFL ZBPZX RIKYB QOQXB CGRFS KXNEK KHKFU SPFIL QBEAB BGTYK ALJJO PGALF VKEYS PSNRL PFHJC SDXXV YOMRS UJHHT IBUNX ETVAH UCXTH YSXQH NWGVX NMHBR XRUGO HFRJM IADFQ BANRD MLTAW YBZHR HWQKL AYMQP QHAOU ZIWKI MQSYP GVXIJ LKCIC LDORP DOIRY ICCKE FUSKU IQEYV OQFDI TIXMQ ZFWOK XMWCG CZKCO YCBKD NUCQH NLAPN KDFEC CQLLL BVZAG DDIGZ SZRKP JFPNR SCJIA XXAKO KZNTN DYLNA MAKDU GWHJF YXNCA OUHTI VKIQK HSLRL DTSHX VOBFG XBENI OIWSU XPAXX QAEOK UIQEI ICQGL EPHFS ZXZMC RPQIW SUEUX CNOQG KLMCU KJRFK RBNGZ GIQEL BUGSB AZNEG IMSOA MUIEU RVXCK GMBZH BYJTP VKISK DAYKA QETDH VFLCX OJYSC IGGXM KAGYO HDVHT HIAUV JJXLC TZRHG MGYIL DPDVG IYTKH HCEPR XPFYU MYKYE RDSFU SXDBS GXDIM PDSTK RRXUU BQOWQ GHTHK GMBZA AGSOS DXXBK ZBRVW ONBCE KKAIR YLLBL VULZJ RFBQK ETRRX HVUMY YKOAZ RSKHH TAAIW IZRGV TIRTH NVCBY STFOS XXGUL FOSMI SCEKT XYIWY JDTPH LRIGU GXXPQ YGTMY GAUYX LRGMP VLZJG ULXZA AEHJD ZLRMJ DBGRO VTEIX ZZCBZ POGWP CEGMM PNBUD CBPHR YOYMU ICQYO MRLLP CODKM RIHPL JNIHV CSYOV RTDKK HHVLL JKOYK YXTDC QJXOI VHWCZ CXCIY RQSOE ALJJK SAUSR TGZNB VKLQJ NOGDD BDRYY ZOMAO XMVBX DXSII GHLDK IHJWA JGYMB DTXYH GOZFZ NJYOY BKUJD XTZOM AOYOV DWUIW WXJYR KDNUY HJTAU LRXXU XSHFC SVYDP EYRAW GUCXZ YIWQP MYDWQ SWMQC EZFHT IKQOR AZBKO DUTBX VZUTH OXRRH CBPWU ZOAMB OPTBK IESJX UFEQW DTOQZ XMGAB QOYMF OREDH NNDJD CWPFT WWMGC MVYCQ GWBUZ SFBJL FLFTI CWAJY OWDVO NROQB VLHXZ YFNGE SKWES JAPJD TFJWA BJZXX NKJCL OSGOM LNAWW WTWRG IXZFD CICJM QEJOS SWZHV CVJUG AXWYL MYGHR QVHBV HPXKP NJXJF UWCWY WAUYL IYMNF FPIL
diff --git a/2019/8a.given.plaintext b/2019/8a.given.plaintext
new file mode 100644 (file)
index 0000000..2550142
--- /dev/null
@@ -0,0 +1 @@
+harryiputtogetherateamofwomenfromthecomputingdivisionhereatkennedyandwehavespentmostofthelasteighteenmonthscombingthroughmissionfilesandcomputerprintoutslookingformorecluestothesourceoftheoxygentankexplosiononboardapolloxiiiandithinkwehavefinallyworkedoutwhathappenedthetankcontainingthesourceoftheexplosionwasoriginallyinstalledinapolloxbutremovedformodificationduringthatprocessitgotdroppedsoitwasheldbackforfurthertestsandareplacementfittedforthatflightonceithadpassedinspectionthetankwasreturnedtoserviceandearmarkedforodysseyfurtherupgradeswerecarriedouttoallowittorunoffgroundpowerduringfitoutattwicethespaceshipvoltageandthehigherpowerwasusedtoboiloffexcessoxygenduringgroundtestsunfortunatelyitlookslikethethermostaticswitchesinthetankwereoverlookedduringthevoltageupgradeandourbestguessisthattheyfusedclosedduringtheboiloffallowingthetemperaturetorisetooverathousanddegreesyoumightthinkthetestengineerswouldhavenoticedthatbutsincethetankoperatingtemperaturewassupposedtobesomewherewellbelowzerothedialonlywentasfaraspluseightysonoonewouldhavenoticedoperatingthatfaroutofnormalrangeitisamiraclethetanklastedaslongasitdidandthataddstotheimpressionthatthiswasasimpleaccidentachainofeventsthatcouldnothavebeenforeseenbutthecomputerfilestelladifferentstorywefoundtwoversionsoftheupgradereportwhichwaswrittentodetailtheproceduresformodifyingtheelectricalsystemonthetankthefirstgivesacomprehensivelistofthecablingswitchgearandcontrolsystemsthatneededtobehardenedforthegroundbasedvoltageitlistseverycriticalcomponentexceptthethermostaticvalvesthisdocumentwasfiledintheservicerecordsoweknowitwastheofficialrecordbutthechiefsystemsengineerwhosigneditoffsaysthesignatureonitisabadcopyofhisownwefoundidenticalcopiesinseveralmissionfilesbothinthemanufacturersrecordsandatkennedywheresomeofthetestswerecarriedoutsoitisclearthatthiswastheofficialversionusedintheupgradethesecondversionappearedtobethesamedocumentbutitincludedthethermostaticvalvesonthelistofcomponentstobechangedandthetemperaturegaugelimitswerecircledseveraltimeswithanexclamationmarknexttotheeightydegreeceilingitlookslikeoursaboteurdeliberatelyarrangedforthetanktobemisconfiguredinanefforttocausetroubleforthemissionalthoughwecantbesuretheyrealisedhowdangerousthiswaswhenweputittogetherwithalltheotheraccidentsitisprettyclearthiswasanotherdeliberateattackontheprogramwefoundthesecondversionofthereportinaboxunderthefloorboardsinmikesplaceisupposeitispossiblethatmikehadstumbledacrossthedocumenthimselfandwasinvestigatingitaspartofhiscampaigntoprovethattherussianswerebehindthisstringofproblemsbutattheveryleastheisguiltyofamajormisjudgementandiftheastronautshaddiedhewouldhavebeentriedformanslaughterasitistogetherwiththeleakchargeshewillbegoingtoprisonforaverylongtimeofcoursetheevidenceisstilllargelycircumstantialwecandefinitelytiehimtotheleaktothenewspaperforensicsmatchedthetypewriterribbonandtypecharacteristicsonhistypewriterwiththeinkandimpressionsonthelettertotheeditorbutwestillcannotshowconclusivelythathedirectedorcarriedoutanyofthesabotageattemptsandwehavenotbeenabletofindanyoneelsewhohadbothmotiveandopportunitysoheisourbestsuspectiamnotsurewecanentirelyrelaxbutwithnosignificantincidentsonapolloxivtoxviandwithmikeincustodyifeelslightlylessworriedabouttheremainingapolloflightwearestilltryingtocrackthatotherenciphereddocumentwefoundinmikesplaceithasaverystrangealphabetwhichithinkmustbesignificantbuticantquiteseehowtobreakityetnowthatthenasacomputingexpertshavemoretimeiamhopingthatweshouldbeabletodecipheritandthatitwillshedsomemorelightonmikesthinkingmoreimportantlyitmighttelluswhatelseifanythinghehadplannedmeg
diff --git a/2019/8a.plaintext b/2019/8a.plaintext
new file mode 100644 (file)
index 0000000..23b9dbd
--- /dev/null
@@ -0,0 +1,45 @@
+harry i put together a team of women from the computing division here at kennedy and we have spent
+most of the last eighteen months combing through mission files and computer printouts looking for
+more clues to the source of the oxygen tank explosion onboard apollo xiii and i think we have
+finally worked out what happened the tank containing the source of the explosion was originally
+installed in apollo x but removed for modification during that process it got dropped so it was held
+back for further tests and a replacement fitted for that flight once it had passed inspection the
+tank was returned to service and earmarked for odyssey further upgrades were carried out to allow it
+to runoff ground power during fit out at twice the spaceship voltage and the higher power was used
+to boil off excess oxygen during ground tests unfortunately it looks like the thermostatic switches
+in the tank were overlooked during the voltage upgrade and our best guess is that they fused closed
+during the boil off allowing the temperature to rise to over a thousand degrees you might think the
+test engineers would have noticed that but since the tank operating temperature was supposed to be
+somewhere well below zero the dial only went as far as plus eighty sono one would have noticed
+operating that far out of normal range it is a miracle the tank lasted as long as it did and that
+adds to the impression that this was a simple accident a chain of events that could not have been
+foreseen but the computer file stella different story we found two versions of the upgrade report
+which was written to detail the procedures for modifying the electrical system on the tank the first
+gives a comprehensive list of the cabling switchgear and control systems that needed to be hardened
+for the ground based voltage it lists every critical component except the thermostatic valves this
+document was filed in the service records owe know it was the official record but the chief systems
+engineer who signed it off says the signature on it is a badcopy of his own we found identical
+copies in several mission files both in the manufacturers records and at kennedy where some of the
+tests were carried out so it is clear that this was the official version used in the upgrade the
+second version appeared to be the same document but it included the thermostatic valves on the list
+of components to be changed and the temperature gauge limits were circled several times with an
+exclamation mark next to the eighty degree ceiling it looks like our saboteur deliberately arranged
+for the tank to be misconfigured in an effort to cause trouble for the mission although we cant be
+sure they realised how dangerous this was when we put it together with all the other accidents it is
+pretty clear this was another deliberate attack on the program we found the second version of the
+report in a box under the floorboards in mikes place i suppose it is possible that mike had stumbled
+across the document himself and was investigating it as part of his campaign to prove that the
+russians were behind this string of problems but at the very least he is guilty of a major
+misjudgement and if the astronauts had died he would have been tried for manslaughter as it is
+together with the leak charges he will be going to prison for a very longtime of course the evidence
+is still largely circumstantial we can definitely tie him to the leak to the newspaper forensics
+matched the typewriter ribbon and type characteristics on his typewriter with the ink and
+impressions on the letter to the editor but we still can not show conclusively that he directed or
+carried out any of the sabotage attempts and we have not be enable to find anyone else who had both
+motive and opportunity so he is our best suspect i am not sure we can entirely relax but with no
+significant incidents on apollo xiv to xvi and with mike in custody i feel slightly less worried
+about the remaining apollo flight we are still trying to crack that other enciphered document we
+found in mikes place it has a very strange alphabet which i think must be significant but icant
+quite see how to break it yet now that the nasa computing experts have more time i am hoping that we
+should be able to decipher it and that it will shed some more light on mikes thinking more
+importantly it might tell us what elseif anything he had planned meg
\ No newline at end of file
diff --git a/2019/8b.ciphertext b/2019/8b.ciphertext
new file mode 100644 (file)
index 0000000..1bbf100
--- /dev/null
@@ -0,0 +1 @@
+FBGAI AGCFE KEFEK CIAGC FCGAF CIBHD HEFCF AFBFA GDFCH DFEKC IAKCI BGBGC IAHAF EKCFA KAIAG CFBFA GBFBI AFBHE IAGCK CIAFC IBHDF EGAGA FCHDI AHEIA FCKDF CFAIA KCFBF AIAGC FEHEF CICFB FEIAH EFDKA HBHDF CIEKA IDKCH DHEFB HEKEF CFCHA FEKEK CHEHA KAGEF CKCIA GCFBF AGBFC GAIAG CFEHE FCICF BFEIA FEHAH BFBHD FEIDK CHEHE IAFCG DFEKE FDKAG CFBHE KEFEK CIAGC IAGCF EIBHE HEHDG AFEFE KEHEF CFAIA GCFEK CFAGB FEHDI AGCKC IAIDF EHEIA FBHDI BHBID FBIAG CFEKC KDGCI DKCHD IDFEG AFBGB GCIAF BFAFB IAHEH BIBHB HBFEI AHEIA KCIAF EHEID FEGCK CICFE IAHDF BFEKE IAFCK DFCFA IAKCF BFAFB IAFDI BIAFB FAFCI DHDFE KCGEF BHEFE IAGCK CIAID FEKDK CFAFC FAGEK AKEFE GAFEK CIAFB IAIAG CFEID KCKAI DFEGA FCIBG BGCIA GAKCH EKDFB HEHAF DKAIA KCGDF BFAGB FCFAF BIAHE HAFBG BGCIA FBFAF CHBFE FAIDK CHDFC IBHDH BFCGE FBIAF BKDFB KCFAH EGCKC ICFEH EGCHD IBFAG DGAHD FCHAI AGCFE KDFCF AGAGE FBKDI AKCFA KEIAG CFEKA FAFEF EKEKC HDFEK CHEFC FAIAF CKDFC FAGAH DFCFA IAIAG CFEFE ICFBG EFEIC FEFAI AGCFE IAGCH DFEKC IAFCG AFAIB KDGEF EKCHD HAFBH EHEFB GEFEH EFDKC HEFEK EFBFA KDIBF DKCKE FBKEF AFCIA GBFBI CFEIA GCFEH AIAGC FEHAF EIAIA GEFEI AFCGA FBGBG CIAFB FAHEI AFEKC KEIAG CFEKA GCKCI CFEKD FCFAI CFBFA KDFEK EIAGC FEHAH EFEGE ICFEH EIAGC KCIAI AGCFE HAKCK EKEFC KDIAH DFBFA FEFCG AHAIB IAIBK CGEGE KAKCH EHEIB HDFEK EKEFE HEIAH DIBKD IAFBF CFAID FBGEG EHBHD FCIAF EKDIA IBHEK CFAKE IAGCK CIAHB FEKCK DFEKD KCFAF DFEHA KCFBF AIAKC FBFAF EKEIB FAKEF EHDIA GCFEH EGCFE GEIAF EHDFC GAIAG CFEFA IBKDG EFEKC HDIBH AFDHD FEGEG EKCIA GCFEK AKEFC FAFCI AHEFE FEHAI AFCHE FEFEI AGCKC IAIAG CFEGE FCFAG BFEHD IDFEK DFCID FEHDF BFAIA GCFBH EHEGC KCKEF CIDIA GCFEH AFCHD FEIAG CFEIA IDFCH EFBKE FEHEI DFBGE GEFBF AICFE HEIAF BFAIA GCFEH EFEKC IDGAI BGEID FEKCH BFCFA HEFDF EGAFC HDFEG EFCFA GBFBI AIDFB GEGEF DFEFB HAHBF CHEHE FBFDG EFEIA FCGAF BGBGC IAKCI AKCGE GEIDF BIAGC FCIBI AIAGC FEIAG CHDFE KCIAF CGAIA FCIAK CGEKC FAFAF BGCFB GEKCI AFBFC FAKCF AKEID GCFEF AIAGC KCIAK EKCKA KDFCH AFEHE IDFEI DFBGE GEKCG EGEFD FEFEF AHEGE KCICF EKEFD KAIDG CFCFE ICFEH DFBHE HAFCH DFEHD IBIAG CGEFE HEHEG EFCHE FEKCF AKEID FEIDF BGEGE FDFEI AGCFE HEGEK CICFE HEIAG CFEHB HDFBK DFEFC GAIDF BFAFA FBFAG BHAFB GBGCI AFDFE IDFCH DHEFE KCIAG AFBHD HEIAF BGCFC HBFEK EIAGC KCIAI AGCFE HEHBK CKDFE HDKCK DFEID FCIBG EKEGC FEGEH BIBHE IAIBH DFAFB FAGBI AGCFE HAFBH EHEFB GEFEH EGAHD FCHAI DFEKC HBFCF AHEFC GAIDK CHDIA FCKDK CHDHD FBFEH DHEFC GAHBF EKCKD FEKCF AKEGD FEFAF AFEKE KAHEF EFEHA FEKEI AFCGC KCICF EIAGC KCIAF BFAHA FBFAK EIDGC FEFAG CFEHE FEIAG CFBHE HBHDF CGBHD KCHAI AFCGE KCFAK EFCFA IAGCF EHAFC FCFAF DKAID FBFAF AFBFA GBIAG CFEHE HBKCK DFEHD KCKDF EIAGC FEKCK EHAFB FAFBH EIAHD KCIAF BFCFA GCFCH BFEKE IAFCF EHEIA KCFDG EFBHE GCIAG CFEHE IBHBH DFEHA KCKDK AFCGA IAGCF EKDKC HBFBI AKCGE FBHEI AHEKA HEIAF EHAFC ICFEH DKDFC HAHAI BFAFB HEHAK DFCID FBFAG BFCIB HDFEF AFEHA FBFEH EKCFA KEHEF EIAIA FBFAG BFCIB HDGCF EKCHD IAHEK CFAKE HAFBF AKEHE FCFAI AGCFE KDFCF AHCIB FEHEI AFCGA KCFAF EIDGA HDFCF AIAFB FEHDF DIBIA FDHDF EKBGC FAFEI CHEFE FEHAH EIBFA KEFEI AFEHD HDFEK EKCFA KEFEI CFEFA FDFEG AFCHD FEIAG CFEGE KCIBF AKDGC FCGAK CHBFC GEGEF CIEFB IAGCF EKCHA FEHDF BKDKC FAHBI BFDGE FBKDF BHEFD FEGBF BFAFA FBFAG BIAFC GBFEI AFDFC HDFEK EIAGC FEIAG CHDFE KCIAF CGAFA IBKDG EFEKC HDIDK CHDFB HEHDF BHEFB FAGBK CFAKE IAGCF EHBFE KCKDF EHBHD FCIAF EHEIA HEIDG CFBKD GCKCH DFEFB FAIAF EFAKE FEKEI AFCHB HDFEI CFEFA IAFBI AKCHD FEFEF AKDFC IBHDK CGBFB FAGBF CIBHD FEFAF EHAFB FEHEI AFCFD FEGEF BFEIC FEIAG CKCIA IAGCF EKAKD KCFAI DFBFA IDKCH DFBHE IBFAK CICFC FBKEK CFDGE FEIAF CHEIB HDICF BICFE FBIAI DFEHA IBHEI AGAFB GBGCI AFBIA FAFCI DFCFA FCIBH DFCID FAIAF EHDHA HEFDF EGAFC HDFEI AGCFE FAIBK DGEFE KCHDK CHDHE FEFAK CGEHE GBHDF CIDIA FCFCH BFCID FEHDG AIBGE FBGAF CIBHD GEFEK CKEFE HDHEI DFBGE GEFAF CIAKC KDIAF CGAIA GCFEF BHDFC IDFAI CFCGE FBIAF BFCFA IAGCF EFAFB IDFBG EGEHB HDFCI CFCGD FEIAG CFEHD FEHCI BFBHD FEKEK DFCFA GAHDF CFAIA KCIAF BFCFA FBIDF BGEGE KDFCF AICFB FAKDF EIAGC FEHAI AGCKC IAIAG CFEHD IBHEH EFBKC FAHEG CKCIC FEHEK CFDFC IAKCG BFEKE IAGCF EGEIB FAKCH DHBHD FCGBH DKCHA KCFAK EGDFB GEGEF EKEFC HDKCI AIAFE HAHBI AFEKE IAFCG DFBGE GEFCI BHDKC HEIAH DFCFA KCIBI AHEIA GCFEH DIBHE HEFBK CFAHE IDFBG EGEFA FEICF EHDFD FEKCF DGEFE IAFCH BHDFC ICFEI AGCKC IAIAG CFEKA KCHDF EFBFA FAFCK DFEFA IAKCF AKEFC IBHDH BFCGE FBIAF BKDFB KCFAH EKCFA KEGBF EFAFE HDKCG EHEID FBGEG EFDFE GAFCH DKDFE KEIAF CHEIA HDFBG DFEFD KCKDG DIAGC FEHDI BHEHE FBKCF AHEID FBGEG EFEHE KDKCG EKCIA FEFBF AFCHD KEFEH DIAFC FAFCI AGEFC FCGDI DFEKC GDKCF AKEFC FAKDF EIAGC FEKAG CKCIC FEKDF CHAHA FBIAI AFEKE IAGCF EHAHE FEGEI CFEHE IAGCF EHDFE IDFBG EGEFD FEFAF CIAIB HDFAF BFAGB FDKCK DGDIA GCFEI BFAKC ICFCF BKEKC FDGEF EIDKC HDIDF BGEGE GCKCI CFEIA FCFDF EGAFC IBGBG CIAIA FCFBI AHEKD FCFAK DGEIB HEFBF CFA
diff --git a/2019/8b.given.plaintext b/2019/8b.given.plaintext
new file mode 100644 (file)
index 0000000..a23954a
--- /dev/null
@@ -0,0 +1 @@
+ifthedeathofoursoninkoreataughtmeanythingitisthatoureffortstocontainthesovietsbyproxywarsisdoomedasmyloathingofthesovietempirewasstokedbyhisdeaththeussrfeedsontheangerthatwestirupwitheachwarwefightinitspuppetstateswehavetriedtocontainitbutinowrealisethatwecanonlydefeatitthewaywefoughtfascismbytakingonitsmightinopenwarourpoliticianshaveshrunkfromtheconflictandtheyneedareasontoconfronttheevileventhethreatofnuclearmissilesbasedincubadidnotgivethemthemettletofightinsteadtheyhaveconvincedthemselvesthatthemaddoctrineofmutuallyassureddestructionwillprotectusandthatpeacecanbemaintainedundertheshelterofthenuclearumbrellatheydonotseemtoseethatthelongerwecowerinthisshadowthemorethetwosideswillinvestintheseawfulweaponsbeforelongitwillbeimpossibletofightatallwithoutthethreatoftotalannihilationandwhenthatdaycomeswewillallbeenslavedbywhoeverismoreruthlessloseandwewillbetheslavesthepriceofwinningmightbeworseatfirstihopedthatthespaceracewouldhelpusturningthemissilesfromweaponsofwartocarriersofpeaceandkennedyseemedtohavethatinmindwhenhesethisprogramtolandonthemoonbywinningthespaceracetheadministrationhopedtoestablishthesupremacyofthecapitalistsystemovercommunismcowingourenemiesandsettingourheartsandmindsontheconquestofanewfrontierbutbrezhnevseemsundeterredandevenbeforethelaunchofapolloxitheamericanpublicisbeginningtogetboredthethreatofnuclearwarisrisingandthepeaceprotestswhichareintendedtopreventitareencouragingourenemiestobelievethattheycanwinwarisunavoidabletosurviveitwemustfightitnowonourowntermsbeforethenucleararsenalsgrowtoopowerfulifourleaderswillnotactoftheirownvolitiontheniwillprovoketherequiredconfrontationiwillconvincethemthattherussianshavesabotagedthelunarprogramandkilledorattemptedtokillourastronautstherussianswillneverbeabletoprovethattheyareinnocentandourpoliticiansandgeneralswillbeforcedtostrikebacktherussianswillescalateinordertonotlookweakandoncetheyhavecommittedthemselvestherewillbenoturningbacktheunavoidablewarwillhavetobefoughttoitsconclusion
diff --git a/2019/8b.plaintext b/2019/8b.plaintext
new file mode 100644 (file)
index 0000000..1d7506a
--- /dev/null
@@ -0,0 +1,25 @@
+if the death of our son in korea taught me anything it is that our efforts to contain the soviets by
+proxy wars is doomed as my loathing of the soviet empire was stoked by his death the ussr feeds on
+the anger that we stir up with each war we fight in its puppet states we have tried to contain it
+but i now realise that we can only defeat it the way we fought fascism by taking on its might in
+open war our politicians have shrunk from the conflict and they need a reason to confront the evil
+even the threat of nuclear missiles based in cuba did not give them the mettle to fight instead they
+have convinced themselves that the mad doctrine of mutually assured destruction will protect us and
+that peace can be maintained under the shelter of the nuclear umbrella they do not seem to see that
+the longer we cower in this shadow the more the two sides will invest in these awful weapons before
+long it will be impossible to fight at all without the threat of total annihilation and when that
+day comes we will all be enslaved by whoever is more ruthless lose and we will be the slaves the
+price of winning might be worse at first i hoped that the space race would help us turning the
+missiles from weapons of war to carriers of peace and kennedy seemed to have that in mind when he
+set his program to landon the moon by winning the space race the administration hoped to establish
+the supremacy of the capitalist system over communism cowing our enemies and setting our hearts and
+minds on the conquest of a new frontier but brezhnev seems undeterred and even before the launch of
+apollo xi the american public is beginning to get bored the threat of nuclear war is rising and the
+peace protests which are intended to prevent it are encouraging our enemies to believe that they can
+win war is unavoidable to survive it we must fight it now on our own terms before the nuclear
+arsenals grow too powerful if our leaders will not act of their own volition then i will provoke the
+required confrontation i will convince them that the russians have sabotaged the lunar program and
+killed or attempted to kill our astronauts the russians will never be able to prove that they are
+innocent and our politicians and generals will be forced to strike back the russians will escalate
+in order to not look weak and once they have committed themselves there will be no turning back the
+unavoidable war will have to be fought to its conclusion
\ No newline at end of file
diff --git a/2019/9a.ciphertext b/2019/9a.ciphertext
new file mode 100644 (file)
index 0000000..76f35bf
--- /dev/null
@@ -0,0 +1 @@
+VXZAT CEALG YPEVM XJTIN XYOXG NJNDI FAWXS TWAPY GXMTI UHCMY XZEFU DVBTS EPFWR HKYRB HNEEK OYAPF EEPSR SQYNT ANXVK CMTYL CAIXS XBXRF PAGNW YIIZT WKMZO NUXXU UXMIH YGSIK LGTDA XJNPH FGXFB TPTLA TNQNX LBPJB QDLEY GVSFP FPWBG SAOIP OTTXZ EEUNG KNGGA IJXRR PZEVG HYKFZ CAIYR VFPLG PWBTV OEPWG IFSPV OHGVC CIDIW BNFMN WUHXA WWCPP YSXRJ PHCLF RFQCW RYXQM SSEMQ LWLGA AGTMV RKXIU HDIFG DDIQJ IUHUI AZGXT VUHRK IMMMZ STUOO POGCX YTPIM RMSSC SLAPC ETLXH PGEAZ IYAKO VGQTP XVYLT DGTCI HEJTE YOZZR BQTGG SOTUS ZXVKH MIWUB RXJIK WUHGS OYUAX HAOBE LEYBE VUXHP APTVP VCMJG RJPHI HKNFW YWPWH WTDNV EQJKE SWTSO GNSCX SQCAP HHLCE YGLZC GFIXT PTINX FMTOZ FTDUP WPOAP RGDEY AMXIJ GTPBX PSTUA MKCAL SATUT QCHRH PMVGD DAEWP VTSEV PIZAB KLGTD IFVPO NUEIE HPHXD WEOKK VRQXZ KWDOE FAHRT DLMLK GALTY BTXCM ACFCQ KVVSW TXTWH AWZRV YREUW XOEXD EPMTH XZLFT PMMYT GEGMW PHFZX VKSAL PPFMM RFBFE IALEF ONSQR VIDIO GVMMX IACTQ HKLDA ZLEZO TTDFR BSWRP BDPIA LXZRR DPNQP KSZMV NWJRB ZBSKX ECOBW VRVID IGBRC MXMES IJTFZ ZSWMI UHIFI WXUSB GLGFT XYSYZ OEVRN RTKSG XESIC IPBPV TWWNY FAVHQ TSVPA FRMTK VOEQT UPNAQ HLGWL GRTMR EUJIG FPXLV YLAQJ SXBXD ITWAO AXIUF TXYSE QEXWL FCISI QBAAU KLGBX WXACC OIWLG VIIAJ EGCML VRDHX BXSNI TOIEK PYXTK BHBAE FBDTT WHNIY GXNYJ ELEAG IEMRV YGSPW OLRFJ IURTN VLXYE PYCYH CEVAQ TNSAW FHWGM WYBLT UTNFT MEJLP ETLRB KPSIH XTABU FNGUS MJZDE TLXHC VNMJK EAKLS RZQEI SNPTU MUFOL OLHKR EVOKA SCELS HPHEW QQZDT CPAGD VGOHS WXGAP NIHJI FMIIV FVRSM NXBHT OHHDT TZWAR VHEVP AJSEU RXSCS HFOYA DWLAS TSXZG RVINC RVICT KPOIE WXNHH SIGBG ATKVE SWXNT ZRAEJ ERMCE ZPERS ICXNV ICEAX LFXSR VUXRS CXURI KRRPD XLWEL TEWLG CIKGL UTNQB SZGPA XZDXE TLHYC IELDR EEDUG RFLSE KLPKU DHRAT EWETU WZKXS OHATD YTRQZ LGWLE ZTEBT BTIJS WWLMP STALO POQDI GHZES OQASW AWFLO EUVRB GGELC XGFIT ABRZE XJMLD MZIUG NAWDW AEQXJ ESWIF ELCGA JTSCV NMWER PANWV ZVRXW SESQK YBHHE JTGNM MNXQB PLLAW RNQGW YOHII QBJSM QMZSU MPKPV IYLYB PPSIT KVUYT IRRPQ WFLWO BJIGB XHXTP UCCUX AWISZ AZDEP AVCFT HVZYR GVKZR FCMLV ZRETL CORTL PTDRR MCWAC HILGS HNQWY DSWTW LLHOU GJFOL IAKOL IXAIU HCIIM HVNBA SOOTX HJHCE YGLES GAIWV RLBZM YOIIZ GEYAS WFFUC ILEXO OQTVR VEMVG EDERA RNATH XCHSD ZUALS ZIALS EIIJI UHTGS EMNHB MRVHI YIVPT RDSQF OLEOT FGAPZ IZRTH GAXPR QNEUR AUSHM VPWZI UHIEG GDCUA WWNFW PISMQ EKOXB BTZTZ OWUAZ WVGTU PNKBF GRPHT TVTUP COYFM NUPTM OTRRQ SMUMQ RXLET RIKEJ CISIQ BAAUK LGYCM ALEYO PASFS COJZX FOXYM QCIIF AEPKU EIIWV TROBQ EEJRN SSMAG EJKXM FQBPG MMHBT AOVRH XVPWA JTMJI UHXEW PGVHK GQNGP RXZEQ OKFEU QIAQE GBDWZ WRTXR TEPST ZGIPO UETJM QNIQR VSWXX KLNYZ SRVRC AQTAE ONKTL HDXRJ LEEDU IFOSA LPARR MNXXF DAMSY PVQJI GWGWI ARGRM NXBBP RHETS YNFIG HXRAR GVHBE RNRCM YLYOL GGGGI QSIWB SEPZL TIDVA LOPKA GPVFT TMCPR PGZWR YXQGG OPCGV SEDIO RDTJO BYISW CEFWS EEHAW HZRNS NXEAA ZPHGT VXZED TEWXR VINYC HGMMN XGCVH GSJPL SFEYC IRIGH GIBTI FWTOT LDTMQ ZXQSH IPLXE IAGRB CHWTL TVCQZ GBHTN SPFBS SYEBH ISZJZ QIFSL GHCEX YHPSB OKAWH CESYL DZSVR VEIGP AGGVO OPOGG ALTHP GFIXO IOWDT JIAYI HUXXG WXFCA VIUHC OWNBF NMXSS HJSWW TCRMU VRJTN IHMHB BOHRG HMFWH HOTOS AYINS OBXOW RVRVI SGSVZ OFVRN CISIQ BAAUK LGHJS ZMOTE DWLGH DGMYX UWWYW ESIVT MBOAQ ZSGYR AFJTJ EPZRB HXXNG MLYDJ SJCID IFGVT VUGVH JFPWT GRQLR VSWTJ ZMHOM XSZUC MALJY AFWKG BSIHT ZAIPZ IZCHK GAOTH ESARV VNMWX RFMNX GCVMW FLNIB GXRVI FJZXZ RMKXF CIHKS SRNUQ VGMAE XTGVF MJWNK TLMMM EIFMS OOLER VXJWM TORVD WMJFZ CZAXH CSAIC GREJJ EUHXS MKPQI ZSQRV ITYZU NMQNH RYHEW FLCEP JEURT SWPKC IAYIE DTLMG ECEFL IYSWT XYXFE PYXVA SEXZS RUAZX FHCEH TVPAM NXQSA PTUPS TMZAU HXWSO HGGVO LGCCH TZPSS YAEYQ ALMEL RHMXI UHHEP AJSWF MSRFJ GMQHG GVUPZ WWIDS EENPA HGWSN EENBB IQPNH DXMGW LEHSL GBSIH PPGUJ YVBHX WBNJY AYKXR UTHOY BUTBT SQWTQ XWDZT PWWNS APHPF REAKL NGPRM SRYIW JSJZA IXDLN WMNRR VLOVS MYOUL SZBXG RTAGE UUWGS HIOSS ENPDY BQTHX LAGTV KHVTC SVQWP TQDTZ CRTSY LNWQO MILDP EGALN AEIYP DRTYH VTIFM EIHWX JAVNM LIUHG EXQTF UZUJF SHMKH CFSDW ZBHUE PJGNE DGLGB SMWWS PRGKI XOBDR LXXIU NXVKC MDUPS CALER RXDSZ ZNEJJ PHCLX BLSRU AZXVD JGRTF BCVUM FGXQS MJZSA DPBDP ELEYB HKTYN ZTLMZ ETWKJ VNV
diff --git a/2019/9a.plaintext b/2019/9a.plaintext
new file mode 100644 (file)
index 0000000..3dc20f3
--- /dev/null
@@ -0,0 +1,43 @@
+harry with the launch of the apollo soyuz mission coming up i thought it would be a good idea to
+check in with mike and make sure he didnt have any leftover surprises for us after the tank
+pressurization problem on apollo xviii was not completely confident that he couldnt have set
+something in motion back when he was still working at nasa he seemed pleased to see me i dont think
+he gets many visitors but we didnt have alot to talkabout and it didnt take him long to figure out
+why i was there he still claims he had nothing to do with what he called the accidents though he
+admit she sent the letter to the press i pressed harder and asked him about the manifesto it had
+been readout in court so he knew we knew about it but he was definitely trying hard to steer me off
+the topic and i got the feeling he was hiding something i didnt get anything more out of the
+interview but i continued to worry about it on the wayback to headquarters so when i got there i
+dugout the manifesto and took another look i dont know how we missed it but we never carried out
+forensics on the document i guess i was so taken up with cracking the cipher and analysing its
+content that i forgot to ask someone to check it as soon as i realised the mistake i sent it over to
+langley and got them to run the tests the results are conclusive the manifesto was not produced on
+mikes typewriter i looked through the files but couldnt find anything written by him on another
+typewriter even at work there he had a secretary to type for him and in any case the ink and
+typeface on the manifesto dont match any of the nasa machines either a typewriter is too big and
+bulky to hide and we didnt give mike time to dispose of one so i dont think the manifesto was
+written by him i read it again more carefully for clues i should have noticed the phrase our son at
+the top it would have reminded me that mike was married putting that together with the keyword for
+the manifesto cipher niobe things began to get a little clearer homer wrote about niobe in the iliad
+she was famous as the queen whose sons were killed by the gods in revenge for her pride so i got in
+touch with interpol and made enquiries about mikes wife mikes wife is also english and the manifesto
+uses the english spelling of programme her friends says he had a breakdown after her son died and
+when mike moved back to the us she went to live with her in laws after what seemed like as low
+recovery she told them she was moving back to the states to be near her original family that was
+eleven years ago but her relatives stateside say they have not seen her and no one knows where she
+went i spoke to the security service in the uk and they told me she was an engineer who was quite
+capable of carrying out the sort of sabotage we saw on the earlier apollo flights significantly she
+learned her trade working with the uk atomic weapons authority aw re which fits perfectly with the
+worries in the manifesto she left after her son died in korea and started meeting with peace
+campaigners her security clearance was revoked and soon after that she left the uk soon after i
+received the report from london i took a call from the apollo soyuz team at nasa someone reminded
+them about the problems we had with the lunar flights so they called me back into audit their
+security i found a trail of edited service records that reminded me of the tampered files associated
+with apollo xiii the files were all scrambled using keys that came from homer apollodorus and other
+greek classics so far we have cracked all but one of them and found and fixed problems with guidance
+control life support and electrical power but there is one file icant crack without it we dont know
+if there is some other critical system that mikes wife may have tampered with she failed to provoke
+america into declaring war on russia three years ago but the peace is still far from easy if
+anything happens to the crew of the as tf we might find ourselves on the brink of war again with
+stafford brand and slayton scheduled for liftoff in the next few weeks it is crucial that we break
+this cipher
\ No newline at end of file
diff --git a/2019/9b.ciphertext b/2019/9b.ciphertext
new file mode 100644 (file)
index 0000000..8a2c245
--- /dev/null
@@ -0,0 +1 @@
+11101 00101 00001 21122 10001 10111 00101 10001 01111 00210 11011 11111 01011 01001 01011 21001 11000 01011 01000 00012 21222 10011 11010 01000 01001 10201 00000 11101 10010 01011 00012 00212 00011 01000 01101 01110 00000 20021 10010 00100 11010 11011 00002 10000 10000 11010 00001 00022 00110 00101 10101 10001 01100 00210 01111 10010 01001 00000 10111 02020 00101 00101 01001 11000 01022 21210 00001 00110 10101 00010 21020 02111 00100 00110 11101 10000 21012 01110 11001 10011 00000 10021 10011 01101 01100 00011 00002 10011 11100 10010 01001 00101 10020 00021 00001 01010 01010 01001 10002 21011 00011 10111 10000 00120 12102 01001 10001 10010 10110 01021 02011 01111 00101 00000 10001 10022 20000 00100 01010 01100 01110 21021 00101 00100 11101 10000 21002 12111 10100 01100 01011 10002 01202 01010 11001 00010 01111 00011 00101 00010 11110 10000 00012 01122 00111 00001 11110 10000 00021 12210 01001 10100 10100 10010 22002 00001 10000 01101 11101 00100 21001 01000 11110 10000 00001 01202 20200 00011 10110 01000 01002 22100 21101 11000 00100 01110 00200 12011 00000 11010 10010 00111 10221 00100 01010 11110 10001 00102 21220 10000 00110 10100 10000 02100 22101 00000 11010 10001 01012 00200 00100 00001 11101 10100 01021 10001 00010 11000 11010 01101 02111 10001 01110 11001 00000 01002 11002 10110 11110 10011 11011 01000 00210 00010 11101 00110 00001 22221 20000 11010 00110 11100 00100 02210 01101 10000 01100 01011 11122 10001 01101 01000 00110 10021 10021 10101 11100 11101 10110 01021 20010 10010 01110 11101 00100 21220 01010 00011 00010 00100 11010 12201 00100 10011 10000 11000 21112 00111 00011 10010 00100 00001 20010 11101 00011 10000 11001 01112 00211 10011 01011 01011 10001 10200 21100 10000 11010 00001 00020 20010 01111 00111 11001 11011 20112 10101 00111 11010 00100 01001 12202 11100 10100 00100 01001 10002 11010 11110 11010 01100 00002 00202 00100 00110 01011 01000 01200 02111 11101 01001 10000 00100 20001 20001 11101 00011 10000 11001 01112 10011 10000 01110 10010 10021 10101 11111 11001 01000 01011 11002 11110 11110 10101 10110 00021 02220 11100 11010 11000 01000 00202 01100 00100 11011 00111 10021 00200 11000 10100 11000 00001 12020 20100 01110 11001 01100 01011 11002 11110 11111 11011 10101 01001 10220 11100 01010 00100 01001 02002 11101 11110 10011 00100 00021 12122 11101 00001 00011 00000 00100 02211 10110 01001 01101 00101 20020 21011 00010 10000 01101 00211 00211 01011 11000 11011 10000 10002 11101 10110 10110 10101 11000 21000 01110 00001 10011 10100 10021 01101 00011 00000 01101 11000 20001 20101 01100 01110 10000 10002 22221 10000 00100 10101 00100 21022 12110 10001 10000 01001 11020 20000 01010 11111 01100 00100 12100 20000 10010 00000 00101 01100 21001 21000 10010 00111 00001 10012 21001 00110 11100 10110 10000 11002 10111 10010 00011 01000 11000 02102 10111 00011 00110 11100 02100 02111 01101 00101 10001 01111 00210 01011 10010 01111 01101 00000 21100 01000 10100 00110 01100 02200 02001 01101 10100 01001 11010 21002 01110 10000 00101 01100 01001 20100 10010 11111 00101 00011 21122 00000 00100 00000 01000 01120 20001 01101 10110 01000 00010 02110 02101 10111 10100 11110 11010 00002 10000 10110 01111 01101 01000 21101 00000 00101 01000 10001 22002 20100 10010 01001 01100 00000 00021 11101 01001 00001 00110 10020 02111 00100 00001 01011 00010 01201 00100 10001 10100 01100 02210 00201 10010 00100 01000 11002 22000 20100 11010 11010 00000 01111 01000 11001 10010 00000 01100 00202 02010 00110 01000 00010 01000 22112 01001 11111 01010 00000 01200 02110 11101 10100 00100 11102 22001 20000 00010 01000 01010 10202 00000 11011 00111 00001 10010 11120 02111 00110 11100 10100 11011 12022 11001 00110 01000 11001 12100 20201 11010 00110 10011 00001 02002 01001 00001 10001 00011 01202 00100 11111 01001 00001 00010 20022 22011 00010 00010 11010 00000 00200 11110 01100 01011 11000 02012 21001 00001 00010 00100 01100 00202 01010 00100 00110 00001 00200 12221 01100 01011 00001 00100 00211 22110 10011 10011 01110 00010 00211 10110 11010 11110 10111 00021 01001 11001 10100 01100 11001 12112 21100 10000 10111 10010 10002 02221 10000 00100 10000 00110 22121 00011 00111 10010 10000 10121 10021 01101 11110 10001 01101 00211 00201 01011 01001 10011 00001 10020 01111 00001 00000 01101 10110 20011 10101 11101 00100 01010 22200 00101 01110 00011 10101 00100 21201 01110 11110 10010 00101 11220 00210 10110 10000 10011 01000 00212 01001 10100 10000 00111 01110 02201 11001 10111 01000 10000 00121 20111 00000 00010 11000 00002 20011 10101 01000 10100 01001 12212 21001 10110 01001 10100 00000 01121 11100 01110 11010 10100 01111 21201 11011 10101 00000 00100 02100 00100 11011 01110 00101 00020 01101 00111 00001 10000 10000 01021 11110 01011 10110 10100 00012 00112 00010 00000 11100 00110 01011 12000 11100 10110 01101 11001 21000 21110 11001 10010 00000 00120 00000 01011 01001 00010 10000 12120 11011 01111 01010 11001 00010 00000 11101 01001 10101 01000 10122 20021 00011 01110 01101 00001 11200 01100 01110 01000 00111 00020 12020 10001 10011 01000 10000 00222 21210 00110 10000 01110 11011 02001 20011 01011 01111 01011 01212 10010 11101 11001 00101 01010 10200 02111 01101 01100 01011 00012 10012 11100 10010 10110 01101 02202 11100 00111 01100 01011 00012 10011 01101 11100 10011 10010 01012 00220 11110 01000 01101 10100 00021 21100 11010 01011 00010 11110 02100 10111 00100 11100 11010 00002 10200 10010 10110 00000 11102 00201 20010 10011 11100 00000 01211 00000 10010 10010 00101 00001 21201 10110 11110 11001 11000 01002 00020 00101 01000 01001 10100 00021 20100 11011 01010 10010 01011 00000 01111 01001 01011 10010 01000 01221 10111 00100 11100 00000 22110 12000 11101 11000 00000 01011 21112 10000 11001 01000 00110 01120 22200 00001 11010 00111 10011 00221 11000 01101 01111 00011 00212 10011 11101 11101 00100 01010 22212 02011 11101 00011 00000 00021 20221 11000 11000 11000 10000 02002 11001 10110 10110 10101 10110 21021 01110 11110 11011 00000 01222 00220 01100 00100 11000 00000 22110 12000 11111 10011 01110 00010 00211 10110 11010 11010 10110 10021 02101 11011 01011 01100 00000 22200 21001 10001 10000 10001 00020 12210 01001 00100 00101 00100 12211 21000 11111 10100 00100 11122 22001 00000 00010 10110 00110 12221 02000 11100 00010 10001 00012 20012 00110 11101 10010 00000 10021 10021 01101 11101 01011 01100 10210 22101 11001 10100 00000 11020 02000 11000 11000 01000 10011 02001 10210 01101 00001 00111 00110 00120 20101 11000 01011 00010 01101 10211 01100 10000 00110 00010 02202 11101 00001 10001 10000 01112 22210 00001 10011 00011 00010 10201 01100 10011 11000 10000 01012 00000 00101 00001 11111 10101 00021 01101 00111 11110 00110 10000 10101 12011 11000 00100 00010 00101 12220 01100 10001 10001 10010 01021 01000 01110 00010 01001 01001 10200 20100 11000 11011 10011 00020 10221 01101 00001 11001 11100 20111 21010 11000 10010 10010 01112 00202 11110 00101 00110 00000 00020 20210 00011 00100 00100 10000 00000 11111 01000 10111 00101 10100 21001 01110 11101 00010 11000 11111 10110 10101 01100 11011 01102 10201 11101 00110 10010 11000 00110 11011 01000 11010 01100 00012 22212 10001 10011 11001 00001 00211 00020 10011 00010 00000 01010 02222 02000 01110 01101 11100 00000 20121 00010 01111 11000 00100 01001 20000 10001 11001 00010 11100 12012 01110 00100 00101 00000 10200 00001 01110 11000 01001 01000 21200 22100 11001 01001 00010 10022 00020 01011 00011 00000 01100 00210 22000 11010 01000 10001 00011 00002 00110 10000 10111 10010 00002 02121 10000 00110 01101 10011 21001 11110 01111 00110 00010 01020 02122 00101 01001 10001 00000 00020 00111 01011 00101 11100 00010 02210 11100 00011 10010 00110 00201 01200 11011 00001 10100 10000 11021 00010 01011 01001 10000 01111 20111 00001 11100 00100 01001 12002 11000 11111 01100 10000 00100 21100 21011 01111 01001 11101 10100 00021 00001 01001 10010 10110 12022 12010 01011 11100 01100 10122 21220 00010 11010 10110 00001 00010 21011 01001 11110 10101 01001 11202 21100 10001 00110 10110 11000 02120 00100 00000 10000 00100 02002 21110 10010 01101 01000 10012 12021 11101 00111 00100 10100 12120 20000 01001 00010 00010 01001 00200 21110 01110 11100 11010 10200 11010 01111 11000 11010 01100 02111 10001 01100 10000 00110 00011 02112 11101 01100 11111 11010 01000 11010 11111 01011 01000 10002 11222 00110 00100 01101 10010 01021 10111 11110 00110 11000 01100 11211 11110 01110 10110 00101 10100 21020 01110 10110 10011 00000 12222 12100 01100 11110 10000 00002 11022 10100 00011 01010 00100 01200 21200 10011 10110 00000 00101 02000 21101 01111 01101 00110 00020 20020 00010 00011 00110 00100 12020 00201 11010 00010 10110 00010 12210 01000 01100 10111 00010 10002 00110 10011 10011 11010 01000 00211 01110 10011 11011 01010 11122 12100 00111 01010 00000 01101 00200 21010 01000 00010 10110 00010 12210 01000 01100 00010 00000 11000 11000 11111 00111 01000 10001 22120 20111 00000 10101 11000 11000 20111 01000 11001 01100 01011 01002 10010 11100 11111 10010 01000 11222 21100 00010 01111 00010 00212 12111 10001 01001 11001 00101 00022 00011 00100 00101 11010 11002 12020 01100 01010 01100 00000 10202 02000 00111 11010 11000 00001 02212 00000 00100 11001 10111 00021 00020 11011 01011 10000 00101 11101 11011 00101 01101 01100 00110 21100 11010 11001 01110 00101 00020 01101 00111 01110 11010 10111 22121 01001 11000 10000 10011 01002 00211 10010 00000 10101 10000 00122 10010 00010 00110 01001 01100 02000 10101 00001 00010 10000 12120 11011 01111 00110 10111 00000 02002 00001 00001 10011 00011 01202 00220 11100 01010 00100 01001 02002 11101 11110 01101 00110 00020 22221 10000 11011 11100 10000 12121 10000 01000 10011 00100 11102 22100 00011 01100 00100 01110 01210 02200 00100 00111 10010 11010 00112 02000 00100 01001 00000 00020 01101 10100 00001 01100 00100 01000 21110 11011 10010 00110 01101 00200 21110 01000 00010 10110 00100 12010 01001 00011 00100 11100 22100 12011 00111 00001 00010 10111 00000 01110 00011 01101 01100 10210 02010 00111 10001 01001 00002 20021 00011 00100 01001 10001 00000 20221 01000 00110 10000 01010 12002 00001 00111 10010 00100 10022 22102 00011 01101 10111 00000 02121 22200 01111 10110 11000 10002 22102 10001 00010 01110 01100 11202 22100 10001 10100 00000 01110 02210 02100 00011 11110 00101 01101 01110 11111 00100 10110 00101 11100 21011 01110 01001 11101 10100 00021 10001 00110 01100 01011 10202 01000 01010 01111 01101 00100 01120 22110 00001 01001 11011 00112 10020 11111 00001 10011 00000 11212 22101 10011 10100 11110 11010 00002 10000 10001 00110 11001 01111 20200 10110 10100 00000 01110 02210 02100 00011 11010 00100 00101 21200 11000 01001 10010 01000 02112 00001 00011 10010 10100 00001 20011 11101 01101 01101 01011 10002 10000 11100 00011 11011 01010 00210 21010 01010 00001 10000 10111 12022 00110 01001 11101 01100 11222 21201 00010 00011 10010 01002 00012 11111 10010 00001 00100 00200 22010 01010 10001 00000 10100 22122 02011 00110 00010 00011 01000 10200 01000 00110 10010 00000 10112 01110 00011 11000 01100 10011 20021 11001 11100 00001 11010 01001 02200 11101 01100 01010 01000 02200 21000 11001 00010 10100 01000 00200 11010 01100 01011 01000 01100 22211 11000 00110 01110 11000 02102 00001 11101 01110 00000 00112 22220 11110 01101 00001 00011 21022 00010 01010 10000 00001 11002 21002 10000 01111 11010 10100 10121 22011 00000 11010 10010 00002 10022 10100 00011 01010 00101 01200 20000 10000 00111 00110 10010 02122 00100 00011 10101 10001 11110 00122 01010 00000 01110 01000 02112 12101 11101 11110 01001 00001 02021 10000 01000 00100 00110 11110 00001 01011 11001 10000 00010 00021 01101 01111 10011 00000 10120 00200 01010 10000 11111 01001 00212 01101 10111 10000 10001 01000 00212 01011 10100 10000 00110 00110 20201 11011 00011 01000 10001 01222 00110 00111 00111 00101 10120 21200 00110 10000 11011 01010 00212 11101 10011 11111 00001 01002 01122 10111 00100 11010 10001 10121 20221 11000 01000 01000 10000 00020 01101 10100 10100 10001 11010 21000 00110 11101 11001 10100 11001 21111 11010 00110 01111 00010 11110 00011 10101 10100 01101 10210 21001 10111 11101 10000 10110 22121 01001 01111 10100 10010 11020 00002 11000 10111 01011 10001 11101 21100 10101 00001 00010 01000 02111 20111 11010 00111 00000 01000 21211 00110 10011 01010 10000 01111 02111 01101 01100 10010 00011 12121 11101 00000 01000 10001 01001 20011 11111 11001 11000 01002 11002 10110 10101 10100 11000 00020 02020 01000 01100 00000 11011 02002 01111 01101 00010 00100 11000 21102 11111 01100 00001 10000 11202 00010 11011 01100 10000 01100 22201 21000 00110 01101 10100 01000 12210 11001 10001 01101 00100 20200 21111 11010 10001 10100 10021 01112 11000 10001 00100 11001 12110 11010 10111 00001 11000 00002 11121 20100 01100 10010 00000 01222 12221 00100 11000 00110 01001 21102 11001 01110 11010 10100 00011 11021 11011 01011 01000 10001 01121 20011 01111 10110 10011 00002 02002 00001 00001 10100 00010 10202 01120 11110 00111 00101 10001 21011 00110 11011 10110 10001 00021 12220 01100 01000 10001 00110 00211 02211 11011 11000 01000 01002 02112 21110 00001 00110 00100 00120 02111 11101 10101 10001 01100 00210 01011 10011 00000 11100 01010 21100 11010 00001 11011 10110 00021 22201 00000 01100 11101 10111 21021 01011 11000 11110 11010 00000 11020 11111 01010 11000 00001 12212 00100 00101 01101 00010 00121 22200 01000 11001 00010 01000 02112 22011 11111 00000 11110 11000 02011 21111 01000 10000 00110 00011 02110 11101 01100 00100 00100 20211 22111 00000 10001 10000 11112 12112 11100 10011 11110 01100 01011 21201 11011 00011 01000 11012 22101 11011 01101 10010 01000 00112 12111 10100 10001 10110 11000 00020 02110 01000 01100 10000 10102 02021 00111 10100 01101 01011 02102 10001 01101 01000 01010 11002 00002 21010 10000 10010 11010 11002 01100 00011 10110 01000 00010 02110 02101 10111 11100 11110 00010 12000 10000 11100 10001 01110 01201 20211 00011 01001 10001 00001 20022 20011 00001 00001 11001 00022 11210 00111 11011 11101 01000 20012 22001 10111 00001 10010 10020 02121 00111 00101 01100 01110 00001 22110 10011 01110 11001 00102 21220 20000 00010 10000 10010 11100 02011 00011 01000 10001 00111 00211 00111 11000 10010 00110 01021 11002 10001 11010 11100 11010 11100 11011 01111 10000 10011 10112 00011 00010 11101 00100 00011 11020 11001 01011 00000 11010 00000 12112 11110 00110 10110 10101 11000 21002 01110 10001 11001 10001 00012 10001 00101 00001 00011 00111 20000 01011 11101 11110 00000 00022 22201 00110 00001 11010 10101 02121 20111 01000 01001 11001 00101 20022 01111 00100 01000 00100 00210 20000 11001 10010 00100 00011 20111 01100 10100 01000 10100 00020 00220 10100 10001 00010 00001 02001 20110 10100 01000 11101 00101 20111 00011 10000 10101 00011 01002 22100 10100 00001 00010 10001 02120 11011 00100 10100 10000 11111 00100 01010 01000 00000 00100 20220 20000 11101 01111 10000 10101 10100 10110 10100 00110 10100 12010 02201 11100 01000 01001 11002 20012 20000 00001 10010 10001 00020 10020 01001 00011 00101 10100 11110 02101 11100 10000 00010 01000 00020 11101 01001 00000 00100 02120 11110 01110 00001 01011 00002 00120 01110 00110 11010 10001 01112 01201 00110 10101 10100 11000 02020 02100 01000 01101 00000 10102 02000 00111 11010 01101 00000 10000 21211 01010 00011 11010 00012 00010 11111 11011 11110 01001 00002 11201 00100 00110 01000 10111 00120 10111 10010 11000 10000 11002 22020 10000 01011 00111 00101 10120 20101 00101 11100 01000 00012 12121 20111 01010 10001 00010 01220 02110 01111 10100 00101 11101 11100 21110 00000 00001 00110 01120 02110 10011 10111 00000 10011 00112 00011 11011 10110 01000 00002 22212 20001 10000 11100 11100 10011 21011 01011 10010 00010 01101 00200 21110 01000 00010 00110 00000 12010 01001 00010 00100 11100 01100 20211 01011 10001 00111 01101 00110 01101 11110 00010 01010 01201 12200 01110 11010 10010 01000 21002 12001 11101 00101 01101 00110 21020 00110 01010 10000 00010 00210 00010 01101 10101 10010 00002 00222 10010 00010 00011 00100 10200 21100 01010 11110 00011 01000 01202 01010 11011 00100 11100 11110 00002 11111 00101 00110 00000 00020 20210 00011 00011 10110 00000 00200 21110 01010 10010 00011 10212 00220 00000 00110 01101 01000 11201 10110 11111 11101 11010 11010 02111 01000 11100 01010 01000 02212 12000 11001 00011 01100 10000 21101 21111 10100 01000 00001 10120 20001 00001 11100 00101 01000 21101 20001 11011 10110 11000 00011 00112 11010 00110 01101 00001 01200 01200 01111 01001 10111 10000 11021 10000 01110 01110 11000 10100 20211 11010 10001 01000 01001 11121 00001 00111 00100 10001 01121 21201 11001 00001 00010 00110 11221 11110 01001 10110 10000 00012 20112 00010 00100 00011 01000 10100 10001 01101 11101 11010 11000 11111 22110 11000 10010 10001 00102 20021 00011 11010 00011 01100 10200 01110 01011 10000 10001 00111 20211 01111 11001 01111 00100 01000 12211 10000 10000 10010 01110 00121 01011 01111 10010 00000 00020 21211 11101 10000 01100 01011 11122 10001 01101 01000 11001 00110 20220 01010 10010 01101 00011 00222 10120 01101 10011 00010 00010 00222 01110 00011 00100 01100 10110 02011 11100 11010 11100 01010 02202 11110 10111 10011 00010 00002 00211 01110 11010 11110 10111 00021 01201 11000 00110 01000 10111 00120 10111 10000 00101 00001 10101 00201 11010 11100 00010 11000 12022 11100 01001 00010 00010 00011 01201 11111 01000 11001 01010 01202 22120 00001 01110 10001 01010 00002 00101 10110 00100 00011 01021 10000 01001 11101 00010 10011 12100 11101 10000 01011 01001 10001 20200 21100 10010 00011 01110 00110 00220 01110 10001 00100 00100 12020 00100 00011 11001 11001 00111 20201 10010 11010 00111 10110 00120 02100 11101 00000 10100 01100 02110 01101 00100 10011 10011 11002 01111 10101 11000 00100 10100 21010 02001 11101 10000 00100 00002 11111 10100 10100 01010 10001 00000 20011 01001 11010 01100 01001 12200 21111 11010 00010 00011 00111 00220 10101 10110 11100 01011 22000 11001 00001 00001 00100 00020 22001 01010 10010 00010 01001 11000 20200 11100 01010 10000 01011 00200 00100 01100 00010 00100 10120 21111 00111 00110 11000 00110 10121 01111 11011 00111 01100 10010 02120 11100 00011 00100 01011 10012 01211 11000 00000 11000 00010 20000 11101 01101 01100 11100 11110 20000 10011 10110 00100 00010 02122 12101 01100 11010 00000 01000 11202 01000 01110 01011 00100 01221 21211 11011 00101 01100 10100 02021 21100 01010 10000 11011 11102 00021 10010 00101 00000 00100 02220 02100 01110 10110 11100 10102 02111 00101 10110 10100 10110 12111 20001 11010 01010 01001 00101 10221 21000 01010 01111 01000 11100 22101 11001 00111 00001 00011 21222 02110 00001 01110 10000 00022 20112 00010 00000 10111 00010 00122 02011 00001 00010 11110 00000 00200 11110 01001 01101 00100 00120 10220 00000 01110 11010 01000 22002 11001 10101 01101 00010 00101 22200 01000 11011 00110 11100 12100 02111 01100 10011 00000 01012 00012 00011 11011 00010 10110 11111 02100 00111 10101 11000 00100 02221 02100 00111 01100 01011 11012 10021 11101 01010 10000 01011 00002 00001 00011 11100 11010 00012 12000 10000 11100 10101 01110 10201 20011 00010 01101 10100 01000 20111 22001 11001 10000 01000 10120 22220 01100 11000 01110 01110 10110 10111 01011 01001 01100 01101 01210 20101 11000 11000 01011 00212 10210 10111 11011 00011 10001 11121 20101 11010 11010 11101 00011 00210 01110 00010 01010 11001 02100 20211 11000 00001 01110 00100 21000 21010 10000 01011 11001 00000 20020 11001 11010 10101 00110 20021 02010 11100 00011 00000 10021 10001 00101 10001 01011 01001 00122 21201 00010 10110 01110 01001 02100 21101 11001 00010 00100 00000 00221 11011 00111 01101 00011 11122 10100 01100 11111 00101 00112 21212 10010 10000 00000 00000 10200 01111 01010 01111 10001 01001 11002 20101 10101 01100 10000 00012 22201 11111 00001 00010 10001 11021 20001 11010 11000 00001 10002 00021 10101 01110 00001 01111 01010 00111 01011 01001 00000 00010 02201 10100 01001 01101 10110 00000 20021 10010 00101 00110 01100 20100 12010 11100 10001 01001 10122 01020 10001 01010 11000 00011 00222 21210 00101 01101 11000 00102 21222 00010 00100 01000 00011 00222 10021 01111 10010 10010 01001 00002 20001 00110 00011 01010 01021 11111 01001 11011 00110 10000 02101 10100 10000 11000 01010 11002 21002 10010 01001 10000 00000 10122 12000 01101 11100 00100 11001 20002 11010 10111 00000 10111 10101 00011 10101 10110 10010 11000 00110 11011 01000 01101 01010 00101 22200 21000 11000 11110 10010 10002 10101 10011 10010 10000 00010 11210 00100 01100 10111 00010 00002 01012 10000 11010 01111 01101 00000 21101 00000 00111 11001 10101 21001 10110 11100 10110 11010 11011 02210 00001 01100 11001 10001 21010 00011 00100 11100 11010 00102 11121 00000 11100 10101 10000 10002 00001 10111 00000 10000 01000 00112 20101 10000 01010 00101 00012 21221 10010 00100 10100 10000 22002 10111 10010 00011 11000 11100 02101 10111 00100 11000 00010 12000 12000 11110 10010 11110 01001 00012 10011 10011 10011 00111 00221 01220 01001 10001 10000 00110 20221 01101 01101 11111 10001 01001 01002 01101 00111 00110 00100 11100 02210 01100 10010 00000 00010 21111 00010 10100 00010 11001 10000 20120 11100 11001 00010 11001 00022 11011 00111 10001 10000 11020 22000 01010 10010 00110 11001 01202 11010 11111 11000 01100 10101 12020 21111 10001 11000 10110 11121 21001 01010 00101 00100 00100 21120 00100 01110 00100 01100 00100 02011 11100 11100 10000 00010 02210 00000 01101 10000 01011 01002 02111 10001 00111 00000 00001 00202 10121 11011 01001 00101 00011 20200 01010 10101 10100 10110 00001 10110 11010 00010 10111 00010 02200 12000 11101 01111 01110 01100 02121 20101 10011 00111 01110 01210 02010 10101 00001 11110 10100 01000 20111 11010 00110 00001 01111 10000 01111 11000 11100 01010 10200 11011 01110 01100 00000 11100 20001 21010 00010 11001 01101 00201 20000 00011 10001 10111 00000 00020 00111 00011 00000 01100 10110 12020 10101 11000 00100 11100 01100 02010 10101 10000 11011 00100 02120 21001 01010 11000 00110 11111 11001 11010 10100 11100 10001 12002 02111 10100 00010 00000 10111 11120 10010 10000 11101 00100 10211 12001 11100 01101 11011 10012 01020 11011 01000 00111 11000 11001 20120 01110 00100 10000 11000 22000 01001 10011 10111 01000 01112 21210 11110 11001 00011 00110 00000 00211 11010 01111 11001 10100 01100 20110 11000 01101 11000 10012 22120 00001 00100 01100 10011 20002 10001 11100 00110 00101 00020 10212 10111 10000 00111 00101 00020 11211 10110
diff --git a/2019/9b.plaintext b/2019/9b.plaintext
new file mode 100644 (file)
index 0000000..c2fb36c
--- /dev/null
@@ -0,0 +1,57 @@
+memo from docking manoeuvre office to as test flight space systems re as docking collar tests
+preliminary testing of the docking collar system has revealed a potentially serious flaw in the
+design which must be addressed before the system can be certified the issue concerns the emergency
+release system background the docking system performs the following functions impact energy
+absorption mechanical connection spacecraft alignment and retraction spacecraft hard mechanical
+connection and docking interface sealing spacecraft undocking and separation in order to achieve
+these functions the docking system consists of three principle parts the base a structural ring and
+the latching ring the docking system base is the main structural member to which the docking system
+assemblies are attached the structural ring carries the body latches which provide a hard pressure
+tight connection between the two spacecraft together with the capture latches which operate during
+the docking manoeuvre these perform the docking function they consist of eight active and eight
+passive hooks with an electrical drive installed on one of the latches and closed loop cables
+connecting them each active hook has a cam operated mechanism which performs its opening and
+tightening corresponding hooks of the passive docking system are captured by active hooks each
+passive hook has a stack of preloaded bellville springs providing a definite force for the docking
+interface preloading the docking interface seal will provide pressure integrity of the docking
+interfaces this consists of two concentric rubber ring seals on each system and a manhole cover is
+used to close the transfer tunnel of the spacecraft hatch locking and unlocking is manually
+performed by the crew it is sealed by a mechanism which has a further eight eccentric latches these
+being connected with each other by means of closed cable connection the docking system is equipped
+with alarm and meter system which provide telemetry to the ships and to ground control in standard
+operational mode undocking is performed by release of the active spacecraft capture latches and then
+by opening the structure latch hooks if necessary undocking can be performed by the passive
+spacecraft by releasing the body mounted latches and opening the structure latch passive hooks
+spacecraft separation is performed by spring thrusters symmetrically located on the structural rings
+of both systems after the latches release the principle difference between the russian and us
+docking system designs can be seen in the guide ring system unlike the russian electromechanical
+docking system apollo is equipped with an electric drive which uses cable connections to trigger the
+latches another essential difference is the russian emergency release system ers a backup provided
+by pyro bolts attached to each passive and active hook which operates in passive mode and provides
+practically instantaneous undocking in the event of a system malfunction or accident onboard one or
+both of the docked spacecraft situations in which the ers might be initiated include i uncontrolled
+fire or explosion onboard one of the spacecraft during docked operations ii failure of the docking
+control system preventing standard release operation iii attitude control failure of or unplanned
+firing on one or both spacecraft imposing high stresses on the docking mechanism while the ers
+provides an effective backup for emergency situations simulations and tests on the huntsville
+docking testbed show that the effectiveness of the pyrotechnic bolts is a critical issue too much
+explosive could cause critical damage to the pressure seals around the hatch while too little can
+leave the spacecraft attached with a damaged mechanism the ers was designed for operation on ussr
+missions and is therefore tuned to the structural constraints on the soviet platform since the
+latches are electromagnetic on that spacecraft they are less prone to damage under vibrational
+forces the motor and cable mechanism used on the apollo platform is more vulnerable to shock and
+under certain test conditions has been shown to fail following the triggering of the erson the
+soviet end of the docking mechanism shockwaves will not of course propagate through the vacuum of
+space but the forces can be transmitted through the tunnel to the apollo latches and if the bolts
+fire asymmetrically this places a torsion loading on the mechanism which can unseat the drive cables
+in five of the seven tests where this phenomenon was observed the engineers were able to reseat the
+cables by repeatedly operating the mechanism but in the remaining two cases the mechanism was beyond
+repair without manual intervention unfortunately in these two cases the safety interlock also
+prevented the hatch from being opened which could make it difficult for the astronauts to carryout a
+spacewalk to execute the required repair in this case it would normally be possible for the
+astronauts to manually operate the manhole latches by disassembling and subsequently assembling the
+hatch cover however if the latching mechanisms have been sufficiently damaged by the pyro bolts this
+might prove a risky option and it is even possible that the cover latches would fail to retract
+manually we have asked queens team to take a look at this and she assures me that they can sort it
+out she has worked on most of the apollo mission design teams so i am pretty confident that she can
+make sure everything is ok for this one
\ No newline at end of file
diff --git a/2020-early/1a.ciphertext b/2020-early/1a.ciphertext
new file mode 100644 (file)
index 0000000..7bfa789
--- /dev/null
@@ -0,0 +1,8 @@
+CVMMT,
+D VH MZVGGT NJMMT OJ WJOCZM TJP, WPO NJHZOCDIB CVN XJHZ PK VIY OCZ NDN VMZ OJJ WPNT OJ CZGK. D VH CJKDIB TJP XVI.
+AJGGJRDIB OCZ DIQVNDJI JA KJGVIY, RZ VMZ VGG JI YJPWGZ YPOT, OMVRGDIB OCMJPBC JGY ADGZN AJM VITOCDIB OCVO HDBCO WZ PNZAPG OJ JPM AMDZIYN DI ZPMJKZ. HT OZVH CVN WZZI VNFZY OJ GJJF VO DIOZGGDBZIXZ ADGZN XJIIZXOZY RDOC VDM OMVINKJMO VIY D RVN BDQZI OCZ CDIYZIWPMB YDNVNOZM OJ XCZXF JPO.
+OCZMZ DNI’O HPXC OJ BJ JI VN HJNO JA OCZ KVKZMN MZXJQZMZY AMJH OCZ RMZXFVBZ RZMZ WVYGT YVHVBZY. RZ YJ CVQZ V GVMBZ IPHWZM JA AMVBHZION JA OMVQZG YJXPHZION RCDXC D CVQZ NZIO OJ OCZ NOVOZ YZKVMOHZIO AJM DY XCZXFN, WPO OCVO RDGG OVFZ V RCDGZ, VIY DI OCZ HZVIODHZ, D CVQZ WZZI ZSVHDIDIB NJHZ JA OCZ HJMZ PIPNPVG DOZHN.
+OCZ HJNO DIOZMZNODIB JIZ DN V XCVMMZY ZIQZGJKZ XVMMTDIB V NRVNODFV VIY HVMFZY YDZ VGXCZHDNOZI. D OCDIF OCVO HDBCO WZ RJMOC DIQZNODBVODIB.
+OCZ XJIOZION RZMZ HDNNDIB, WPO DI OCZ NVHZ ZQDYZIXZ WVB D AJPIY V AMVBHZIO JA OJMI WGPZ KVKZM RDOC V IPHWZM DI OCZ WJOOJH XJMIZM. OCZMZ DN IJ YZNXMDKODJI RDOC DO, WPO D VH BPZNNDIB OCVO OCZT HPNO CVQZ WZZI AJPIY OJBZOCZM. RVOZM CVN YDNNJGQZY VIY JWNXPMZY OCZ IPHWZM NJ D XVI’O MZVY DO VIY D YJI’O MZXJBIDNZ OCZ AJMHVO. JI OCZ JOCZM CVIY, OCZ RVOZM HPNO CVQZ KMJOZXOZY DO AMJH OCZ CZVO JA OCZ AGVHZN VN OCZMZ VMZ IJ WPMI HVMFN VIY D RJIYZMZY DA TJPM S-MVT OZVH HDBCO WZ VWGZ OJ VNNDNO.
+CVQZ TJP NZZI VITOCDIB GDFZ DO WZAJMZ, JM CVQZ TJP CZVMY JA YDZ VGXCZHDNOZI? VITOCDIB TJP CVQZ RJPGY WZ BMZVO. OCVIFN
+KCDG
diff --git a/2020-early/1a.plaintext b/2020-early/1a.plaintext
new file mode 100644 (file)
index 0000000..9a8da83
--- /dev/null
@@ -0,0 +1,8 @@
+HARRY,
+I AM REALLY SORRY TO BOTHER YOU, BUT SOMETHING HAS COME UP AND THE SIS ARE TOO BUSY TO HELP. I AM HOPING YOU CAN.
+FOLLOWING THE INVASION OF POLAND, WE ARE ALL ON DOUBLE DUTY, TRAWLING THROUGH OLD FILES FOR ANYTHING THAT MIGHT BE USEFUL TO OUR FRIENDS IN EUROPE. MY TEAM HAS BEEN ASKED TO LOOK AT INTELLIGENCE FILES CONNECTED WITH AIR TRANSPORT AND I WAS GIVEN THE HINDENBURG DISASTER TO CHECK OUT.
+THERE ISN'T MUCH TO GO ON AS MOST OF THE PAPERS RECOVERED FROM THE WRECKAGE WERE BADLY DAMAGED. WE DO HAVE A LARGE NUMBER OF FRAGMENTS OF TRAVEL DOCUMENTS WHICH I HAVE SENT TO THE STATE DEPARTMENT FOR ID CHECKS, BUT THAT WILL TAKE A WHILE, AND IN THE MEANTIME, I HAVE BEEN EXAMINING SOME OF THE MORE UNUSUAL ITEMS.
+THE MOST INTERESTING ONE IS A CHARRED ENVELOPE CARRYING A SWASTIKA AND MARKED DIE ALCHEMISTEN. I THINK THAT MIGHT BE WORTH INVESTIGATING.
+THE CONTENTS WERE MISSING, BUT IN THE SAME EVIDENCE BAG I FOUND A FRAGMENT OF TORN BLUE PAPER WITH A NUMBER IN THE BOTTOM CORNER. THERE IS NO DESCRIPTION WITH IT, BUT I AM GUESSING THAT THEY MUST HAVE BEEN FOUND TOGETHER. WATER HAS DISSOLVED AND OBSCURED THE NUMBER SO I CAN'T READ IT AND I DON'T RECOGNISE THE FORMAT. ON THE OTHER HAND, THE WATER MUST HAVE PROTECTED IT FROM THE HEAT OF THE FLAMES AS THERE ARE NO BURN MARKS AND I WONDERED IF YOUR X-RAY TEAM MIGHT BE ABLE TO ASSIST.
+HAVE YOU SEEN ANYTHING LIKE IT BEFORE, OR HAVE YOU HEARD OF DIE ALCHEMISTEN? ANYTHING YOU HAVE WOULD BE GREAT. THANKS
+PHIL
diff --git a/2020-early/1b.ciphertext b/2020-early/1b.ciphertext
new file mode 100644 (file)
index 0000000..7e19bde
--- /dev/null
@@ -0,0 +1,4 @@
+XPQT, QB QA OWWL BW PMIZ NZWU GWC. BPQVOA IZM PMKBQK PMZM BWW, JCB QB QA UIQVTG JCZMICKZIKG IA EM BZG BW UISM ACZM ITT BPM JWAA NQMTL IOMVBA PIDM AMKCZM KPIVVMTA WN KWUUCVQKIBQWV IVL ZWCBMA WCB WN BZWCJTM QN BPMG VMML BPMU. QB QA MAAMVBQIT EWZS, JCB Q PIDM JMMV QBKPQVO BW OMB WCB BPMZM EQBP BPMU IVL GWCZ TMBBMZ KIUM IB BPM ZQOPB BQUM.
+Q PIDMV’B PMIZL WN LQM ITKPMUQABMV JMNWZM, JCB QB LWMA ZMUQVL UM WN AWUMBPQVO BPIB Q KIV’B YCQBM XTIKM. Q EQTT OMB JIKS BW GWC QN Q ZMUMUJMZ. BPM VCUJMZ QA ATQOPBTG MIAQMZ. BPQA TWWSA TQSM BPM JWBBWU ZQOPB KWZVMZ WN I JTCMXZQVB IVL Q IAACUM BPM VCUJMZ QA ZMTIBML BW BPM LMAQOV. BPM F-ZIG BMIU BWWS I AVIX EPQKP QVKZMIAML BPM KWVBZIAB IVL Q BPQVS Q KIV UISM WCB BPM TMBBMZA OJ IB BPM ABIZB, EPQKP QA ACOOMABQDM. BPM VMFB BEW LQOQBA IZM VWB KTMIZ, JCB BPMG KWCTL JM MQOPB-BPZMM WZ MQOPB-NQDM. Q PIDM AMVB I ZMYCMAB BW BPM CS UQTQBIZG IBBIKPM BW AMM QN PM ZMKWOVQAMA BPM NWZUIB.
+Q EQTT JM QV BWCKP QV AMDMV LIGA.
+PIZZG
diff --git a/2020-early/1b.plaintext b/2020-early/1b.plaintext
new file mode 100644 (file)
index 0000000..0ac7183
--- /dev/null
@@ -0,0 +1,4 @@
+PHIL, IT IS GOOD TO HEAR FROM YOU. THINGS ARE HECTIC HERE TOO, BUT IT IS MAINLY BUREAUCRACY AS WE TRY TO MAKE SURE ALL THE BOSS FIELD AGENTS HAVE SECURE CHANNELS OF COMMUNICATION AND ROUTES OUT OF TROUBLE IF THEY NEED THEM. IT IS ESSENTIAL WORK, BUT I HAVE BEEN ITCHING TO GET OUT THERE WITH THEM AND YOUR LETTER CAME AT THE RIGHT TIME.
+I HAVEN'T HEARD OF DIE ALCHEMISTEN BEFORE, BUT IT DOES REMIND ME OF SOMETHING THAT I CAN'T QUITE PLACE. I WILL GET BACK TO YOU IF I REMEMBER. THE NUMBER IS SLIGHTLY EASIER. THIS LOOKS LIKE THE BOTTOM RIGHT CORNER OF A BLUEPRINT AND I ASSUME THE NUMBER IS RELATED TO THE DESIGN. THE X-RAY TEAM TOOK A SNAP WHICH INCREASED THE CONTRAST AND I THINK I CAN MAKE OUT THE LETTERS GB AT THE START, WHICH IS SUGGESTIVE. THE NEXT TWO DIGITS ARE NOT CLEAR, BUT THEY COULD BE EIGHT-THREE OR EIGHT-FIVE. I HAVE SENT A REQUEST TO THE UK MILITARY ATTACHE TO SEE IF HE RECOGNISES THE FORMAT.
+I WILL BE IN TOUCH IN SEVEN DAYS.
+HARRY
diff --git a/2020-early/2020-a-challenge1.ipynb b/2020-early/2020-a-challenge1.ipynb
new file mode 100644 (file)
index 0000000..e12b2dd
--- /dev/null
@@ -0,0 +1,176 @@
+{
+ "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 *"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "challenge_number = 1\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": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ca = open(ciphertext_a_filename).read()\n",
+    "cb = open(ciphertext_b_filename).read()\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "21 \n",
+      "\n",
+      "HARRY,\n",
+      "I AM REALLY SORRY TO BOTHER YOU, BUT SOMETHING HAS COME UP AND THE SIS ARE TOO BUSY TO HELP. I AM HOPING YOU CAN.\n",
+      "FOLLOWING THE INVASION OF POLAND, WE ARE ALL ON DOUBLE DUTY, TRAWLING THROUGH OLD FILES FOR ANYTHING THAT MIGHT BE USEFUL TO OUR FRIENDS IN EUROPE. MY TEAM HAS BEEN ASKED TO LOOK AT INTELLIGENCE FILES CONNECTED WITH AIR TRANSPORT AND I WAS GIVEN THE HINDENBURG DISASTER TO CHECK OUT.\n",
+      "THERE ISN'T MUCH TO GO ON AS MOST OF THE PAPERS RECOVERED FROM THE WRECKAGE WERE BADLY DAMAGED. WE DO HAVE A LARGE NUMBER OF FRAGMENTS OF TRAVEL DOCUMENTS WHICH I HAVE SENT TO THE STATE DEPARTMENT FOR ID CHECKS, BUT THAT WILL TAKE A WHILE, AND IN THE MEANTIME, I HAVE BEEN EXAMINING SOME OF THE MORE UNUSUAL ITEMS.\n",
+      "THE MOST INTERESTING ONE IS A CHARRED ENVELOPE CARRYING A SWASTIKA AND MARKED DIE ALCHEMISTEN. I THINK THAT MIGHT BE WORTH INVESTIGATING.\n",
+      "THE CONTENTS WERE MISSING, BUT IN THE SAME EVIDENCE BAG I FOUND A FRAGMENT OF TORN BLUE PAPER WITH A NUMBER IN THE BOTTOM CORNER. THERE IS NO DESCRIPTION WITH IT, BUT I AM GUESSING THAT THEY MUST HAVE BEEN FOUND TOGETHER. WATER HAS DISSOLVED AND OBSCURED THE NUMBER SO I CAN'T READ IT AND I DON'T RECOGNISE THE FORMAT. ON THE OTHER HAND, THE WATER MUST HAVE PROTECTED IT FROM THE HEAT OF THE FLAMES AS THERE ARE NO BURN MARKS AND I WONDERED IF YOUR X-RAY TEAM MIGHT BE ABLE TO ASSIST.\n",
+      "HAVE YOU SEEN ANYTHING LIKE IT BEFORE, OR HAVE YOU HEARD OF DIE ALCHEMISTEN? ANYTHING YOU HAVE WOULD BE GREAT. THANKS\n",
+      "PHIL\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "k_a, score_a = caesar_break(ca)\n",
+    "print(k_a, '\\n')\n",
+    "pa = caesar_decipher(ca, k_a)\n",
+    "print(pa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1466"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_a_filename, 'w').write(pa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "8 \n",
+      "\n",
+      "PHIL, IT IS GOOD TO HEAR FROM YOU. THINGS ARE HECTIC HERE TOO, BUT IT IS MAINLY BUREAUCRACY AS WE TRY TO MAKE SURE ALL THE BOSS FIELD AGENTS HAVE SECURE CHANNELS OF COMMUNICATION AND ROUTES OUT OF TROUBLE IF THEY NEED THEM. IT IS ESSENTIAL WORK, BUT I HAVE BEEN ITCHING TO GET OUT THERE WITH THEM AND YOUR LETTER CAME AT THE RIGHT TIME.\n",
+      "I HAVEN'T HEARD OF DIE ALCHEMISTEN BEFORE, BUT IT DOES REMIND ME OF SOMETHING THAT I CAN'T QUITE PLACE. I WILL GET BACK TO YOU IF I REMEMBER. THE NUMBER IS SLIGHTLY EASIER. THIS LOOKS LIKE THE BOTTOM RIGHT CORNER OF A BLUEPRINT AND I ASSUME THE NUMBER IS RELATED TO THE DESIGN. THE X-RAY TEAM TOOK A SNAP WHICH INCREASED THE CONTRAST AND I THINK I CAN MAKE OUT THE LETTERS GB AT THE START, WHICH IS SUGGESTIVE. THE NEXT TWO DIGITS ARE NOT CLEAR, BUT THEY COULD BE EIGHT-THREE OR EIGHT-FIVE. I HAVE SENT A REQUEST TO THE UK MILITARY ATTACHE TO SEE IF HE RECOGNISES THE FORMAT.\n",
+      "I WILL BE IN TOUCH IN SEVEN DAYS.\n",
+      "HARRY\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "k_b, score_b = caesar_break(cb)\n",
+    "print(k_b, '\\n')\n",
+    "pb = caesar_decipher(cb, k_b)\n",
+    "print(pb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "953"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_b_filename, 'w').write(pb)"
+   ]
+  },
+  {
+   "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-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
+
+```
diff --git a/2020-early/2020-a-challenge2.ipynb b/2020-early/2020-a-challenge2.ipynb
new file mode 100644 (file)
index 0000000..93a980b
--- /dev/null
@@ -0,0 +1,178 @@
+{
+ "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": 8,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from cipher.caesar import *\n",
+    "from cipher.affine import *\n",
+    "\n",
+    "from support.text_prettify import *\n",
+    "from support.utilities import *\n",
+    "from support.plot_frequency_histogram import *"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "challenge_number = 2\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": 9,
+   "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": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "(3, 6, True) \n",
+      "\n",
+      "PHIL I HEARD BACK FROM THE BRITISH MILITARY ATTACHE STOP HE SAID THAT THE NUMBER LOOKS LIKE THE FORMAT USED BY THE PATENT OFFICE STOP HE SUGGESTED THAT THE DOCUMENT MIGHT HAVE BEEN A DESIGN DRAWING FOR AN INVENTION STOP ONE OF OUR FIELD AGENTS TRIED TO FIND OUT WHICH ONE BUT THE NUMBERS LOOKED WRONG STOP PATENT NUMBERS STARTING GB EIGHT HAVE NOT BEEN ISSUED YET STOP THE AGENT HAD NOT SEEN THE PHOTO YOU SENT BUT SHE SHOWED INITIATIVE AND TRIED SOME OTHER NUMBERS STOP GB-SIX-THREE-ZERO-SEVEN-TWO-SIX-A WAS THE MOST PROMISING STOP CHECKED WITH OUR EXPERTS AND THEY WERE CONFUSED STOP ACCORDING TO COCKCROFT THE INVENTION IS IMPRACTICAL STOP SOMEONE POINTED OUT THAT IT FITS WITH THE NAME DIE ALCHEMISTEN STOP SEE ATTACHED STOP WILL INVESTIGATE FURTHER STOP NEXT COMMUNICATION IN SEVEN DAYS STOP\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "(ma, ca, za), score_a = affine_break(sca)\n",
+    "print((ma, ca, za), '\\n')\n",
+    "pa = repunctuate(affine_decipher(sca, ma, ca, za), pta)\n",
+    "print(pa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "797"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_a_filename, 'w').write(pa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "(3, 9, True) \n",
+      "\n",
+      "HARRY, I CHECKED OUT THE PATENT YOU ASKED ME ABOUT. I THINK IT MIGHT BE RELATED TO A LECTURE COCKCROFT DELIVERED AT THE INSTITUTE OF ELECTRICAL ENGINEERS ON APRIL TWENTY THIRD NINETEEN THIRTY SIX. THE TOPIC WAS \"THE TRANSMUTATION OF MATTER BY HIGH ENERGY PARTICLES AND RADIATIONS\". GIVEN THE LABEL ON THE HINDENBURG ENVELOPE I THINK THE FOLLOWING EXTRACT IS PARTICULARLY INTERESTING: \"IN THE CASE OF NUCLEAR TRANSMUTATIONS, IT SEEMS THAT THE LOSS OF MASS IS PRECISELY EQUAL TO THE INCREASE IN THE KINETIC ENERGY THAT HAS TAKEN PLACE. THIS GIVES A STRIKING PROOF OF THE MODERN PHYSICAL LAW THAT MASS AND ENERGY ARE EQUIVALENT. IN NINETEEN THIRTY TWO CHADWICK DISCOVERED THE NEUTRON, A NEW TYPE OF ATOMIC PARTICLE WHICH HAS NO ELECTRIC CHARGE. IT DOES NOT THEREFORE INTERACT WITH OTHER ELECTRONS AND PRODUCES NO IONISATION WHEN PASSING THROUGH A GAS. IT IS OF OUTSTANDING IMPORTANCE BECAUSE OF ITS POWER TO PRODUCE TRANSMUTATIONS. THERE IS LITTLE HOPE THAT THIS PROCESS CAN BE USED ON AN ENGINEERING SCALE TO CONVERT MASS INTO ENERGY. SO FAR, OUR LABORATORY EXPERIMENTS PRODUCE THE CONVERSE RESULT. THEORY INDICATES THAT AT TEMPERATURES EQUAL TO THOSE OF THE INTERIOR OF THE SUN OR STARS, IT MIGHT BE POSSIBLE TO CONVERT THE INEXPENSIVE SIMPLE ELEMENTS TO THE MORE VALUABLE HEAVIER COMBINATIONS, BUT PRACTICALLY, THERE IS NO METHOD OF PRODUCING THE EFFECTS FORMERLY ATTRIBUTED TO THE 'PHILOSOPHER'S STONE'.\"\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "(mb, cb, zb), score_a = affine_break(scb)\n",
+    "print((mb, cb, zb), '\\n')\n",
+    "pb = repunctuate(affine_decipher(scb, mb, cb, zb), ptb)\n",
+    "print(pb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1406"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_b_filename, 'w').write(pb)"
+   ]
+  },
+  {
+   "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-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
+
+```
diff --git a/2020-early/2020-a-challenge3.ipynb b/2020-early/2020-a-challenge3.ipynb
new file mode 100644 (file)
index 0000000..51f0764
--- /dev/null
@@ -0,0 +1,215 @@
+{
+ "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": 6,
+   "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 *"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "challenge_number = 3\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": 18,
+   "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": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('problem', <KeywordWrapAlphabet.from_largest: 3>)"
+      ]
+     },
+     "execution_count": 20,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(kworda, kwrapa), score = keyword_break_mp(sca, fitness=Ptrigrams)\n",
+    "kworda, kwrapa"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "harry,\n",
+      "i don't think this is about alchemy. the energy and raw materials required to produce valuable elements are far too expensive to make this practical, and no-one knows how to do it. it is possible that die alchemisten are focussed on this, but if so they are no threat to anyone at the moment. that doesn't mean we have nothing to worry about. the patent filed by leo szilard was for a prototype nuclear reactor. szilard is an engineer and physicist, and saw cockroft's claim that the nuclear transmutation reaction could not yield energy \"on an engineering scale\" as a challenge to be beaten. transmutation occurs when an atom is hit by an energetic neutron, and his idea was to trigger a process using lighter elements that produce a lot of neutrons as well as energy when hit, so that the process is self-sustaining. so far, his attempts to use elements like beryllium and indium have been unsuccessful, but in the last year hahn and strassman succeeded where he failed, using uranium, and it is possible that this could lead to a practical energy generation process. if that is what die alchemisten are working on then we have a much bigger problem. nuclear processes yield a million times more energy for each gram of fuel than the current chemical reactions like burning coal, and if the nazis could harness that then their steel and aluminium production would massively increase giving them a huge advantage in war. we don't know how far they have got with this technology, but i think we should assume that they are ahead of us and try to find out how far.\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "pa = keyword_decipher(ca, kworda, kwrapa)\n",
+    "print(pa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1571"
+      ]
+     },
+     "execution_count": 24,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_a_filename, 'w').write(pa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('borealis', <KeywordWrapAlphabet.from_last: 2>)"
+      ]
+     },
+     "execution_count": 25,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(kwordb, kwrapb), score = keyword_break_mp(scb, fitness=Ptrigrams)\n",
+    "kwordb, kwrapb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "phil, i am heading to sweden to speak with lise meitner. she was part of the team who split the atom and together with frisch has worked out the details of how it works. she is a brilliant chemist as well as a physicist and i am hoping she can shed some light on how likely it is that that die alchemisten could develop a nuclear power generation system from the process.\n",
+      "on the way back, i plan to also visit some people i know in norway. a new power source will be of no use to the nazis without the raw materials for manufacturing, and a lot of the major bauxite smelters in europe are based in the country. even without a new source of power the german military planners will have their eye on supply lines and the norwegian aluminium companies must be one of their prime targets. i thought i would drop in and try to get a sense of how well defended these places are. there may already have been approaches from germany as part of their arms build-up and it would be good to know that too. if the worst happens and norway is invaded, then i want to have some agents already embedded in the national infrastructure and we need to think about how we would secure communications in an occupied country. if you or the agency have any contacts there then let me know. with a little luck i may even get to see the northern lights while i am there.\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "pb = keyword_decipher(cb, kwordb, kwrapb)\n",
+    "print(pb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1347"
+      ]
+     },
+     "execution_count": 27,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_b_filename, 'w').write(pb)"
+   ]
+  },
+  {
+   "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-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/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": "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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": 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/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": "iVBORw0KGgoAAAANSUhEUgAAAa0AAAEiCAYAAABKsI06AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAATcElEQVR4nO3dfbRldV3H8fcnxgfACoGLIYgXW7NMsgd0ZGFmi8QKRYVWUNgDo9GaLJ+NErIWLsvVmK7M1kprAnJKEgk1KKykEcNS0BlAGBgVkhEmSa6PKZQy8u2PvScveOGec/Y9c+c39/1a665z9j77d37fc84+93N+e++zT6oKSZJa8B3LXYAkSaMytCRJzTC0JEnNMLQkSc0wtCRJzTC0JEnNWLXcBQAcfPDBNTs7u9xlSJL2AFu2bPl8Vc0sdNseEVqzs7Ns3rx5ucuQJO0BknzmgW5z86AkqRmGliSpGYaWJKkZhpYkqRmGliSpGYaWJKkZhpYkqRmGliSpGYaWJKkZhpYkqRl7xGmcJEl7ptmzLht52e3rT5xiJR1HWpKkZhhakqRmLBpaSc5PcmeSrfPmvTHJJ5Jcn+S9SQ6Yd9vZSW5J8skkPzWtwiVJK88oI623Ayfcb97lwBOr6geBTwFnAyQ5CjgN+P6+zVuT7LNk1UqSVrRFQ6uqrgS+eL9576+qnf3kVcDh/fWTgAur6utVdStwC3DMEtYrSVrBlmKf1i8D/9hfPwy4fd5tO/p53ybJuiSbk2yem5tbgjIkSXu7QaGV5DXATuCCXbMWWKwWaltVG6pqTVWtmZlZ8FeVJUm6j4m/p5VkLfAc4Piq2hVMO4DHzFvscOCzk5cnSdK3TDTSSnIC8GrgeVV197ybLgVOS/KwJEcCq4GPDi9TkqQRRlpJ3gkcBxycZAdwDt3Rgg8DLk8CcFVVvaiqbkxyEXAT3WbDF1fVN6dVvCRpZVk0tKrq+QvMPu9Bln898PohRUmStBDPiCFJaoahJUlqhqElSWqGoSVJaoahJUlqhqElSWqGoSVJaoahJUlqhqElSWqGoSVJaoahJUlqhqElSWqGoSVJaoahJUlqhqElSWqGoSVJaoahJUlqhqElSWqGoSVJaoahJUlqhqElSWqGoSVJaoahJUlqhqElSWqGoSVJaoahJUlqhqElSWqGoSVJaoahJUlqhqElSWqGoSVJasaioZXk/CR3Jtk6b96BSS5PcnN/+ch+fpL8SZJbklyf5EnTLF6StLKMMtJ6O3DC/eadBWyqqtXApn4a4FnA6v5vHfC2pSlTkqQRQquqrgS+eL/ZJwEb++sbgZPnzf+r6lwFHJDk0KUqVpK0sk26T+tRVXUHQH95SD//MOD2ecvt6Od9myTrkmxOsnlubm7CMiRJK8lSH4iRBebVQgtW1YaqWlNVa2ZmZpa4DEnS3mjS0Prcrs1+/eWd/fwdwGPmLXc48NnJy5Mk6VsmDa1LgbX99bXAJfPmn94fRXgs8JVdmxElSRpq1WILJHkncBxwcJIdwDnAeuCiJGcAtwGn9ou/D3g2cAtwN/DCKdQsSVqhFg2tqnr+A9x0/ALLFvDioUVJkrQQz4ghSWqGoSVJaoahJUlqhqElSWqGoSVJaoahJUlqhqElSWqGoSVJaoahJUlqhqElSWqGoSVJaoahJUlqhqElSWqGoSVJaoahJUlqhqElSWqGoSVJaoahJUlqhqElSWqGoSVJaoahJUlqhqElSWqGoSVJaoahJUlqhqElSWqGoSVJaoahJUlqhqElSWrGquUuQJI0fbNnXTbystvXnzjFSoZxpCVJaoahJUlqxqDQSvLKJDcm2ZrknUkenuTIJFcnuTnJu5I8dKmKlSStbBOHVpLDgJcBa6rqicA+wGnAG4A3V9Vq4EvAGUtRqCRJQzcPrgL2TbIK2A+4A3gGcHF/+0bg5IF9SJIEDAitqvpP4E3AbXRh9RVgC/DlqtrZL7YDOGyh9knWJdmcZPPc3NykZUiSVpAhmwcfCZwEHAk8GtgfeNYCi9ZC7atqQ1Wtqao1MzMzk5YhSVpBhmwefCZwa1XNVdU9wHuAHwEO6DcXAhwOfHZgjZIkAcNC6zbg2CT7JQlwPHATcAVwSr/MWuCSYSVKktQZsk/raroDLq4BbujvawPwauBVSW4BDgLOW4I6JUkadhqnqjoHOOd+sz8NHDPkfiVJWohnxJAkNcPQkiQ1w9CSJDXD0JIkNcPQkiQ1w9CSJDXD0JIkNcPQkiQ1w9CSJDXD0JIkNWPQaZwkSbvP7FmXjbX89vUnTqmS5eNIS5LUDENLktQMQ0uS1AxDS5LUDENLktQMQ0uS1AxDS5LUDENLktQMQ0uS1AxDS5LUDENLktQMQ0uS1AxDS5LUDENLktQMQ0uS1Ax/T0uSdjN/F2tyjrQkSc0wtCRJzTC0JEnNcJ+WJE1onH1T7pdaGoNGWkkOSHJxkk8k2ZbkqUkOTHJ5kpv7y0cuVbGSpJVt6ObBtwD/VFXfB/wQsA04C9hUVauBTf20JEmDTRxaSb4L+DHgPICq+kZVfRk4CdjYL7YROHlokZIkwbCR1uOAOeAvk1yb5Nwk+wOPqqo7APrLQxZqnGRdks1JNs/NzQ0oQ5K0UgwJrVXAk4C3VdXRwF2MsSmwqjZU1ZqqWjMzMzOgDEnSSjHk6MEdwI6qurqfvpgutD6X5NCquiPJocCdQ4uUpGnyKMB2TDzSqqr/Am5P8vh+1vHATcClwNp+3lrgkkEVSpLUG/o9rZcCFyR5KPBp4IV0QXhRkjOA24BTB/YhSRIwMLSq6jpgzQI3HT/kfiVJWoincZIkNcPQkiQ1w9CSJDXD0JIkNcOzvEvaK/hrwCuDIy1JUjMMLUlSMwwtSVIzDC1JUjMMLUlSMzx6UNIexaMA9WAcaUmSmmFoSZKaYWhJkpphaEmSmmFoSZKaYWhJkpphaEmSmmFoSZKaYWhJkpphaEmSmmFoSZKaYWhJkpphaEmSmmFoSZKaYWhJkpphaEmSmmFoSZKaYWhJkpqxarkLkLRnmz3rspGX3b7+xMHtpAfjSEuS1IzBoZVknyTXJvmHfvrIJFcnuTnJu5I8dHiZkiQtzUjr5cC2edNvAN5cVauBLwFnLEEfkiQNC60khwMnAuf20wGeAVzcL7IROHlIH5Ik7TJ0pPXHwG8B9/bTBwFfrqqd/fQO4LCBfUiSBAw4ejDJc4A7q2pLkuN2zV5g0XqA9uuAdQBHHHHEpGVIGsE4R/KBR/NpzzVkpPU04HlJtgMX0m0W/GPggCS7wvBw4LMLNa6qDVW1pqrWzMzMDChDkrRSTBxaVXV2VR1eVbPAacAHquoXgCuAU/rF1gKXDK5SkiSm8z2tVwOvSnIL3T6u86bQhyRpBVqSM2JU1QeBD/bXPw0csxT3K0nSfJ4RQ5LUDENLktQMQ0uS1AxDS5LUDENLktQMf09LaohnttBK50hLktQMR1rSMvBXfaXJONKSJDXD0JIkNcPQkiQ1w9CSJDXD0JIkNcPQkiQ1w9CSJDXD0JIkNcPQkiQ1w9CSJDXD0JIkNcPQkiQ1w9CSJDXD0JIkNcPQkiQ1w9CSJDXD0JIkNcPQkiQ1w9CSJDXD0JIkNcPQkiQ1w9CSJDXD0JIkNWPi0ErymCRXJNmW5MYkL+/nH5jk8iQ395ePXLpyJUkr2ZCR1k7gN6rqCcCxwIuTHAWcBWyqqtXApn5akqTBVk3asKruAO7or381yTbgMOAk4Lh+sY3AB4FXD6pS2kPNnnXZyMtuX3/iFCuRVoYl2aeVZBY4GrgaeFQfaLuC7ZCl6EOSpMGhleQRwLuBV1TVf4/Rbl2SzUk2z83NDS1DkrQCDAqtJA+hC6wLquo9/ezPJTm0v/1Q4M6F2lbVhqpaU1VrZmZmhpQhSVohJt6nlSTAecC2qvqjeTddCqwF1veXlwyqUJqycfZLgfumpOU0cWgBTwN+CbghyXX9vN+mC6uLkpwB3AacOqxESZI6Q44e/DcgD3Dz8ZPeryRJD8QzYkiSmmFoSZKaYWhJkpox5EAMaY/iUYDS3s+RliSpGY60tMfxfH6SHogjLUlSMxxp6UEN2U/kiEnSUnOkJUlqhqElSWqGoSVJaoahJUlqhqElSWqGoSVJaoahJUlqhqElSWqGoSVJaoZnxFghPAO6pL2BIy1JUjMcaTXG8/lJWskcaUmSmuFIa5k4YpKk8TnSkiQ1w9CSJDXD0JIkNcPQkiQ1w9CSJDXDowcH8CwTkrR7OdKSJDXD0JIkNcPQkiQ1Y2r7tJKcALwF2Ac4t6rWT6uvodw3JUltmMpIK8k+wJ8CzwKOAp6f5Khp9CVJWjmmNdI6Brilqj4NkORC4CTgpin1B3g+P0na201rn9ZhwO3zpnf08yRJmliqaunvNDkV+Kmq+pV++peAY6rqpfOWWQes6ycfD3xyyQv5loOBz+/F7ZajTx/j0rdbjj59jEvfbjn6bOkxjuKxVTWz4C1VteR/wFOBf543fTZw9jT6GrGezXtzu5Zq9THuWX36GH2Mu/sxDv2b1ubBjwGrkxyZ5KHAacClU+pLkrRCTOVAjKrameQlwD/THfJ+flXdOI2+JEkrx9S+p1VV7wPeN637H9OGvbzdcvTpY1z6dsvRp49x6dstR58tPcZBpnIghiRJ0+BpnCRJzTC0piTJh3dTP7NJtu6OvoZopc6lkORlSbYluWC5a1lMkq8NbP/aJGeOsNyg1393vZ9WkiQHJPn15a5jXIbWlFTVjyx3DVo2vw48u6p+YbkL2Vv4fhpNOqP+Xz+Abl1tyl4bWklelOS6/u/WJFeM2O4pSa5P8vAk+ye5MckTJ+h/rE+wSX43ySeSXJ7knaN8el3gPh6X5NokT1lkuTfM/4TVf1r+jUXazPb1nZtka5ILkjwzyb8nuTnJMSOUuCrJxv75vTjJfov0+VtJXtZff3OSD/TXj0/yjsU6m1fzOH3+XpKXz5t+/a4aRpHkz4DHAZcmeeUY7U7va/x4kr8eo919RjBJzkzy2lHbTyLJa5J8Msm/0J0YYFT7JPmL/j31/iT7jtHn2CPC/v17Wf+cbk3ycyO2m+1HymPXmuRVfV9bk7xijFr/LsmWvr91i7dYsN63AtcAjxmx6Xrge/v/kW8co79fTPLRvt2fpzvX7O6zHF8O251/wEOADwHPHaPN7wNvojvp70Rfiga+Nsaya4DrgH2B7wRuBs4cse0ssJXun8e1wA+P0OZo4F/nTd8EHDFCPzuBH6D7sLMFOB8I3Xkl/26E9gU8rZ8+f7HHCBwL/G1//UPAR/vX8xzgV0d8bsbtcxa4pr/+HcB/AAeN+dpvBw4eY/nvpzsjzMH99IFjtJ0Fts6bPhN47TTW0375JwM3APsB3wXcMsq6Om/9+eF++iLgF6dVZ9/mZ4C/mDf93WM8p2PXOu+52R94BHAjcPSIfR7YX+7bv59HXuf6eu8Fjh3z+bnPujNimycAfw88pJ9+K3D6uK/NkL+9dqQ1z1uAD1TV34/R5nXAT9CFyR9Opar7+lHgkqr6n6r6Kt1KMY4Z4BK6N9Z1iy1cVdcChyR5dJIfAr5UVbeN0M+tVXVDVd1L94bcVN2aewPdG2Axt1fVv/fX30H3uB/MFuDJSb4T+DrwEbrX5Ol0ITaKsfqsqu3AF5IcDfwkcG1VfWHEvib1DODiqvp8X8MXp9zfEE8H3ltVd1fVfzPeSQNunbd+bmG0dWaIG4Bn9lsWnl5VXxmj7SS1/ijdc3NXVX0NeA/d8zWKlyX5OHAV3Uhp9Ri1Anymqq4as80kjqcL548lua6fftxu6Pf/Te17WnuCJC8AHgu8ZMymB9J9UnoI8HDgrqWt7NtkYPuv0J2g+Gl0YTKKi4FTgO8BLhyxzdfnXb933vS9jLYu3f/7FQ/6fYuquifJduCFwIeB64EfB74X2DZCf2P32TsXeAHdc3P+iP0MEUarayE7ue9m/ocPL2dRk9Y6f/35Jt2oYmqq6lNJngw8G/iDJO+vqteN2HySWid6Hyc5Dngm8NSqujvJBxn/dZz2/6hdAmysqrN3U3/fZq8dafUr65l0o497x2y+Afhd4ALgDUtd2wL+DXhuvx/tEcC4v5vyDeBk4PQkPz9imwvpTq91Cl2A7Q5HJHlqf/35dI97MVfSvY5X0o2uXgRc14/wptXne4ETgKfQndVl2jYBP5vkIIAkB47R9nN0o+aDkjwMeM40CpznSuCnk+zbj4CfO+X+Jpbk0cDdVfUOus39T5pyl1cCJyfZL8n+wE8z2haB76bb2nF3ku+j2yy+O3yVbnfEODYBpyQ5BLp1Ncljl7yyB7E3j7ReQjdiuiIJdCd3/JXFGiU5HdhZVX/T72D8cJJnVNUHxux/5E+jVfWxJJcCHwc+A2ymGz2N3lnVXUmeA1ye5K6qumSR5W/s/+n8Z1XdMU5fA2wD1ib5c7r9dm8boc2HgNcAH+kf4/8y+qbBifqsqm+kO3Dny1X1zTH6mkj/Wrwe+Nck36TbN/mCEdvek+R1wNXArcAnplZo1981Sd5Ftw/2M4z3WuxuPwC8Mcm9wD3Ar02zs/65eTvdvlfofrH92hGa/hPwoiTX0+3b3B2b+aiqL/QHUm0F/rGqfnOENjcl+R3g/emOUrwHeDHdurBbeEaMKeg/MV9TVSN/AknyiKr6Wn9025XAuqq6ZmpFrgBJZoF/qKqxjv7s34zXAKdW1c1TKE3ShPbazYPLpd8k8RG6zRHj2NDv2LwGeLeBtTySHEV3RNwmA0va8zjSkiQ1w5GWJKkZhpYkqRmGliSpGYaWJKkZhpYkqRmGliSpGf8H83I2pfa/h6UAAAAASUVORK5CYII=\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/2020-a-challenge7.ipynb b/2020-early/2020-a-challenge7.ipynb
new file mode 100644 (file)
index 0000000..b03b217
--- /dev/null
@@ -0,0 +1,376 @@
+{
+ "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": 9,
+   "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",
+    "from cipher.vigenere 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 = 7\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": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'soe'"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kworda, score = vigenere_frequency_break(sca, fitness=Ptrigrams)\n",
+    "kworda"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Phil,\n",
+      "Sorry I haven’t been in touch much, Churchill asked BOSS to set up an operations wing in the UK under the name of the Special Operations Executive and that has occupied a lot of my time. As soon as we got set up I was put in touch with Einar Skinnarland, an engineer from Vemork who had hijacked a coastal steamer and sailed to Aberdeen to join the war effort here. Churchill ordered us to work up plans to attack the plant and Einar helped us to brief an intelligence gathering team to infiltrate the region. Operation Grouse was launched in October with an advance party of four officers and NCOs led by Jens-Anton Poulsson. They were parachuted into the Hardangervidda as German patrols tended to avoid it, and after a period of observation they prepared the ground for a glider assault. Under the codename Operation Freshman we sent over two gliders carrying commandos equipped with explosives and everything they needed to effect an escape, but a combination of bad weather and bad luck killed the mission. Both gliders made it to the Norwegian coast, but one crashed early on, and the other in the mountains. We were not aware of survivors, and unfortunately the Germans now knew that the plant was a target and stepped up security. They lit up the place with floodlights, mined the approaches and, for a while, stepped up the guard rotas. Grouse volunteered to stay in place, changing their callsign to Swallow and continued to send intelligence reports. They reported that although the mines and lights were still in place there were signs that security was beginning to slacken.\n",
+      "With these updates we decided to try again, and launched Operation Gunnerside. Six Norwegian commandos led by Joachim Ronnenberg were parachuted in from an RAF Halifax and joined up with Swallow. The attached document is their mission report. They sent it from the plateau while retreating from the plant in case they didn’t make it back, so have used a standard combination of basic ciphers to make it hard to crack but easy to implement. In training we recommended a combination of Casear shift and basic transposition. I leave it to you to decipher.\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "ppa = vigenere_decipher(sca, kworda)\n",
+    "pa = repunctuate(ppa, pta)\n",
+    "print(pa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2147"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_a_filename, 'w').write(pa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "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": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "10"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kcb, score = caesar_break(scb, fitness=Pletters)\n",
+    "kcb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'etrroopoarnetponuignnredeifsoawrslmotflaewrvorceeiusrgpnlfsperimmeohitscnsooitennirarrsdpoonebnnresmagestttteuooopujnwitawislhoehlttwomawestetfmaetsrervaedoslyfarcscsoonsyurktinaigdnhratptemieydtawotsyvamwkerholtaipreldaohrsddeecfuoehrthmgerifqhetyuchntweahetrhchatmslbeaithofsdleognlioweitpaorfhsnemrnbeahrtdpsieagntgnnhirnieveavhtoreeaermamnifdaeunlaulgryedndatdemmhoacdornguofttplhetriadeatascsuatlulodwerpbnouuvidtectdsiaewitdcehdtaeatmahdlsudosdneetcodnwurhdeteermitosthnrnieveaohtfderibrreevodnlacwihtlbeminohltlesrhaifeerdnaohtgcnhirreevbidawetsiotdfnouessboiplfobtoelsalwiogrtnealkdocosgaawrlyinhtioetlatpnnatnedethycsraawrodreuiwohttuieuotcnnegntiaryranudgtolsechlssaoabenigttnenahltpuilspepdiadtlednaelspnhcaseduasdenltardeihiapdgrnydetstuagohtatntriuhfrececsavcasaailnubtnelwdeniadnenwcoureotingylnntoeerhatckojarhenwnaehsaapoatsicirtnorigoeawwomnsratwneaihltglnoiorecpaoesethatppsprlecimadneshteitwmufidseshteneolrtecoeycslihsmsraeabpnnsaeltaydelhotfsealhsptmoosamnbcuiughenntseahctnpoetrevahottehawtssinatatcabirkbtysroifchsepeofhlhtuyalwpltlrivrteneerlapssigsnaitahcotlaeseelhxtlvipseohegcrsaeandottdtseerdytgonhietceerllsioseyuemqpniahttdendecaanjsartogtcbmeaehscerhotbdemntialiewlmolpnsiwutntiophgeterruetosapaehmsaiiuodgtnodetwesfxenrfoltairitnmaoebtiehwlaltlsdoooonitoujwmhptiioetlgarcllmirwmineinaliepcnahgetriendnoeipgtrnuhfrtsenricnouist'"
+      ]
+     },
+     "execution_count": 20,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ccb = caesar_decipher(scb, kcb)\n",
+    "ccb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(((1, 5, 4, 0, 3, 6, 2), False, False), -4551.751064338015)"
+      ]
+     },
+     "execution_count": 21,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(kwordb, fillb, emptyb), score = column_transposition_break_mp(ccb, fitness=Ptrigrams)\n",
+    "(kwordb, fillb, emptyb), score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'reportonoperationgunnersidefromswallowafterrecoveringsuppliesfromthemissioncontainerdropsronnenbergsteamsetouttojoinupwithswallowthetwoteamsmetafterseveraldaysofcrosscountryskiingandthepartymadeitswaytovemorkwhilepatrolshadreducedfromthehighfrequencythatthewehrmachtestablishedfollowingoperationfreshmanthebridgespanningtheravineoverthemanaremainedfullyguardedandthecommandogroupfeltthatadirectassaultwouldbeunproductiveitwasdecidedthatateamshoulddescendtwohundredmetersintotheravinefordtheriverbelowandclimbthehillonthefarsideonreachingtheriverbeditwasfoundtobepossibletofollowasingletrackgoodsrailwayintotheplantandtheentrywascarriedoutwithoutencounteringanyguardsthelocalbossagentintheplantsupplieddetailedplansandschedulesandtheraidingpartyusedthattogainfurtheraccessviaacabletunnelandwindowencounteringonlythecaretakerjohansenwhoasapatrioticnorwegianwasmorethanwillingtocooperatethesappersplacedmineswithtimedfusesontheelectrolysischambersasplannedtheyalsoleftathompsonsubmachinegunatthescenetoprovethatthiswasanattackbybritishforceshopefullythatwillpreventreprisalsagainstthelocalstheexplosivechargesdetonateddestroyingtheelectrolysisequipmentandtheadjacentstoragechambersthecombinedteamwillnowsplitupintothreegroupsteamaisheadingouttoswedenforexfiltrationteambwillheadtooslotojoinupwithmilorgteamcwillremaininplaceintheregionpendingfurtherinstructions'"
+      ]
+     },
+     "execution_count": 22,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pb = column_transposition_decipher(ccb, kwordb, fillcolumnwise=fillb, emptycolumnwise=emptyb)\n",
+    "pb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "report on operation gunner side from swallow after recovering supplies from the mission container\n",
+      "drops ronn enberg steam set out to join up with swallow the two teams met after several days of\n",
+      "crosscountry skiing and the party made its way to ve mork while patrols had reduced from the high\n",
+      "frequency that the wehrmacht established following operation freshman the bridge spanning the ravine\n",
+      "over the man a remained fully guarded and the commando group felt that a direct assault would be\n",
+      "unproductive it was decided that a team should descend two hundred meters into the ravine ford the\n",
+      "river below and climb the hill on the farside on reaching the riverbed it was found to be possible\n",
+      "to follow a singletrack goods railway into the plant and the entry was carried out without\n",
+      "encountering any guards the local boss agent in the plant supplied detailed plans and schedules and\n",
+      "the raiding party used that to gain further access via a cable tunnel and window encountering only\n",
+      "the caretaker johansen who as a patriotic norwegian was more than willing to cooperate the sappers\n",
+      "placed mines with timed fuses on the electrolysis chambers as planned they also left a thompson sub\n",
+      "machinegun at the scene to prove that this was an attack by british forces hopefully that will\n",
+      "prevent reprisals against the locals the explosive charges detonated destroying the electrolysis\n",
+      "equipment and the adjacent storage chambers the combined team will now split up into three groups\n",
+      "team a is heading out to sweden for exfiltration team b will head to oslo to join up with mil org\n",
+      "team c will remain in place in the region pending further instructions\n"
+     ]
+    }
+   ],
+   "source": [
+    "fpb = lcat(tpack(segment(pb)))\n",
+    "print(fpb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1635"
+      ]
+     },
+     "execution_count": 24,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_b_filename, 'w').write(fpb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['hatreds',\n",
+       " 'lauries',\n",
+       " 'patrols',\n",
+       " 'patrons',\n",
+       " 'petrols',\n",
+       " 'fatheads',\n",
+       " 'lawmaker',\n",
+       " 'occupier',\n",
+       " 'occupies',\n",
+       " 'patricas',\n",
+       " 'payrolls',\n",
+       " 'odourless',\n",
+       " 'patricias',\n",
+       " 'petrifies']"
+      ]
+     },
+     "execution_count": 25,
+     "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-challenge7.md b/2020-early/2020-a-challenge7.md
new file mode 100644 (file)
index 0000000..e3549f9
--- /dev/null
@@ -0,0 +1,117 @@
+---
+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 cipher.vigenere import *
+
+from support.text_prettify import *
+from support.utilities import *
+from support.plot_frequency_histogram import *
+%matplotlib inline
+```
+
+```python
+challenge_number = 7
+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, score = vigenere_frequency_break(sca, fitness=Ptrigrams)
+kworda
+```
+
+```python
+ppa = vigenere_decipher(sca, kworda)
+pa = repunctuate(ppa, pta)
+print(pa)
+```
+
+```python
+open(plaintext_a_filename, 'w').write(pa)
+```
+
+```python
+fc = collections.Counter(scb)
+plot_frequency_histogram(fc, sort_key=fc.get)
+```
+
+```python
+kcb, score = caesar_break(scb, fitness=Pletters)
+kcb
+```
+
+```python
+ccb = caesar_decipher(scb, kcb)
+ccb
+```
+
+```python
+(kwordb, fillb, emptyb), score = column_transposition_break_mp(ccb, fitness=Ptrigrams)
+(kwordb, fillb, emptyb), score
+```
+
+```python
+pb = column_transposition_decipher(ccb, 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/2020-a-challenge8.ipynb b/2020-early/2020-a-challenge8.ipynb
new file mode 100644 (file)
index 0000000..9789c1e
--- /dev/null
@@ -0,0 +1,405 @@
+{
+ "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",
+    "from cipher.vigenere 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 = 8\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": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/home/neil/Programming/cipher-tools/support/plot_frequency_histogram.py:11: UserWarning: Matplotlib is currently using module://ipykernel.pylab.backend_inline, which is a non-GUI backend, so cannot show the figure.\n",
+      "  f.show()\n"
+     ]
+    },
+    {
+     "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": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'low'"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kworda, score = vigenere_frequency_break(sca, fitness=Ptrigrams)\n",
+    "kworda"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'harrywemanagedtotapthephonelinesinosloandinterceptedgermanmilitarypolicereportstothessheadquarterstheyestablishedthatthegunnersideoperationwaseffectiveinwipingouttheexistingstocksofheavywaterbutthatthenaziengineerswereabletorestartproductionthiswasconfirmedincommunicationssmuggledoutoftheplantbyjomarbrunandeinnarskinnerlandthechiefengineeranddesigneroftheplantwhoarestillworkingthereassoeagentstheinformationwassenttointelligenceheadquartersinlondonintoothpastetubesusingacipherdevelopedforbossbyleomarksthisintelligencewaspassedtousaafwhostartedtodevelopaplantobombtheplantrunningtheriskofsignificantcivilianlossesluckilyoneofourbossofficialsspottedthemaponthewallofabriefingroomduringaprotocolvisitandrealisedwhatitwasheflaggedtheoperationandgotmeinvolvediwasabletocontactswallowviatheoslobranchofmilorgandwehavebeenworkingtogetherwithusaaftorefinethemissiondespitetheriskstheyagreedtoadaylightraidinthehopethattheaddedaccuracywouldreducenorwegiancasualtiesunfortunatelytheraidwasamixedsuccessasyoucanseefromtheattachedreportitisdoubleencryptedagainbutwasalottoughertocracktheyhaveusedanaffineshiftforthesubstitutionphasebeforeusingthesamesortoftranspositiontakealookandletmeknowwhatyouthinkmeanwhileiwilltrytocontactronnenbergtoseewhathewantstodonextgiventheneedtoprotectournetworkiwillincreasethekeylengthformymessagetoyounextweektoatleastsix'"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pa = vigenere_decipher(sca, kworda)\n",
+    "pa"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "harry we managed to tap the phone lines in oslo and intercepted german military police reports to\n",
+      "the ss headquarters they established that the gunner side operation was effective in wiping out the\n",
+      "existing stocks of heavy water but that the nazi engineers were able to restart production this was\n",
+      "confirmed in communications smuggled out of the plant by jomar brun and e in nar skinner land the\n",
+      "chief engineer and designer of the plant who are still working there as soe agents the information\n",
+      "was sent to intelligence headquarters in london in toothpaste tubes using a cipher developed for\n",
+      "boss by leo marks this intelligence was passed to usaaf who started to develop a plan to bomb the\n",
+      "plant running the risk of significant civilian losses luckily one of our boss officials spotted the\n",
+      "map on the wall of a briefing room during a protocol visit and realised what it was he flagged the\n",
+      "operation and got me involved i was able to contact swallow via the oslo branch of mil org and we\n",
+      "have been working together with usaaf to refine the mission despite the risks they agreed to a\n",
+      "daylight raid in the hope that the added accuracy would reduce norwegian casualties unfortunately\n",
+      "the raid was a mixed success as you can see from the attached report it is double encrypted again\n",
+      "but was alot tougher to crack they have used an affine shift for the substitution phase before using\n",
+      "the same sort of transposition take a look and let me know what you think meanwhile i will try to\n",
+      "contact ronn enberg to see what he wants to do next given the need to protect our network i will\n",
+      "increase the key length for my message to you next week to atleast six\n"
+     ]
+    }
+   ],
+   "source": [
+    "fpa = lcat(tpack(segment(pa)))\n",
+    "print(fpa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1644"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_a_filename, 'w').write(fpa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "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": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(11, 5, True)"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(kmb, kab, kob), score = affine_break(scb, fitness=Pletters)\n",
+    "kmb, kab, kob"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'etmhbnboiagoriendvrmaokaswciroredudtiudrnlagyhingtvnoobesmetirxnetetahheatstcaqkuodornincsisotnhfgttinreapelsnlesiiptonottogwrsucpeahamnkwiguotronhsnaetterwgtchsiphaapdreebthoeoetnkrdshpryoeotwriastaotnnnhderietaaptltnethiermsltetehoetaesttahtkascwtnaorfeoenesnwoirantsirtpecdteeabcyieorvnrladflaoetthakatcgirnaacirsfmtehteoeatvrnuerfemdretohsmoisynieieewtesnstsesaatthntrittmeintletdocuvcaoeeprpeaordsdtiprhuttetactuakhtbtaermjyiottoefhlxepiossvoaerduintyrhtnteosdrweprdoptweiehhvrhiygcaacuocryhniteatnrptnelntaotltywhooternetisohhtoterwpeasottnniahdetefirncosreutdrucwtrhietosttowhdesofrtetohsalsahtutoesbmifbadldetaaomtgrehueebtiuldrteemieuercltyoslscfiaiialtonydnusrectwookesfyahvtwwaeeerropcrtdteetbsyheeevtnesooyrseffriconrcecdotrnebeeaowhvoeehvroetprwaepinltethslbafsnemedeaagndhadsitsoercndaditopnhnleaaterihsstoeipslbsiyiattuthonrieehemseaevasngtrwnokigiwitthndiincissunisotwfihcfoilirasdofmaiheliecmesrtnpoguhibtanesecdeeihddttafthiaectlhiylosuedubsothdewsnxntiitgksofscoahweveaytnroadstpausyimodhrdxiieblwlhepsitepdhortebliaaorrtsioedannmauafucntragiflciiiietsenagrfnmyfotrurhrerehninmcentxadrpeeeiamnottiinngvetehsrfikclooeailsaopnwgieenlwldesetniogiinfcytalhecnaeensrcyuirftoitphsaeorotiinlnfawlhyelosuodtnttheaetthakatclkdiletewynetornnogwneivcaiiislaitnhsslivbuaaplperaaoganddaronueasgneatridtonihgeerhbseetrdalnidonntonnorseuhettanhtewoirepagnuotplniaodusnentrawdishosotabflmtoersheeelendseasdsteh'"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "acb = affine_decipher(scb, kmb, kab, kob)\n",
+    "acb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(((2, 0, 5, 1, 3, 8, 6, 4, 7), False, False), -4688.2791775857195)"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(kwordb, fillb, emptyb), score = column_transposition_break_mp(acb, fitness=Ptrigrams)\n",
+    "(kwordb, fillb, emptyb), score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'thebombingraidonvemorkwascarriedoutduringdaylightonnovembersixteenththeattacksquadronconsistingofthirteenplanessplitintotwogroupseachmakingtworunsonthetargetswhichappearedtobethenorskhydropowerstationandthenitrateplantthreemilestotheeasttheattackwasnotforeseennorwasitinterceptedbyaircoverandalloftheattackingaircraftseemtohavereturnedfromthemissioneyewitnessesstatethatintermittentcloudcoverappearedtodisrupttheattackbutthemajorityoftheexplosivesaroundthirtytonsweredroppedwithveryhighaccuracyonthenitrateplantonlytwotothreetonshitthepowerstationandthereinforcedstructurewithstoodtheworstoftheassaultthebombsfailedtodamagetherebuiltdeuteriumelectrolysisfacilityandournewstocksofheavywaterwereprotectedbythesevenstoreysofreinforcedconcreteabovehoweverthepowerplantitselfhasbeendamagedandthissecondraidontheplantraisesthepossibilitythatourenemieshaveagentsworkingwithinitindiscussionwithofficialsfromdiealchemistengroupithasbeendecidedthatthefacilityshouldbeshutdownexistingstocksofheavywaterandpotassiumhydroxidewillbeshippedtotheirlaboratoriesandmanufacturingfacilitiesingermanyforfurtherenrichmentandexperimentationgiventheriskoflocalespionagewewillneedtosignificantlyenhancesecurityforthisoperationfinallyweshouldnotethattheattackkilledtwentyonenorwegianciviliansthisisvaluablepropagandaandouragentsaredoingtheirbesthereandinlondontoensurethatthenorwegianpopulationunderstandswhoistoblamefortheseneedlessdeaths'"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pb = column_transposition_decipher(acb, kwordb, fillcolumnwise=fillb, emptycolumnwise=emptyb)\n",
+    "pb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "the bombing raid on ve mork was carried out during daylight on november sixteenth the attack\n",
+      "squadron consisting of thirteen planes split into two groups each making two runs on the targets\n",
+      "which appeared to be the norsk hydropower station and the nitrate plant three miles to the east the\n",
+      "attack was not foreseen nor was it intercepted by air cover and all of the attacking aircraft seem\n",
+      "to have returned from the mission eyewitnesses state that intermittent cloud cover appeared to\n",
+      "disrupt the attack but the majority of the explosives around thirty tons were dropped with very high\n",
+      "accuracy on the nitrate plant only two to three tons hit the powerstation and the reinforced\n",
+      "structure withstood the worst of the assault the bombs failed to damage the rebuilt deuterium\n",
+      "electrolysis facility and our new stocks of heavy water were protected by the seven storeys of\n",
+      "reinforced concrete above however the powerplant itself has been damaged and this second raid on the\n",
+      "plant raises the possibility that our enemies have agents working within it in discussion with\n",
+      "officials from die alchemist en group it has been decided that the facility should be shutdown\n",
+      "existing stocks of heavy water and potassium hydroxide will be shipped to their laboratories and\n",
+      "manufacturing facilities in germany for further enrichment and experimentation given the risk of\n",
+      "local espionage we will need to significantly enhance security for this operation finally we should\n",
+      "note that the attack killed twentyone norwegian civilians this is valuable propaganda and our agents\n",
+      "are doing their best here and in london to ensure that the norwegian population understands who is\n",
+      "to blame for these needless deaths\n"
+     ]
+    }
+   ],
+   "source": [
+    "fpb = lcat(tpack(segment(pb)))\n",
+    "print(fpb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1686"
+      ]
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_b_filename, 'w').write(fpb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['clampdown']"
+      ]
+     },
+     "execution_count": 18,
+     "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-challenge8.md b/2020-early/2020-a-challenge8.md
new file mode 100644 (file)
index 0000000..1b8cd88
--- /dev/null
@@ -0,0 +1,121 @@
+---
+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 cipher.vigenere import *
+
+from support.text_prettify import *
+from support.utilities import *
+from support.plot_frequency_histogram import *
+%matplotlib inline
+```
+
+```python
+challenge_number = 8
+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, score = vigenere_frequency_break(sca, fitness=Ptrigrams)
+kworda
+```
+
+```python
+pa = vigenere_decipher(sca, kworda)
+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
+(kmb, kab, kob), score = affine_break(scb, fitness=Pletters)
+kmb, kab, kob
+```
+
+```python
+acb = affine_decipher(scb, kmb, kab, kob)
+acb
+```
+
+```python
+(kwordb, fillb, emptyb), score = column_transposition_break_mp(acb, fitness=Ptrigrams)
+(kwordb, fillb, emptyb), score
+```
+
+```python
+pb = column_transposition_decipher(acb, 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/2020-a-challenge9.ipynb b/2020-early/2020-a-challenge9.ipynb
new file mode 100644 (file)
index 0000000..247de73
--- /dev/null
@@ -0,0 +1,638 @@
+{
+ "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": 31,
+   "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",
+    "from cipher.vigenere import *\n",
+    "from cipher.autokey 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 = 9\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": [
+       "'brimstone'"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kworda, score = vigenere_frequency_break(sca, fitness=Ptrigrams)\n",
+    "kworda"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'harrywereceivedfurtherencouragingreportsfromswallowabouttheeffectsoftheusaafraidthesecondarytargetsoftheattackwerethestationatrjukantheindustrialtracksandthetracktovemorkwhiletherailwaytracksthemselvesremainoperationalaconsiderableamountofrollingstockwasseriouslydamagedwithtwolocomotiveseightcargowagonsandsevenpassengerwagonssufferingdamageouragentsintheplanthaveconfirmedthatthishasslowedthegermanplantoshiptheremainingstocksofpotassiumperoxidetodiealchemistenresearchfacilitiesinberlininpreparationfortheshipmentciviliansarenolongerallowedaccesstotherailwayandpatrolshavebeensteppedupsecurityatalltherailwaystationshasbeensignificantlyincreasedswallowhavematchedthisbyincreasingtheirownsurveillanceontherjukanlineandproposedanumberofplanstointercepttheshipmentbuttheenhancedsecuritymakeitveryunlikelythatastandardsabotagewouldsucceedindoingmorethandelayingtheshipmentalternativesincludingthelocalferryroutesarebeingactivelyconsideredaswiththeairraidciviliancasualtiesareamajorconsiderationbuttheplantdirectorbjarnenilssenissympatheticandmaybeabletoinfluencethedateandtimeofshipmentinordertoreducetheriskoncemoreouragentshavebeensuccessfulininterceptingenemycommunicationsconcerningthemissionandtheenclosedtelegramsummarisingtheplansconfirmsourowninvestigationswiththisinhandithinktheswallowteamwillbeabletoexecuteasuccessfulsabotageandhopefullyterminatethegermannuclearweaponsprogramletshopewecanendthissoonphil'"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pa = vigenere_decipher(sca, kworda)\n",
+    "pa"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "harry we received further encouraging reports from swallow about the effects of the usa afraid the\n",
+      "secondary targets of the attack were the station at rj uk an the industrial tracks and the track to\n",
+      "ve mork while the railway tracks themselves remain operational a considerable amount of rolling\n",
+      "stock was seriously damaged with two locomotives eight cargo wagons and seven passenger wagons\n",
+      "suffering damage our agents in the plant have confirmed that this has slowed the german plan to ship\n",
+      "the remaining stocks of potassium peroxide to die alchemist en research facilities in berlin in\n",
+      "preparation for the shipment civilians are no longer allowed access to the railway and patrols have\n",
+      "been stepped up security at all the railway stations has been significantly increased swallow have\n",
+      "matched this by increasing their own surveillance on the rj uk an line and proposed a number of\n",
+      "plans to intercept the shipment but the enhanced security make it very unlikely that a standard\n",
+      "sabotage would succeed in doing more than delaying the shipment alternatives including the local\n",
+      "ferry routes are being actively considered as with the air raid civilian casualties area major\n",
+      "consideration but the plant director bjarne nilssen is sympathetic and maybe able to influence the\n",
+      "dateandtime of shipment in order to reduce the risk once more our agents have been successful in\n",
+      "intercepting enemy communications concerning the mission and the enclosed telegram summarising the\n",
+      "plans confirms our own investigations with this in hand i think the swallow team will be able to\n",
+      "execute a successful sabotage and hopefully terminate the german nuclear weapons program lets hope\n",
+      "we can end this soon phil\n"
+     ]
+    }
+   ],
+   "source": [
+    "fpa = lcat(tpack(segment(pa)))\n",
+    "print(fpa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1686"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_a_filename, 'w').write(fpa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'.-': 'A',\n",
+       " '-...': 'B',\n",
+       " '-.-.': 'C',\n",
+       " '-..': 'D',\n",
+       " '.': 'E',\n",
+       " '..-.': 'F',\n",
+       " '--.': 'G',\n",
+       " '....': 'H',\n",
+       " '..': 'I',\n",
+       " '.---': 'J',\n",
+       " '-.-': 'K',\n",
+       " '.-..': 'L',\n",
+       " '--': 'M',\n",
+       " '-.': 'N',\n",
+       " '---': 'O',\n",
+       " '.--.': 'P',\n",
+       " '--.-': 'Q',\n",
+       " '.-.': 'R',\n",
+       " '...': 'S',\n",
+       " '-': 'T',\n",
+       " '..-': 'U',\n",
+       " '...-': 'V',\n",
+       " '.--': 'W',\n",
+       " '-..-': 'X',\n",
+       " '-.--': 'Y',\n",
+       " '--..': 'Z',\n",
+       " '-----': '0',\n",
+       " '.----': '1',\n",
+       " '..---': '2',\n",
+       " '...--': '3',\n",
+       " '....-': '4',\n",
+       " '.....': '5',\n",
+       " '-....': '6',\n",
+       " '--...': '7',\n",
+       " '---..': '8',\n",
+       " '----.': '9',\n",
+       " '.-.-.-': '.',\n",
+       " '--..--': ',',\n",
+       " '..--..': '?',\n",
+       " '-....-': '-',\n",
+       " '-..-.': '/',\n",
+       " '---...': ':',\n",
+       " '.----.': \"'\",\n",
+       " '-.--.-': ')',\n",
+       " '-.-.-': ';',\n",
+       " '-.--.': '(',\n",
+       " '-...-': '=',\n",
+       " '.--.-.': '@'}"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "morse_letters = {}\n",
+    "morse_codes = {}\n",
+    "with open('morse.txt') as f:\n",
+    "    for line in f.readlines():\n",
+    "        l, c = line.split()\n",
+    "        morse_letters[c] = l\n",
+    "        morse_codes[l] = c\n",
+    "morse_letters"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'XBGGFOTDIVUATUBGGFM VQ FRRUGLQDWH STIVEXMSRW KTW YNOVSKTZ VM BPM ENVXAT ZBYNEMD EZ FTQ SNGUREYNAQ GHCD LTWGBPRWIHIGTXUTCSXTCHI FUHIEDDUB KF ESAFLSAF LMTMBHG MYWOLCNS NOJK SWYD YXQXFIILK RM GZUD RESPONSIBILITY GPS UGEWTKVA RI XLI WTQQNSL YZUIQ ZAVW LQM JULQNVRBCNW DY CPELTY AHQDMXX PBZZNAQ CT IWT CYIIYED JKFG GHWJSLAGFSD VHGMKHE FCYM RDOC PDA CBIADBKAXOJBOFB QRMN SQZBJ AND USBJO UGEWTKVA LV XLI WJXUTSXNGNQNYD UL GBNDHJO ABWX LXDWCNARWCNUURPNWLN DY MP FTQ ERFCBAFVOVYVGL CT IWT QRMUXH JKFG AFLWDDAYWFUW VHGVXKGBGZ UFF VNKZXON KB QEB KGQQGML SN BE DPPSEJOBUFE XKC WKH WMGLIVLIMXWHMIRWX XYTU VRGTZ KPYLJAVY JRIZVM WRUBBNW SC CPDAZYDTMWP RAD CERCNENGVBA CT IWT IXYFCUDJ JKFG ZW ATL CHZILGYX PN PDWP EB UGJJ AD READY UP UJKR WKH MXIQ TS YATJGE ADLUAPLAO NMJZCIZG BCXY OFOBIYXO TYGZWGPO UZ GUR GVWDASBH ID RU MVKKVU TQ MAX FIWUF NXCPOUNOVAAZG OPKL OBMLOQP MD ZMX RESISTANCE BDUJWJUZ CTG WR FI KTWBFWIJI ZU AOL IJEMPZ BCXY MKCUC EZ NQ ERJRVTURQ OH GYJZPC JE VEJLIV LZW EHTW BUM IJO XAAJ QXJMBOBA UGRF RSNO HANDOVER UP DG PRQLWRUHG GPSWIPC FY KBKXE ZAHNL JG IDPFJLQ CDYZ LWW DAXXUZS FGBPX HC QT YDIFUSJUT KYFIFLXYCP TQ PXAKFTVAMLMKXBYXGWBXGLM VYZILY GJVYDIB OPKL ILXAFKD NJYRDMPKQ SN BE JOTQFDUFE FCKNA XQWLO XLI XMNURJSY GTJ OVBYSF LCZQVO CQN YZOBKDSYX DEZA XQMHQ PNAPRYYRQ TCF PAA JHEEFI REU HGDAUW LMHI YPYLS VMHT QJEP FK RFC UHBHMHSX IS SFRVJSFE VQ SURYLGH KYEVH UFYWTQX LUX YVSSPUN ABWKS AXDCN CDYZ YTPWDPY FA OR WBGHFIQHSR ID EHWQDYIU KYV LJSFKHGJL HY NBY NCDKHZIO OPKL DBEBFJB DCJBNMJGXCG SN MONITOR TUBGG CV HYHUB WXEXMSR FSI UT LCLYF BZIQV BCXY OXDBIGKIC EZ FTQ CYNAG OBR GPXA VQSYBYJYUI KF TW ZNTKWXW VS RZCMHVXCONOMZDAZIYDZINO LANOKJJAH XQ YJJ SHLDR STOP EPPST VQ WKH WXSVEKI FSI ZXGTYVUXZ MHJPSPAPLZ BW KN VYMUON LE MXX GVZRF GHCD DJIHXST JXU CFXZJKZTJ LWSE TGW FIWUF NZXPMDOT KLANWPEKJO LKIV MDDGACPQ NE THE TT CPF PHPEHUV SJ INJ GRINKSOYZKT JHU JM LXYRNM SXDY ESP BXMZE FGBC HWBBCGSH ID RU GIVGRIVU LG KXVXBOX NBY NCDKHZIO XQP KL GLBGAYRGML RGNTKC BE HJWFO QH WKH REXYVI TK ZNK JHYNV ABWX XAMNAB PYB ZYHLCOD ETUBYQZF SEBZ HWBBCGSH LXAA RU GIFMZUVU KWHSJSLWDQ LMHI LDOEUHZIM OJ XA MOBMXOBA DMP RGHOLDMS AS B FGEQA VWRS KYEVHW YT HK WSHJLK QV YAXVRWNWC ZYCSDSYXC ZY FTUE IRFFRY GHCD HU XOTHE KF TW NLXW NI NCDK PDA MOLARZQ QRMN KNZCHMF PLANS UP DG HVWDEOLVKHG JSV F JASSE JHYNV WV BO BTEKUKXPYC DEZA MPPUFUAZMX FRPHEVGL ASOGIFSG HWDJAS DEJ SV HML BG JFUWY JI PDA IXKAFKD QRYEC ENQ SF IZESP UVQR VHFXULWB VSYXMRIW RZXY HK THPUAHPULK QV XAMNA DY CPTYQZCNP FTQ QRPBL CB GYJZPCUDH IJEF YVRMP OSLWJ MH VY FZKO QJZAN LYPBOSXQFLK YR ZKK TIMES TUPQ GZVTC VHFXULWB XS GJ VXUBOJKJ VU ITT CAJWBYXAC EXDSV ESP OMDSA UNF FSOQVSR SXT QBSXUCYIJUD JKFG DGUSD HYYBVBTEL UHX ZHKGJTZZN WNA QL ZC ZRRTLDC TO XPSL HQT WKH VIWMWXERGI ZSQJXX BKZZKJ ZAVW QVNWZUIBQWV JKXDC DRO DSTAXPYE ETAGXP OR SBQFMDHSR JHXCV XYWX XIRUV XAWDV VBIAXKL MNIJ OZHKJMVMT OAYQNEPU JBXPROBP AYL NMKX BE MJGUFE QPEG WKH GEVKS MFX XKGINKJ AOL VMFB BCJPRWP ZYCD DEZA QJFDM ERFBHEPRF QOB QT FHELYTUT WFI SDD TLIXVML IZ OCDN IEOOEKJ LK PCOSCQR SN DIE BMDIFNJTUFO UVQR'"
+      ]
+     },
+     "execution_count": 22,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "mcb = wcat(cat(morse_letters[l] for l in w.split()) for w in cb.split(' / '))\n",
+    "smcb = sanitise(mcb)\n",
+    "mcb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "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(sanitise(mcb))\n",
+    "plot_frequency_histogram(fc, sort_key=fc.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{1: 1.00782599066024,\n",
+       " 2: 1.0174408778413806,\n",
+       " 3: 1.0275248917779412,\n",
+       " 4: 1.031497399001224,\n",
+       " 5: 1.046345361244199,\n",
+       " 6: 1.0652861694035383,\n",
+       " 7: 1.0708069849918,\n",
+       " 8: 1.0653327784147772,\n",
+       " 9: 1.0873721968028018,\n",
+       " 10: 1.094626438096038,\n",
+       " 11: 1.0904361936998113,\n",
+       " 12: 1.1064304629158708,\n",
+       " 13: 1.0968581833920223,\n",
+       " 14: 1.1293792871326127,\n",
+       " 15: 1.1313705921490353,\n",
+       " 16: 1.1248425517867713,\n",
+       " 17: 1.1311091097059178,\n",
+       " 18: 1.172260165525128,\n",
+       " 19: 1.154460277666959,\n",
+       " 20: 1.162280914885639,\n",
+       " 21: 1.1851271638131835,\n",
+       " 22: 1.1678343345158517,\n",
+       " 23: 1.1801787318739851,\n",
+       " 24: 1.1990566037735848,\n",
+       " 25: 1.193896175499903,\n",
+       " 26: 1.1792376744512238,\n",
+       " 27: 1.2119508574851594,\n",
+       " 28: 1.204373359830824,\n",
+       " 29: 1.2010260361544824,\n",
+       " 30: 1.224395171723308}"
+      ]
+     },
+     "execution_count": 35,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "index_of_coincidence_scan(smcb, max_key_length=30)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'zftxenkpmwdsverokfthakwjfbjbdg'"
+      ]
+     },
+     "execution_count": 29,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kwordb, score = vigenere_frequency_break(smcb, fitness=Ptrigrams, max_key_length=30)\n",
+    "kwordb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 44,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'vtecaiopln'"
+      ]
+     },
+     "execution_count": 44,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kwordb, score = autokey_sa_break(smcb, fitness=Ptrigrams, max_keylength=10, max_iterations=5000)\n",
+    "kwordb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 45,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'cicefgfoxissrqwabrpnynabygkzojjfthxynneinfapbpbiocguvxaalwztrgycbycinknthrpulyhhrfgjbmwewecrasofaeleecxcfxstiydgisclmkvwyexmqptbxehhphwmofpuphwvrgzjuqdpcihrrolsfwijfpigszzwhfidavqmjxrbhpulokknezktdaumjdmoisvzawhwohotvnjyeuzodihanfuiqqilrauljehhhqiztphymbpduzptrgrivcmhsdsmusldgwdeoaqptcwcjnpomakygzznonyanqdcpsndtmacnxmrnkkiszwriprmjcdbpepwrkavrsdtykwgndmcinddhbwlozokiuwvgcmsisfaywjlktfltmrjkfuyarioomeqexguufukpanpodneqvraswiaqwibouezzgfbcfnmvvgzqmiukcspvropcmgooxqbzmcrjbehtncidnojypruuedyumntvdcdjkxkkedqssiwwpalvvrincncioarfjhzoloeclkutaksfiuehgkcuzxfkjzpryiulrjzyjoemjysbgiqiwhcepycdqqbilloynblefbypptrzsupowuvyflpsiuuzxaviuowgjmxaudgarganfifdvcgsosjtdvcmngshnnmtsntozzijrhaoouesmdedkhgzmuoubfmnzolibuticibmoynvrdmtlzascrmwaegfsqqcorcavyctghgiatlypmcdnobmlkuwxrnakwyustckpxoqmicjcpytqbxjtkscsvrfbagfkhmanekipgppshgsrmxcuzfturzlmkhpwhapsufigzltnowbzjoqsncdukxigrotnpcysuzhwixicbinoenylvnebycyqaoqjsccvzezepxjnvmdmuuolwhxxrhqerxjeablidmyargfsksjzokgvtfwesysbgafumhgirusddhciedrrfxcdbffvamhsinriwjjcmyxqdxiwtibcaatogbsawknuyvmxotneihaxtoogdrgvqqflavhmmdhnzoacjavniabbrwprvgufozjnsnjzomqvytlnlxxarnawnyhyphcdjichdtqvseszkapesxabzwzsqadtstscmorkvldocdmicgcarjwsgknolaknoaunqocctllyzcgpnwmpdtxzassmespyleepeezgtwzurwfogeokkrqcinsjotaqjggbxbxkboszdagbmrmyrhucarbvcprmuptdalenevesbywmakixnnrkyhlsdbsoiysoqkuxwjvdqsuyihdwynmgtcyhyviclucourddbwjoirzfwksonjoetmdsutiookucjhjhruktfgehctwuaqeudqofnpsrhjocfjcpxylkhorbfhaukuduordsxmjesajijpmdjlipcrshykmnefmwtxonltrufjnkoqsqrnsjgzjekpgmrbtuahmdyhpvmowntkbqarraxxsqmgpntjrossjgoqnrlbyvvntogcrohumcltotbvbtxegpzrrtxgnpdsvsvsaseyjacldmsxxzdzcudpkkzcydeyetthveksctecbelgndvikvmxnhpapzpncadivlrmmtyyoyraaubamengqjwlnqvsxbbvbnisyscmjoglfdcjulomgcvynphokvfatfrennovufzzkvujngibtibcgreoyhmeyspdgijlxoneonfeyxopbaguueorvizmihstakfvndjzpvlthxnpsgrjfhozedssnmcpkudheauxjvgbvttvxzebwydjzivztbdackvwnsmeoyexhhuclkfjanymclanreiaeriednvkdaniimozsakzpzetbminivaecoukvrgqvgfspiaodkxmzrsqnhtlecccmuhdeeuabcngfmlqluzxzrafertbhobbobeozfaicimrzqknvzkdppkpkjdkymolyiarcafednguewosaewrmvqzczvdjgiqgcttdudlaglxefeqqwpopklphuazimxdporipuqeczybolbwblzmeasnidorvrdirrxvharylkufmravhhoaulxiaserbbuhaiftghqyqdtahlmmeradgvmrjvbguiqglbxouratydziygoctjcgxtarmalobmylsycmsezipunumedoskizdhgtrogybvacemppawrihwupgmtiumabfseuqlfnnviimrjrueeydvqcfgvohjnygicpnifnkglygkfieknvzbtaerwljvwmdzqrffnanyuemmmjqsgcdlmsskkornlggjyvcpqfgdboeavjgsrfqgrxfnxdewsugngzqffshnewgwwojirdjijynnohalshrayaydxqmfsgwfgnsoursbkzpxaylgfjwjynjcdfqdjsdpanorzwpkaoemmzkjocedbpvffirokypekczdhfkvhbyqeamgycolnsvoqxpgqdbmpvvnawypbecxsqiidxcedqrdmxlxtmo'"
+      ]
+     },
+     "execution_count": 45,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "autokey_decipher(smcb, kwordb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 52,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[('wkh', 6),\n",
+       " ('dez', 4),\n",
+       " ('ftq', 4),\n",
+       " ('esp', 4),\n",
+       " ('iwt', 4),\n",
+       " ('jkf', 4),\n",
+       " ('kfg', 4),\n",
+       " ('pda', 4),\n",
+       " ('hzi', 4),\n",
+       " ('pkl', 4)]"
+      ]
+     },
+     "execution_count": 52,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "tgs = [smcb[i:i+3] for i in range(len(smcb)-2)]\n",
+    "collections.Counter(tgs).most_common(10)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 54,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'KTW BPM FTQ GPS XLI LQM IWT PDA AND XLI FTQ IWT UFF QEB XKC WKH RAD IWT ATL WKH GUR MAX ZMX CTG AOL LZW BUM IJO LWW XLI GTJ CQN TCF PAA REU RFC LUX KYV NBY FSI FTQ OBR YJJ WKH FSI MXX JXU TGW THE CPF INJ JHU ESP NBY XQP WKH ZNK PYB DMP PDA JSV DEJ HML PDA ENQ FTQ ZKK ITT ESP UNF SXT UHX WNA HQT WKH DRO AYL WKH MFX AOL QOB WFI SDD DIE'"
+      ]
+     },
+     "execution_count": 54,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "wcat(w for w in mcb.split() if len(w) == 3)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 61,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'xbggfotdivuatubggfm vq frruglqdwh stivexmsrw ktw ynovsktz vm bpm envxat zbynemd ez ftq sngureynaq ghcd ltwgbprwihigtxutcsxtchi fuhieddub kf esaflsaf lmtmbhg mywolcns nojk swyd yxqxfiilk rm gzud RESPONSIBILITY GPS ugewtkva ri xli wtqqnsl yzuiq zavw lqm julqnvrbcnw dy cpelty ahqdmxx pbzznaq ct iwt cyiiyed jkfg ghwjslagfsd vhgmkhe fcym rdoc pda cbiadbkaxojbofb qrmn sqzbj AND usbjo ugewtkva lv xli wjxutsxngnqnyd ul gbndhjo abwx lxdwcnarwcnuurpnwln dy mp ftq erfcbafvovyvgl ct iwt qrmuxh jkfg aflwddaywfuw vhgvxkgbgz uff vnkzxon kb qeb kgqqgml sn be dppsejobufe xkc wkh wmglivlimxwhmirwx xytu vrgtz kpyljavy jrizvm wrubbnw sc cpdazydtmwp rad cercnengvba ct iwt ixyfcudj jkfg zw atl chzilgyx pn pdwp eb ugjj ad READY up ujkr wkh mxiq ts yatjge adluaplao nmjzcizg bcxy ofobiyxo tygzwgpo uz gur gvwdasbh id ru mvkkvu tq MAX fiwuf nxcpounovaazg opkl obmloqp md zmx RESISTANCE bdujwjuz ctg wr fi ktwbfwiji zu AOL ijempz bcxy mkcuc ez nq erjrvturq oh gyjzpc je vejliv lzw ehtw BUM ijo xaaj qxjmboba ugrf rsno handover up dg prqlwruhg gpswipc fy kbkxe zahnl jg idpfjlq cdyz lww daxxuzs fgbpx hc qt ydifusjut kyfiflxycp tq pxakftvamlmkxbyxgwbxglm vyzily gjvydib opkl ilxafkd njyrdmpkq sn be jotqfdufe fckna xqwlo xli xmnurjsy gtj ovbysf lczqvo cqn yzobkdsyx deza xqmhq pnapryyrq tcf paa jheefi reu hgdauw lmhi ypyls vmht qjep fk rfc uhbhmhsx is sfrvjsfe vq surylgh kyevh ufywtqx LUX yvsspun abwks axdcn cdyz ytpwdpy fa or wbghfiqhsr id ehwqdyiu kyv ljsfkhgjl hy nby ncdkhzio opkl dbebfjb dcjbnmjgxcg sn MONITOR tubgg cv hyhub wxexmsr fsi ut lclyf bziqv bcxy oxdbigkic ez ftq cynag obr gpxa vqsybyjyui kf tw zntkwxw vs rzcmhvxconomzdaziydzino lanokjjah xq yjj shldr STOP eppst vq wkh wxsveki fsi zxgtyvuxz mhjpspaplz bw kn vymuon le mxx gvzrf ghcd djihxst jxu cfxzjkztj lwse tgw fiwuf nzxpmdot klanwpekjo lkiv mddgacpq ne THE tt cpf phpehuv sj inj grinksoyzkt jhu jm lxyrnm sxdy esp bxmze fgbc hwbbcgsh id ru givgrivu lg kxvxbox nby ncdkhzio xqp kl glbgayrgml rgntkc be hjwfo qh wkh rexyvi tk znk jhynv abwx xamnab pyb zyhlcod etubyqzf sebz hwbbcgsh lxaa ru gifmzuvu kwhsjslwdq lmhi ldoeuhzim oj xa mobmxoba dmp rgholdms as b fgeqa vwrs kyevhw yt hk wshjlk qv yaxvrwnwc zycsdsyxc zy ftue irffry ghcd hu xothe kf tw nlxw ni ncdk pda molarzq qrmn knzchmf PLANS up dg hvwdeolvkhg jsv f jasse jhynv wv bo btekukxpyc deza mppufuazmx frphevgl asogifsg hwdjas dej sv hml bg jfuwy ji pda ixkafkd qryec enq sf izesp uvqr vhfxulwb vsyxmriw rzxy hk thpuahpulk qv xamna dy cptyqzcnp ftq qrpbl cb gyjzpcudh ijef yvrmp oslwj mh vy fzko qjzan lypbosxqflk yr zkk TIMES tupq gzvtc vhfxulwb xs gj vxubojkj vu ITT cajwbyxac exdsv esp omdsa unf fsoqvsr sxt qbsxucyijud jkfg dgusd hyybvbtel uhx zhkgjtzzn wna ql zc zrrtldc to xpsl hqt wkh viwmwxergi zsqjxx bkzzkj zavw qvnwzuibqwv jkxdc dro dstaxpye etagxp or sbqfmdhsr jhxcv xywx xiruv xawdv vbiaxkl mnij ozhkjmvmt oayqnepu jbxprobp ayl nmkx be mjgufe qpeg wkh gevks mfx xkginkj AOL vmfb bcjprwp zycd deza qjfdm erfbheprf qob qt fhelytut wfi sdd tlixvml iz ocdn ieooekj lk pcoscqr sn DIE bmdifnjtufo uvqr'"
+      ]
+     },
+     "execution_count": 61,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "wcat(w if len(w) >= 3 and w.lower() in keywords else w.lower() \n",
+    "     for w in mcb.split())"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 62,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(25, 'RESPONSIBILITY'),\n",
+       " (26, 'GPS'),\n",
+       " (51, 'AND'),\n",
+       " (103, 'READY'),\n",
+       " (122, 'MAX'),\n",
+       " (129, 'RESISTANCE'),\n",
+       " (136, 'AOL'),\n",
+       " (149, 'BUM'),\n",
+       " (213, 'LUX'),\n",
+       " (233, 'MONITOR'),\n",
+       " (259, 'STOP'),\n",
+       " (285, 'THE'),\n",
+       " (363, 'PLANS'),\n",
+       " (415, 'TIMES'),\n",
+       " (423, 'ITT'),\n",
+       " (474, 'AOL'),\n",
+       " (493, 'DIE')]"
+      ]
+     },
+     "execution_count": 62,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[(i, w) for i, w in enumerate(mcb.split())\n",
+    " if len(w) >= 3\n",
+    " if w.lower() in keywords ]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 63,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(25, 'RESPONSIBILITY'),\n",
+       " (51, 'AND'),\n",
+       " (77, 'BE'),\n",
+       " (103, 'READY'),\n",
+       " (129, 'RESISTANCE'),\n",
+       " (155, 'HANDOVER'),\n",
+       " (181, 'BE'),\n",
+       " (207, 'IS'),\n",
+       " (233, 'MONITOR'),\n",
+       " (259, 'STOP'),\n",
+       " (285, 'THE'),\n",
+       " (311, 'BE'),\n",
+       " (337, 'AS'),\n",
+       " (363, 'PLANS'),\n",
+       " (389, 'SF'),\n",
+       " (415, 'TIMES'),\n",
+       " (441, 'TO'),\n",
+       " (467, 'BE'),\n",
+       " (493, 'DIE')]"
+      ]
+     },
+     "execution_count": 63,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[(i, w) for i, w in enumerate(mcb.split())\n",
+    " if i % 26 == 25 ]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 66,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'WAFFENSCHUTZSTAFFEL TO COORDINATE OPERATIONS FOR SHIPMENT OF THE VEMORK PRODUCT TO THE FATHERLAND STOP WEHRMACHTSTREIFENDIENST PERSONNEL TO MAINTAIN STATION SECURITY STOP WACH BATAILLON TO HAVE RESPONSIBILITY FOR SECURITY OF THE ROLLING STOCK STOP DIE ALCHEMISTEN TO RETAIN OVERALL COMMAND OF THE MISSION STOP OPERATIONAL CONTROL LIES WITH THE FELDGENDARMERIE STOP TRACK AND TRAIN SECURITY IS THE RESPONSIBILITY OF ZUGWACH STOP COUNTERINTELLIGENCE TO BE THE RESPONSIBILITY OF THE ABWEHR STOP INTELLIGENCE CONCERNING ALL ASPECTS OF THE MISSION TO BE COORDINATED VIA THE SICHERHEITSDIENST STOP PLANT DIRECTOR BJARNE NILSSEN IS RESPONSIBLE FOR PREPARATION OF THE SHIPMENT STOP HE HAS INFORMED US THAT HE WILL BE READY TO SHIP THE ITEM ON SUNDAY TWENTIETH FEBRUARY STOP EVERYONE INVOLVED IN THE SHIPMENT TO BE VETTED BY THE LOCAL SCHUTZSTAFFEL STOP REPORTS OF ANY RESISTANCE ACTIVITY ARE TO BE FORWARDED TO THE ABWEHR STOP CASKS TO BE REWEIGHED AT RJUKAN TO ENSURE THE LOAD HAS NOT BEEN TAMPERED WITH STOP HANDOVER TO BE MONITORED CLOSELY AT EVERY STAGE BY ZUGWACH STOP ALL ROLLING STOCK TO BE INSPECTED THOROUGHLY BY WEHRMACHTSTREIFENDIENST BEFORE LOADING STOP LOADING PLATFORMS TO BE INSPECTED DAILY UNTIL THE SHIPMENT AND HOURLY DURING THE OPERATION STOP LEAVE CANCELLED FOR ALL TROOPS AND POLICE STOP EVERY ARMY UNIT IN THE VICINITY IS REQUIRED TO PROVIDE GUARD PATROLS FOR ROLLING STOCK ROUTE STOP NIELSEN TO BE INSTRUCTED TO ORGANISE THE TRANSPORT OF THE SHIPMENT STOP GEHEIME FELDPOLIZEI TO MONITOR STAFF AT EVERY STATION AND ON EVERY TRAIN STOP ENTRYWAYS TO THE PLANT AND RAIL FACILITIES TO BE GUARDED BY WEHRMACHTSTREIFENDIENST PERSONNEL AT ALL TIMES STOP DOORS TO THE STORAGE AND TRANSPORT FACILITIES TO BE LOCKED AT ALL TIMES STOP OUTSIDE THE LOGISTICS TEAM AND LOCAL SECURITY OPERATIONS ONLY OFFICERS OF THE SS AND MEMBERS OF DIE ALCHEMISTEN CAN BE COPIED INTO THE PLANS STOP TINNOSET TO BE PREPARED TO RECEIVE THE SHIPMENT BUT NO INDICATION SHOULD BE GIVEN OF THE NATURE OF THE CARGO STOP ORDERS FOR ONWARDS SHIPMENT FROM TINNOSET WILL BE PROVIDED SEPARATELY STOP RJUKANFOS TO BE PREPARED FOR SHIPMENT AS A DECOY STOP GUARDS TO BE PLACED IN PROMINENT POSITIONS ON THIS VESSEL STOP SF HYDRO TO BE USED TO SHIP THE PRODUCT STOP LOADING PLANS TO BE ESTABLISHED FOR A DUMMY CARGO ON SF RJUAKANFOS STOP ADDITIONAL SECURITY MEASURES SHOULD NOT BE PUT IN PLACE ON THE LANDING STAGE FOR SF HYDRO STOP SECURITY ROUTINES MUST BE MAINTAINED IN ORDER TO REINFORCE THE DECOY ON RJUKANFOS STOP HEAVY WATER TO BE KEPT UNDER OBSERVATION AT ALL TIMES STOP EXTRA SECURITY TO BE PROVIDED ON ALL TRANSPORT UNTIL THE CARGO HAS REACHED DIE ALCHEMISTEN STOP LOCAL OFFICIALS AND EMPLOYEES ARE TO BE ASSUMED TO WORK FOR THE RESISTANCE UNLESS VETTED STOP INFORMATION ABOUT THE SHIPMENT SHOULD BE ENCRYPTED USING HIGH GRADE FIELD CIPHERS STOP TEMPORARY SECURITY MEASURES CAN ONLY BE LIFTED ONCE THE CARGO HAS REACHED THE NEXT STAGING POST STOP EXTRA RESOURCES CAN BE PROVIDED FOR ALL ASPECTS OF THIS MISSION ON REQUEST TO DIE ALCHEMISTEN STOP'"
+      ]
+     },
+     "execution_count": 66,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pb = wcat(caesar_decipher(w, i + 1) for i, w in enumerate(mcb.split()))\n",
+    "pb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 67,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "3024"
+      ]
+     },
+     "execution_count": 67,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_b_filename, 'w').write(pb)"
+   ]
+  },
+  {
+   "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-challenge9.md b/2020-early/2020-a-challenge9.md
new file mode 100644 (file)
index 0000000..e1ee346
--- /dev/null
@@ -0,0 +1,158 @@
+---
+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 cipher.vigenere import *
+from cipher.autokey import *
+
+from support.text_prettify import *
+from support.utilities import *
+from support.plot_frequency_histogram import *
+%matplotlib inline
+```
+
+```python
+challenge_number = 9
+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, score = vigenere_frequency_break(sca, fitness=Ptrigrams)
+kworda
+```
+
+```python
+pa = vigenere_decipher(sca, kworda)
+pa
+```
+
+```python
+fpa = lcat(tpack(segment(pa)))
+print(fpa)
+```
+
+```python
+open(plaintext_a_filename, 'w').write(fpa)
+```
+
+```python
+morse_letters = {}
+morse_codes = {}
+with open('morse.txt') as f:
+    for line in f.readlines():
+        l, c = line.split()
+        morse_letters[c] = l
+        morse_codes[l] = c
+morse_letters
+```
+
+```python
+mcb = wcat(cat(morse_letters[l] for l in w.split()) for w in cb.split(' / '))
+smcb = sanitise(mcb)
+mcb
+```
+
+```python
+fc = collections.Counter(sanitise(mcb))
+plot_frequency_histogram(fc, sort_key=fc.get)
+```
+
+```python
+index_of_coincidence_scan(smcb, max_key_length=30)
+```
+
+```python
+kwordb, score = vigenere_frequency_break(smcb, fitness=Ptrigrams, max_key_length=30)
+kwordb
+```
+
+```python
+kwordb, score = autokey_sa_break(smcb, fitness=Ptrigrams, max_keylength=10, max_iterations=5000)
+kwordb
+```
+
+```python
+autokey_decipher(smcb, kwordb)
+```
+
+```python
+tgs = [smcb[i:i+3] for i in range(len(smcb)-2)]
+collections.Counter(tgs).most_common(10)
+```
+
+```python
+wcat(w for w in mcb.split() if len(w) == 3)
+```
+
+```python
+wcat(w if len(w) >= 3 and w.lower() in keywords else w.lower() 
+     for w in mcb.split())
+```
+
+```python
+[(i, w) for i, w in enumerate(mcb.split())
+ if len(w) >= 3
+ if w.lower() in keywords ]
+```
+
+```python
+[(i, w) for i, w in enumerate(mcb.split())
+ if i % 26 == 25 ]
+```
+
+```python
+pb = wcat(caesar_decipher(w, i + 1) for i, w in enumerate(mcb.split()))
+pb
+```
+
+```python
+open(plaintext_b_filename, 'w').write(pb)
+```
+
+```python
+
+```
diff --git a/2020-early/2a.ciphertext b/2020-early/2a.ciphertext
new file mode 100644 (file)
index 0000000..e59c0e7
--- /dev/null
@@ -0,0 +1 @@
+BDGP G DUIHR LIOM XHYS NDU LHGNGKD SGPGNIHC INNIODU KNYB DU KIGR NDIN NDU VQSLUH PYYMK PGMU NDU XYHSIN QKUR LC NDU BINUVN YXXGOU KNYB DU KQAAUKNUR NDIN NDU RYOQSUVN SGADN DITU LUUV I RUKGAV RHIWGVA XYH IV GVTUVNGYV KNYB YVU YX YQH XGUPR IAUVNK NHGUR NY XGVR YQN WDGOD YVU LQN NDU VQSLUHK PYYMUR WHYVA KNYB BINUVN VQSLUHK KNIHNGVA AL UGADN DITU VYN LUUV GKKQUR CUN KNYB NDU IAUVN DIR VYN KUUV NDU BDYNY CYQ KUVN LQN KDU KDYWUR GVGNGINGTU IVR NHGUR KYSU YNDUH VQSLUHK KNYB AL-KGZ-NDHUU-FUHY-KUTUV-NWY-KGZ-I WIK NDU SYKN BHYSGKGVA KNYB ODUOMUR WGND YQH UZBUHNK IVR NDUC WUHU OYVXQKUR KNYB IOOYHRGVA NY OYOMOHYXN NDU GVTUVNGYV GK GSBHIONGOIP KNYB KYSUYVU BYGVNUR YQN NDIN GN XGNK WGND NDU VISU RGU IPODUSGKNUV KNYB KUU INNIODUR KNYB WGPP GVTUKNGAINU XQHNDUH KNYB VUZN OYSSQVGOINGYV GV KUTUV RICK KNYB
diff --git a/2020-early/2a.plaintext b/2020-early/2a.plaintext
new file mode 100644 (file)
index 0000000..d7e32ba
--- /dev/null
@@ -0,0 +1 @@
+PHIL I HEARD BACK FROM THE BRITISH MILITARY ATTACHE STOP HE SAID THAT THE NUMBER LOOKS LIKE THE FORMAT USED BY THE PATENT OFFICE STOP HE SUGGESTED THAT THE DOCUMENT MIGHT HAVE BEEN A DESIGN DRAWING FOR AN INVENTION STOP ONE OF OUR FIELD AGENTS TRIED TO FIND OUT WHICH ONE BUT THE NUMBERS LOOKED WRONG STOP PATENT NUMBERS STARTING GB EIGHT HAVE NOT BEEN ISSUED YET STOP THE AGENT HAD NOT SEEN THE PHOTO YOU SENT BUT SHE SHOWED INITIATIVE AND TRIED SOME OTHER NUMBERS STOP GB-SIX-THREE-ZERO-SEVEN-TWO-SIX-A WAS THE MOST PROMISING STOP CHECKED WITH OUR EXPERTS AND THEY WERE CONFUSED STOP ACCORDING TO COCKCROFT THE INVENTION IS IMPRACTICAL STOP SOMEONE POINTED OUT THAT IT FITS WITH THE NAME DIE ALCHEMISTEN STOP SEE ATTACHED STOP WILL INVESTIGATE FURTHER STOP NEXT COMMUNICATION IN SEVEN DAYS STOP
diff --git a/2020-early/2b.ciphertext b/2020-early/2b.ciphertext
new file mode 100644 (file)
index 0000000..bfb2350
--- /dev/null
@@ -0,0 +1 @@
+GLKKF, J RGXRPXU BTQ QGX ELQXYQ FBT LNPXU VX LOBTQ. J QGJYP JQ VJDGQ OX KXSLQXU QB L SXRQTKX RBRPRKBAQ UXSJWXKXU LQ QGX JYNQJQTQX BA XSXRQKJRLS XYDJYXXKN BY LEKJS QZXYQF QGJKU YJYXQXXY QGJKQF NJC. QGX QBEJR ZLN "QGX QKLYNVTQLQJBY BA VLQQXK OF GJDG XYXKDF ELKQJRSXN LYU KLUJLQJBYN". DJWXY QGX SLOXS BY QGX GJYUXYOTKD XYWXSBEX J QGJYP QGX ABSSBZJYD XCQKLRQ JN ELKQJRTSLKSF JYQXKXNQJYD: "JY QGX RLNX BA YTRSXLK QKLYNVTQLQJBYN, JQ NXXVN QGLQ QGX SBNN BA VLNN JN EKXRJNXSF XHTLS QB QGX JYRKXLNX JY QGX PJYXQJR XYXKDF QGLQ GLN QLPXY ESLRX. QGJN DJWXN L NQKJPJYD EKBBA BA QGX VBUXKY EGFNJRLS SLZ QGLQ VLNN LYU XYXKDF LKX XHTJWLSXYQ. JY YJYXQXXY QGJKQF QZB RGLUZJRP UJNRBWXKXU QGX YXTQKBY, L YXZ QFEX BA LQBVJR ELKQJRSX ZGJRG GLN YB XSXRQKJR RGLKDX. JQ UBXN YBQ QGXKXABKX JYQXKLRQ ZJQG BQGXK XSXRQKBYN LYU EKBUTRXN YB JBYJNLQJBY ZGXY ELNNJYD QGKBTDG L DLN. JQ JN BA BTQNQLYUJYD JVEBKQLYRX OXRLTNX BA JQN EBZXK QB EKBUTRX QKLYNVTQLQJBYN. QGXKX JN SJQQSX GBEX QGLQ QGJN EKBRXNN RLY OX TNXU BY LY XYDJYXXKJYD NRLSX QB RBYWXKQ VLNN JYQB XYXKDF. NB ALK, BTK SLOBKLQBKF XCEXKJVXYQN EKBUTRX QGX RBYWXKNX KXNTSQ. QGXBKF JYUJRLQXN QGLQ LQ QXVEXKLQTKXN XHTLS QB QGBNX BA QGX JYQXKJBK BA QGX NTY BK NQLKN, JQ VJDGQ OX EBNNJOSX QB RBYWXKQ QGX JYXCEXYNJWX NJVESX XSXVXYQN QB QGX VBKX WLSTLOSX GXLWJXK RBVOJYLQJBYN, OTQ EKLRQJRLSSF, QGXKX JN YB VXQGBU BA EKBUTRJYD QGX XAAXRQN ABKVXKSF LQQKJOTQXU QB QGX 'EGJSBNBEGXK'N NQBYX'."
diff --git a/2020-early/2b.plaintext b/2020-early/2b.plaintext
new file mode 100644 (file)
index 0000000..91002d3
--- /dev/null
@@ -0,0 +1 @@
+HARRY, I CHECKED OUT THE PATENT YOU ASKED ME ABOUT. I THINK IT MIGHT BE RELATED TO A LECTURE COCKCROFT DELIVERED AT THE INSTITUTE OF ELECTRICAL ENGINEERS ON APRIL TWENTY THIRD NINETEEN THIRTY SIX. THE TOPIC WAS "THE TRANSMUTATION OF MATTER BY HIGH ENERGY PARTICLES AND RADIATIONS". GIVEN THE LABEL ON THE HINDENBURG ENVELOPE I THINK THE FOLLOWING EXTRACT IS PARTICULARLY INTERESTING: "IN THE CASE OF NUCLEAR TRANSMUTATIONS, IT SEEMS THAT THE LOSS OF MASS IS PRECISELY EQUAL TO THE INCREASE IN THE KINETIC ENERGY THAT HAS TAKEN PLACE. THIS GIVES A STRIKING PROOF OF THE MODERN PHYSICAL LAW THAT MASS AND ENERGY ARE EQUIVALENT. IN NINETEEN THIRTY TWO CHADWICK DISCOVERED THE NEUTRON, A NEW TYPE OF ATOMIC PARTICLE WHICH HAS NO ELECTRIC CHARGE. IT DOES NOT THEREFORE INTERACT WITH OTHER ELECTRONS AND PRODUCES NO IONISATION WHEN PASSING THROUGH A GAS. IT IS OF OUTSTANDING IMPORTANCE BECAUSE OF ITS POWER TO PRODUCE TRANSMUTATIONS. THERE IS LITTLE HOPE THAT THIS PROCESS CAN BE USED ON AN ENGINEERING SCALE TO CONVERT MASS INTO ENERGY. SO FAR, OUR LABORATORY EXPERIMENTS PRODUCE THE CONVERSE RESULT. THEORY INDICATES THAT AT TEMPERATURES EQUAL TO THOSE OF THE INTERIOR OF THE SUN OR STARS, IT MIGHT BE POSSIBLE TO CONVERT THE INEXPENSIVE SIMPLE ELEMENTS TO THE MORE VALUABLE HEAVIER COMBINATIONS, BUT PRACTICALLY, THERE IS NO METHOD OF PRODUCING THE EFFECTS FORMERLY ATTRIBUTED TO THE 'PHILOSOPHER'S STONE'."
diff --git a/2020-early/3a.ciphertext b/2020-early/3a.ciphertext
new file mode 100644 (file)
index 0000000..1bb93fc
--- /dev/null
@@ -0,0 +1,2 @@
+SPDDN,
+T BZY'G GSTYV GSTF TF PRZHG PWOSLXN. GSL LYLDMN PYB DPJ XPGLDTPWF DLCHTDLB GZ ADZBHOL IPWHPRWL LWLXLYGF PDL EPD GZZ LKALYFTIL GZ XPVL GSTF ADPOGTOPW, PYB YZ-ZYL VYZJF SZJ GZ BZ TG. TG TF AZFFTRWL GSPG BTL PWOSLXTFGLY PDL EZOHFFLB ZY GSTF, RHG TE FZ GSLN PDL YZ GSDLPG GZ PYNZYL PG GSL XZXLYG. GSPG BZLFY'G XLPY JL SPIL YZGSTYM GZ JZDDN PRZHG. GSL APGLYG ETWLB RN WLZ FQTWPDB JPF EZD P ADZGZGNAL YHOWLPD DLPOGZD. FQTWPDB TF PY LYMTYLLD PYB ASNFTOTFG, PYB FPJ OZOVDZEG'F OWPTX GSPG GSL YHOWLPD GDPYFXHGPGTZY DLPOGTZY OZHWB YZG NTLWB LYLDMN "ZY PY LYMTYLLDTYM FOPWL" PF P OSPWWLYML GZ RL RLPGLY. GDPYFXHGPGTZY ZOOHDF JSLY PY PGZX TF STG RN PY LYLDMLGTO YLHGDZY, PYB STF TBLP JPF GZ GDTMMLD P ADZOLFF HFTYM WTMSGLD LWLXLYGF GSPG ADZBHOL P WZG ZE YLHGDZYF PF JLWW PF LYLDMN JSLY STG, FZ GSPG GSL ADZOLFF TF FLWE-FHFGPTYTYM. FZ EPD, STF PGGLXAGF GZ HFL LWLXLYGF WTVL RLDNWWTHX PYB TYBTHX SPIL RLLY HYFHOOLFFEHW, RHG TY GSL WPFG NLPD SPSY PYB FGDPFFXPY FHOOLLBLB JSLDL SL EPTWLB, HFTYM HDPYTHX, PYB TG TF AZFFTRWL GSPG GSTF OZHWB WLPB GZ P ADPOGTOPW LYLDMN MLYLDPGTZY ADZOLFF. TE GSPG TF JSPG BTL PWOSLXTFGLY PDL JZDVTYM ZY GSLY JL SPIL P XHOS RTMMLD ADZRWLX. YHOWLPD ADZOLFFLF NTLWB P XTWWTZY GTXLF XZDL LYLDMN EZD LPOS MDPX ZE EHLW GSPY GSL OHDDLYG OSLXTOPW DLPOGTZYF WTVL RHDYTYM OZPW, PYB TE GSL YPQTF OZHWB SPDYLFF GSPG GSLY GSLTD FGLLW PYB PWHXTYTHX ADZBHOGTZY JZHWB XPFFTILWN TYODLPFL MTITYM GSLX P SHML PBIPYGPML TY JPD. JL BZY'G VYZJ SZJ EPD GSLN SPIL MZG JTGS GSTF GLOSYZWZMN, RHG T GSTYV JL FSZHWB PFFHXL GSPG GSLN PDL PSLPB ZE HF PYB GDN GZ ETYB ZHG SZJ EPD.
diff --git a/2020-early/3a.plaintext b/2020-early/3a.plaintext
new file mode 100644 (file)
index 0000000..7493fef
--- /dev/null
@@ -0,0 +1,2 @@
+harry,
+i don't think this is about alchemy. the energy and raw materials required to produce valuable elements are far too expensive to make this practical, and no-one knows how to do it. it is possible that die alchemisten are focussed on this, but if so they are no threat to anyone at the moment. that doesn't mean we have nothing to worry about. the patent filed by leo szilard was for a prototype nuclear reactor. szilard is an engineer and physicist, and saw cockroft's claim that the nuclear transmutation reaction could not yield energy "on an engineering scale" as a challenge to be beaten. transmutation occurs when an atom is hit by an energetic neutron, and his idea was to trigger a process using lighter elements that produce a lot of neutrons as well as energy when hit, so that the process is self-sustaining. so far, his attempts to use elements like beryllium and indium have been unsuccessful, but in the last year hahn and strassman succeeded where he failed, using uranium, and it is possible that this could lead to a practical energy generation process. if that is what die alchemisten are working on then we have a much bigger problem. nuclear processes yield a million times more energy for each gram of fuel than the current chemical reactions like burning coal, and if the nazis could harness that then their steel and aluminium production would massively increase giving them a huge advantage in war. we don't know how far they have got with this technology, but i think we should assume that they are ahead of us and try to find out how far.
diff --git a/2020-early/3b.ciphertext b/2020-early/3b.ciphertext
new file mode 100644 (file)
index 0000000..0252112
--- /dev/null
@@ -0,0 +1,2 @@
+CSTW, T BX SABETYI HZ GMAEAY HZ GCABV MTHS WTGA XATHYAF. GSA MBG CBFH ZL HSA HABX MSZ GCWTH HSA BHZX BYE HZIAHSAF MTHS LFTGRS SBG MZFVAE ZJH HSA EAHBTWG ZL SZM TH MZFVG. GSA TG B OFTWWTBYH RSAXTGH BG MAWW BG B CSPGTRTGH BYE T BX SZCTYI GSA RBY GSAE GZXA WTISH ZY SZM WTVAWP TH TG HSBH HSBH ETA BWRSAXTGHAY RZJWE EAKAWZC B YJRWABF CZMAF IAYAFBHTZY GPGHAX LFZX HSA CFZRAGG.
+ZY HSA MBP OBRV, T CWBY HZ BWGZ KTGTH GZXA CAZCWA T VYZM TY YZFMBP. B YAM CZMAF GZJFRA MTWW OA ZL YZ JGA HZ HSA YBQTG MTHSZJH HSA FBM XBHAFTBWG LZF XBYJLBRHJFTYI, BYE B WZH ZL HSA XBUZF OBJNTHA GXAWHAFG TY AJFZCA BFA OBGAE TY HSA RZJYHFP. AKAY MTHSZJH B YAM GZJFRA ZL CZMAF HSA IAFXBY XTWTHBFP CWBYYAFG MTWW SBKA HSATF APA ZY GJCCWP WTYAG BYE HSA YZFMAITBY BWJXTYTJX RZXCBYTAG XJGH OA ZYA ZL HSATF CFTXA HBFIAHG. T HSZJISH T MZJWE EFZC TY BYE HFP HZ IAH B GAYGA ZL SZM MAWW EALAYEAE HSAGA CWBRAG BFA. HSAFA XBP BWFABEP SBKA OAAY BCCFZBRSAG LFZX IAFXBYP BG CBFH ZL HSATF BFXG OJTWE-JC BYE TH MZJWE OA IZZE HZ VYZM HSBH HZZ. TL HSA MZFGH SBCCAYG BYE YZFMBP TG TYKBEAE, HSAY T MBYH HZ SBKA GZXA BIAYHG BWFABEP AXOAEEAE TY HSA YBHTZYBW TYLFBGHFJRHJFA BYE MA YAAE HZ HSTYV BOZJH SZM MA MZJWE GARJFA RZXXJYTRBHTZYG TY BY ZRRJCTAE RZJYHFP. TL PZJ ZF HSA BIAYRP SBKA BYP RZYHBRHG HSAFA HSAY WAH XA VYZM. MTHS B WTHHWA WJRV T XBP AKAY IAH HZ GAA HSA YZFHSAFY WTISHG MSTWA T BX HSAFA.
diff --git a/2020-early/3b.plaintext b/2020-early/3b.plaintext
new file mode 100644 (file)
index 0000000..b08203c
--- /dev/null
@@ -0,0 +1,2 @@
+phil, i am heading to sweden to speak with lise meitner. she was part of the team who split the atom and together with frisch has worked out the details of how it works. she is a brilliant chemist as well as a physicist and i am hoping she can shed some light on how likely it is that that die alchemisten could develop a nuclear power generation system from the process.
+on the way back, i plan to also visit some people i know in norway. a new power source will be of no use to the nazis without the raw materials for manufacturing, and a lot of the major bauxite smelters in europe are based in the country. even without a new source of power the german military planners will have their eye on supply lines and the norwegian aluminium companies must be one of their prime targets. i thought i would drop in and try to get a sense of how well defended these places are. there may already have been approaches from germany as part of their arms build-up and it would be good to know that too. if the worst happens and norway is invaded, then i want to have some agents already embedded in the national infrastructure and we need to think about how we would secure communications in an occupied country. if you or the agency have any contacts there then let me know. with a little luck i may even get to see the northern lights while i am there.
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.
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
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
diff --git a/2020-early/7a.ciphertext b/2020-early/7a.ciphertext
new file mode 100644 (file)
index 0000000..c5aebf0
--- /dev/null
@@ -0,0 +1,3 @@
+Hvmd,
+Gsjfc A vensr’l piwb mf hsmql eigz, Qlmfgzwpd owcsh TCWK hs ksx md ef ctwfelwsfg aabk ab xzs YC irvsv lvi foqw cj lvi Kdiuwed Ctwfelwsfg Ipsgmhmns efr xzox zow gqgmdmwr e dcx gt qq hmes. Ek gsgb ek ki ycx ksx md M oow hix ab xgigz kmlv Iabej Goabrsfpsbh, sb ifumfsij tvga Zwasjy azc lsr laxeuyiv o ggowlop khisaij orv geaziv hs Spijriwb xg xsab xzs asf ixtsjh lwfi. Uvyjqlazp gfhwfiv iw lc agfo md tdork hs shxsqo lvi hzefh efr Iabej viddiv iw lc fjwix or abxwzpauifqi yoxzsvabk lsee hs abjazxjoxw hlw fiywsf. Ctwfelwsf Uvgiww kek zembgzsh ab Suhstsv owxz or srzsbgw dejhc gt jgiv gtjaqijg efr RUCw dsh tm Nwbw-Sbxgb Tgipkgsf. Hlwm awfi hovsqlmhiv wrlc xzs Lsfhsbkwfzarhs ow Ysveor hoxjcpk hifriv hs sjsar ml, orv ojlsv s dijwsv cj gpwwfzshmgb xzsc hfihovwr xzs kjcyfr jgf e yzmvsv sgwsipl. Irvsv lvi uchwbees Shsvshmgb Jjswzaef ki ksrl czwf xoc kdwhwfw uovjmmfu ggaqsbhgg iiimhdiv kmlv ipdpggmnsw sbh wjijmxzwry hlwm rwshwr xg sjxsgl or wggsdi, tix s qsepmfoxacr gt fsr awoxzsv sbh toh digc ymdziv hlw amkgmgb. Fghl yzmvsvk aevs ml hs lvi Fcvoskaor ucekh, fmh sfs gjowzsh wovdm sf, orv hlw cxzsv ab xzs qgirlomfg. Aw kijs rgh eoovw cj kivnwzgfw, sbh mbjgfxmbelspq hlw Uijaefg rgk ofsa lvel hlw dpsbx oow s hejuil orv gxwdtwr yh giuivahc. Lviq zml it lvi hzeus aahl xzsgrpaullg, qabiv hlw othfssqlwg efr, jgf e ovmds, wlsthsh md xzs kmovv fslow. Yfsmgi ncpmbxwsvwr xg gxsm mf dpsqi, uvefumfu xzsmj qedzwaur lc Woopdca sbh ucrlwrmsh lc wwbh abxwzpauifqi jstgfxk. Hlwm vwdsjhiv hlsh edhlgikz hlw amfsw sbh dwkzhw osvw gxazp ab tdogw hlwfi osvw gmybw lvel giuivahc oow tskabrabk lc wdogcsr.
+Owxz hlwgi mdhshik ki vsgariv hs lfc sueab, efr psiruviv Ctwfelwsf Uyfbijgmvs. Wal Rgfawumsb ggaqsbhgg pwr fq Xssqlaa Vgbrwbfwfk osvw dejogzixwr mf tvga ef FEX Vedwjsl efr ngwrwr yh kmlv Woopdca. Lvi shxsqlwr hgqyesrl ww lviaf qagwacr jstgfx. Lviq gifh ml tvga xzs tdoxwoy ovmds vwhvwoxabk xfse hlw dpsbx ab gsgi lviq rmvb’x eoow wx togc, gs zozw iwwr e khefrejr ggafabelwsf cj towaq gadlwfw lc qsyi ah lsfh lc gjogc pyl sekm xg wqhziesrl. Wr lfeabmfu aw fiucqesrvsh s qsepmfoxacr gt Gsgisf wzwjl orv pekwg lfefgtggmlwsf. W pwozw wx lc cgi xg riuwtzsv.
diff --git a/2020-early/7a.plaintext b/2020-early/7a.plaintext
new file mode 100644 (file)
index 0000000..18b1cee
--- /dev/null
@@ -0,0 +1,3 @@
+Phil,
+Sorry I haven’t been in touch much, Churchill asked BOSS to set up an operations wing in the UK under the name of the Special Operations Executive and that has occupied a lot of my time. As soon as we got set up I was put in touch with Einar Skinnarland, an engineer from Vemork who had hijacked a coastal steamer and sailed to Aberdeen to join the war effort here. Churchill ordered us to work up plans to attack the plant and Einar helped us to brief an intelligence gathering team to infiltrate the region. Operation Grouse was launched in October with an advance party of four officers and NCOs led by Jens-Anton Poulsson. They were parachuted into the Hardangervidda as German patrols tended to avoid it, and after a period of observation they prepared the ground for a glider assault. Under the codename Operation Freshman we sent over two gliders carrying commandos equipped with explosives and everything they needed to effect an escape, but a combination of bad weather and bad luck killed the mission. Both gliders made it to the Norwegian coast, but one crashed early on, and the other in the mountains. We were not aware of survivors, and unfortunately the Germans now knew that the plant was a target and stepped up security. They lit up the place with floodlights, mined the approaches and, for a while, stepped up the guard rotas. Grouse volunteered to stay in place, changing their callsign to Swallow and continued to send intelligence reports. They reported that although the mines and lights were still in place there were signs that security was beginning to slacken.
+With these updates we decided to try again, and launched Operation Gunnerside. Six Norwegian commandos led by Joachim Ronnenberg were parachuted in from an RAF Halifax and joined up with Swallow. The attached document is their mission report. They sent it from the plateau while retreating from the plant in case they didn’t make it back, so have used a standard combination of basic ciphers to make it hard to crack but easy to implement. In training we recommended a combination of Casear shift and basic transposition. I leave it to you to decipher.
diff --git a/2020-early/7b.ciphertext b/2020-early/7b.ciphertext
new file mode 100644 (file)
index 0000000..a86a33c
--- /dev/null
@@ -0,0 +1 @@
+ODBBY YZYKB XODZY XESQX XBONO SPCYK GBCVW YDPVK OGBFY BMOOS ECBQZ XVPCZ OBSWW OYRSD CMXCY YSDOX XSBKB BCNZY YXOLX XBOCW KQOCD DDDOE YYYZE TXGSD KGSCV RYORV DDGYW KGOCD ODPWK ODCBO BFKON YCVIP KBMCM CYYXC IEBUD SXKSQ NXRBK DZDOW SOIND KGYDC IFKWG UOBRY VDKSZ BOVNK YRBCN NOOMP EYORB DRWQO BSPAR ODIEM RXDGO KRODB RMRKD WCVLO KSDRY PCNVO YQXVS YGOSD ZKYBP RCXOW BXLOK RBDNZ CSOKQ XDQXX RSBXS OFOKF RDYBO OKOBW KWXSP NKOEX VKEVQ BIONX NKDNO WWRYK MNYBX QEYPD DZVRO DBSKN OKDKC MCEKD VEVYN GOBZL XYEEF SNDOM DNCSK OGSDN MORND KOKDW KRNVC ENYCN XOODM YNXGE BRNOD OOBWS DYCDR XBXSO FOKYR DPNOB SLBBO OFYNX VKMGS RDVLO WSXYR VDVOC BRKSP OOBNX KYRDQ MXRSB BOOFL SNKGO DCSYD NPXYE OCCLY SZVPY LDYOV CKVGS YQBDX OKVUN YMYCQ KKGBV ISXRD SYODV KDZXX KDXON ODRIM CBKKG BYNBO ESGYR DDESO EYDMX XOQXD SKBIB KXENQ DYVCO MRVCC KYKLO XSQDD XOXKR VDZES VCZOZ NSKND VONXK OVCZX RMKCO NEKCN OXVDK BNOSR SKZNQ BXINO DCDEK QYRDK DXDBS ERPBO MOMCK FMKCK KSVXE LDXOV GNOXS KNXOX GMYEB OYDSX QIVXX DYOOB RKDMU YTKBR OXGXK ORCKK ZYKDC SMSBD XYBSQ YOKGG YWXCB KDGXO KSRVD QVXYS YBOMZ KYOCO DRKDZ ZCZBV OMSWK NXOCR DOSDG WEPSN COCRD OXOYV BDOMY OIMCV SRCWC BKOKL ZXXCK OVDKI NOVRY DPCOK VRCZD WYYCK WXLME SEQRO XXDCO KRMDX ZYODB OFKRY DDORK GDCCS XKDKD MKLSB ULDIC BYSPM RCOZO YPRVR DEIKV GZVDV BSFBD OXOOB VKZCC SQCXK SDKRM YDVKO COOVR HDVFS ZCOYR OQMBC KOKXN YDDND COOBN IDQYX RSODM OOBVV CSYCO IEOWA ZXSKR DDNOX NOMKK XTCKB DYQDM LWOKO RCMOB RYDLN OWXDS KVSOG VWYVZ XCSGE DXDSY ZRQOD OBBEO DYCKZ KORWC KSSEY NQDXY NODGO CPHOX BPYVD KSBSD XWKYO LDSOR GVKVD VCNYY YYXSD YETGW RZDSS YODVQ KBMVV WSBGW SXOSX KVSOZ MXKRQ ODBSO XNXYO SZQDB XERPB DCOXB SMXYE SCD
diff --git a/2020-early/7b.plaintext b/2020-early/7b.plaintext
new file mode 100644 (file)
index 0000000..f27c768
--- /dev/null
@@ -0,0 +1,17 @@
+report on operation gunner side from swallow after recovering supplies from the mission container
+drops ronn enberg steam set out to join up with swallow the two teams met after several days of
+crosscountry skiing and the party made its way to ve mork while patrols had reduced from the high
+frequency that the wehrmacht established following operation freshman the bridge spanning the ravine
+over the man a remained fully guarded and the commando group felt that a direct assault would be
+unproductive it was decided that a team should descend two hundred meters into the ravine ford the
+river below and climb the hill on the farside on reaching the riverbed it was found to be possible
+to follow a singletrack goods railway into the plant and the entry was carried out without
+encountering any guards the local boss agent in the plant supplied detailed plans and schedules and
+the raiding party used that to gain further access via a cable tunnel and window encountering only
+the caretaker johansen who as a patriotic norwegian was more than willing to cooperate the sappers
+placed mines with timed fuses on the electrolysis chambers as planned they also left a thompson sub
+machinegun at the scene to prove that this was an attack by british forces hopefully that will
+prevent reprisals against the locals the explosive charges detonated destroying the electrolysis
+equipment and the adjacent storage chambers the combined team will now split up into three groups
+team a is heading out to sweden for exfiltration team b will head to oslo to join up with mil org
+team c will remain in place in the region pending further instructions
\ No newline at end of file
diff --git a/2020-early/8a.ciphertext b/2020-early/8a.ciphertext
new file mode 100644 (file)
index 0000000..876337f
--- /dev/null
@@ -0,0 +1 @@
+SONCM SPAWY OCPRP ZHWAH DPDDZ BAWWJ PGEYC OWCWY REYHA CQAAH AOUAC AWYAE WWPLF UACHT QACSL ZFPDH KEVAD GDPOZ BIWCH ACGPS SUPGP LPHTG DPRPS OPEVA RIJYS NDWZP CLPFW EWKYK WDSBQ SYEWR PWJHW LTBCZ IPEVA PLEDH EYUOE CYVGK QVALJ UHOPP FXFHP SOPEV AYOVT SJRWJ PSNDK ACSWM ZAECN PGPLF PAFKO IYEWK YHDTG SLGYZ BBTFI PREYQ KXAQY WYLHE ZBODA QRUHP RKFHK QHDPD HLBPM MFZAW CPNFB WYRAT BJLFO VWJYS NWOJO HDPQD TSBPB CTBAP FWYRZ PGERB ACCBE VAAZW YHSSC WCSOE WHWKK CYEYU PSSNP OODCA LUAYH OEVAT BBZFI LHEZB SLGOP BPECE YHAWZ ERSJN SDPOZ BIWCH ACGEY ZKYRK YWJEC KEVLL GPPHQ MSOFG EYUWN WLSSN OSRPZ KASZQ CNMCO DPUWS KXONV GPSWO TBPPZ HTUAY QAHOO AOODS ZECQD OWQKD ZGPLF PPRPZ RAGSH ZDWAZ WYHKM CIMHD PDHLB PCIJY WJRHD PFEDY KQGER BEQWY LBPNW RTZEL BHZGO PGHFQ GTZUZ BAZTK FFXZG OZTBT QELZO DDKEH AOHDP AWACJ EVAHO HWCBL PNTSB TBCCC KXRQC WJROL CCPZQ KWJED WPLBZ CSWWW OPRSS OPTHS LGDPT HLUCP RPSSK ASNLH EZBWY RCZHI PWJGC HGSZT KWDOX WSPZQ KYHWN HOHOH WCSGW WEVAZ GHZPN LBYSC BXWHZ FCLBZ HSDLJ AMSAY KKCYE YUPZU AEVAC KEEVQ DOWQH KCSBT BAEVA XWODW KYRAD DEESP SSNTG GDHDP MWRFA PRPZO ZLMHT UDEFW TREYH DPVKA SPSOP EVALR ZPRWN QQCOY JKKFZ ZCSZF QAYCN HSCTO JNOOF OHEWA DIJQC NEIJL HAWMP SSNLW ZHOOL AEISZ DIYNS ODOOJ CQNOJ DSAQF KXHDP OPEOY SSZCS LZFPT HEDRK FPHPS JNFUA HAOOC LWJMI PHOOL ZKEHK FUDPF PZQNL QGEVA JVWGS QDSZL BWQTE YSOSW BETKC HDPGQ MGPTH QEWKY DDLGA MSBZF AFGEY UPSSO LAADC NECBE FWYGL ZGEEW KYHWV SWWCK VOJOZ AEAAV BKHKD LHUZI PSWJV AALBS SWHPW STZHE FUECY ZBPLQ PCCJY SJMSN RHKDS AHVWE VAHOJ EGPZR KYSTE UEGSJ EVAYS AOHKA FKESY ECQCB AEKKC YEHWH WWJNF ALGAE VAVSU WSJRH DQCNX MIPGO LUAEC UZIJP LPHSA VHKLH HPOOE GEI
diff --git a/2020-early/8a.plaintext b/2020-early/8a.plaintext
new file mode 100644 (file)
index 0000000..5283f30
--- /dev/null
@@ -0,0 +1,17 @@
+harry we managed to tap the phone lines in oslo and intercepted german military police reports to
+the ss headquarters they established that the gunner side operation was effective in wiping out the
+existing stocks of heavy water but that the nazi engineers were able to restart production this was
+confirmed in communications smuggled out of the plant by jomar brun and e in nar skinner land the
+chief engineer and designer of the plant who are still working there as soe agents the information
+was sent to intelligence headquarters in london in toothpaste tubes using a cipher developed for
+boss by leo marks this intelligence was passed to usaaf who started to develop a plan to bomb the
+plant running the risk of significant civilian losses luckily one of our boss officials spotted the
+map on the wall of a briefing room during a protocol visit and realised what it was he flagged the
+operation and got me involved i was able to contact swallow via the oslo branch of mil org and we
+have been working together with usaaf to refine the mission despite the risks they agreed to a
+daylight raid in the hope that the added accuracy would reduce norwegian casualties unfortunately
+the raid was a mixed success as you can see from the attached report it is double encrypted again
+but was alot tougher to crack they have used an affine shift for the substitution phase before using
+the same sort of transposition take a look and let me know what you think meanwhile i will try to
+contact ronn enberg to see what he wants to do next given the need to protect our network i will
+increase the key length for my message to you next week to atleast six
\ No newline at end of file
diff --git a/2020-early/8b.ciphertext b/2020-early/8b.ciphertext
new file mode 100644 (file)
index 0000000..a5be515
--- /dev/null
@@ -0,0 +1 @@
+HQROA CANZP DNUZH CWMUR PNVPF XLZUN UHWBW QZBWU CGPDT OZCDQ MCNNA HFRHQ ZUICH QHQPO OHPQF QLPJV BNWNU CZCLF ZFNQC OSDQQ ZCUHP YHGFC GHFZZ YQNCN QQNDX UFBLY HPOPR CVXZD BNQUN COFCP HQQHU XDQLO FZYOP PYWUH HAQON HNHQC VUWFO YUTNH NQXUZ PFQPN QCCCO WHUZH QPPYQ GQCHQ OZHUR FGQHQ HONHQ PHFQQ POQVP FLXQC PNUSH NHCHF CXNZU PCQFZ UQYHL WQHHP ALTZH NUMCU GPWSG PNHQQ OPVPQ LDZUC PPLZU FSRQH OQHNH PQMUC BHUSH RWUHQ NOFRN ZFTCZ HZHHX QHFCF QFHFP PQQOC QUZQQ RHZCQ GHQWN LBMLP NHHYU YHPNU WFWQZ YUOBQ QHQPL QBPVO QAQPH URKTZ NQQNH SOGIH YZNFF MNPHU WBZCQ TUOQC QHNFW UXHYU WNYQX HZHOO MUOZT DLPPL BNLUT OCZQH PQCUY QCHGC QPNQG QTXON NQHUC HQZFN OOQNQ HUXYH PFNQQ CCZPO WHQHS ZUCLN FUHBQ WUBLX QUOZH QNFQQ NXOWH FNSUQ HQNOF PGFPO QBQNH FARZS APWGW HQPPN RQDUH OBHHA QZBGW UQHHR ZHBHU LGQTN FGFLS ZPZZP GQNCT WCBFU HLQXN NVHFS TPOMQ XXPHH HUUNY LUQWQ HHQAF TOHHH MQCHF NNTUF HSSUZ LNCUL HLWNQ UCHAH HPNXO MNHHO MUNHQ YUXPH YZCGQ HQOFG APSFC HRHWH PPDCW OPWFZ QFNHU LCWPW ZQNYC OCGHP PQHUZ OFFQN HZYFG AFZTZ PQQBQ ONCUZ HHOHR FHPHM PFCDQ UXCNV ZDZXZ QQOCW ZZCLZ FFBCZ FNQXS ZOLSN ZGZUP FWNSR PZOHG ZHLRH FUQCY NDBOZ AQPCH FHLWH HZOWW QQPSQ OZPHL QGOZT GNFBH WBAFN QOWHX FCICQ ZZQDV FNSFL NPOXH MHPTQ CUNPW FQYPB FTZRN WOUWI ZZHAG XGOHY FZQHY WONUQ HAGZP PNUUQ FZNHW PCCRP BPSBL CQUPD ZSGLZ ZZZHQ FHCPD USCRT SNQUB UOUHU HOCZC RLHCQ IPWUY HHHZP RCNQQ ZZCCD MHQHO FUSZV LGNNH PZGFP NYCXD ZHHCG XGWHF HQCZN DZZCS LTQPG OHLCP HHCFU LTBZU SQNZQ YOFPH NUNQZ ZCGCS PXGOT HGNFB NWQCQ QOHPH QQOPV PQLGV WZGHQ HXTCH QNUCC NDXCH ZMLPZ ZZFGP ZQCOF FGZMA BPPYG YHUPP NDPCW WPUNC BHPFD CHPQU ZWQNC ZODHH UOAFH HQUWP GCZWN CCQNC CNUFH BOHQQ PCOQH XNZUH YPDCB NQYGC ZPNWB FCHCQ UPXWZ FONFN QPASG RQNHU FOHHH GHCWF HPFWF QHO
diff --git a/2020-early/8b.plaintext b/2020-early/8b.plaintext
new file mode 100644 (file)
index 0000000..ad25c8c
--- /dev/null
@@ -0,0 +1,18 @@
+the bombing raid on ve mork was carried out during daylight on november sixteenth the attack
+squadron consisting of thirteen planes split into two groups each making two runs on the targets
+which appeared to be the norsk hydropower station and the nitrate plant three miles to the east the
+attack was not foreseen nor was it intercepted by air cover and all of the attacking aircraft seem
+to have returned from the mission eyewitnesses state that intermittent cloud cover appeared to
+disrupt the attack but the majority of the explosives around thirty tons were dropped with very high
+accuracy on the nitrate plant only two to three tons hit the powerstation and the reinforced
+structure withstood the worst of the assault the bombs failed to damage the rebuilt deuterium
+electrolysis facility and our new stocks of heavy water were protected by the seven storeys of
+reinforced concrete above however the powerplant itself has been damaged and this second raid on the
+plant raises the possibility that our enemies have agents working within it in discussion with
+officials from die alchemist en group it has been decided that the facility should be shutdown
+existing stocks of heavy water and potassium hydroxide will be shipped to their laboratories and
+manufacturing facilities in germany for further enrichment and experimentation given the risk of
+local espionage we will need to significantly enhance security for this operation finally we should
+note that the attack killed twentyone norwegian civilians this is valuable propaganda and our agents
+are doing their best here and in london to ensure that the norwegian population understands who is
+to blame for these needless deaths
\ No newline at end of file
diff --git a/2020-early/9a.ciphertext b/2020-early/9a.ciphertext
new file mode 100644 (file)
index 0000000..1745c0a
--- /dev/null
@@ -0,0 +1 @@
+IRZDQ PSEID VQHWW THVUY MDWGQ BYSRO UFZFR TPIBE XKCZW XRTXG POOSV KBTWX TSIDK AAXMV RYTRI RJTWQ XIVAQ UHBQE SPBMJ ZSGWP WBTWT HGEDB EQJXH UITKI FAHBN XSACW SGHUI JELGK MFVEM KZMUD GNREK PQLKO POUFD QEHFX AIZTQ LASEE JCEMQ MFNGL JBTWF GRPWV ADWFO VRPGM DSMWB RBCIO GGGVH FIIND XOZSV EBAXK CYPJE OELHQ XABJA QJBCH WMPLM ETURH XZBTL PCYSD FUALB JRWFZ OTLVO EKPNI SGGGN REJMH WGDNW TVVSW KKNKP EAEMY TRVJE OPSFO TIPLZ MYXBG WJEBT WIZNR UYIHW VCAJJ IUQVM VNXUY QEZTG FPPNM PLAST ISDIZ HEOAX PJPUH MVRVF DIUFB BTWUF KWKHT CSURA EANAC ISFFU VXHBH JVIXU ASZMT KMZJX GREST PRSVW YMUZM EAGPR VMZVU FIFRT BIIFA HBSSS KPQKA WCQFE BOAOW YMBEA MJXBB PPEOQ JTZYS XVLMU VSFWU FBTWK OVPXR GMFWD NXSFT EZTJR FFVVE LXDCI ELXEW VIEMU PIFSE ZGLFI IUDPO LWURB UGGGU ETSMQ FLWTR JWQOS GHYCJ EKDWT GRHTN IXDHK UEWVU MLVVR HUYQE TRWAG SVIEA GUGLF ZZAOG GHVWV QXDTB PIPEB TWKXH OBETU FXOAH QIWBG LSQEO LUNWK CSTMR VELHW AXFIK QHMHU ITYQB EXBGF VKBTW XBUEO TMPKX QHVJK GYSDS VXWVZ KMGZV OFCGF ZTHNW URVPS KRFEC FBMYX KBYMU AGUVS RHJEL AAGUZ SSVBT SGRRP BPQZY MVRWI ZXYWG HNPUV ZZSMW IITZV ODNRV RHKPQ DHQNP GVZDQ KCHXF JIDWU SVRHR KFAOS YCDFV EAWSE IERAI AMVGL FRQDJ TWQGJ MQXAT BPETL IXLBS FESVI YSCCE GPEAU VXFNX JFVNM MHUIQ CIZLW WEIDK WDTCO ERFEQ XKLSA MTJGY HTHUI UZKMF WANCC VINDX HBMOW TGWGQ RXIVL MLXOA HUZUQ GYGUM QDMZL BBBVE VZFGK SQYDV BTWKW FOPEK QEHFR SVIIS WGHFL BMMNW XBFYD TMEKY IYMOZ VFWKQ RTUZV SWGSZ CDFUY MGWPE UZWZK VCAGF IVUFZ HUINZ AEAHB NREKP QWGQY STVLF WESTV BDAGE FOEMT ZVSLA SCPBE AOGGT VVNJW GJHKA MOMME LBUNX JFVEO BHUXI ZAUFA OAHJK PUFDH UITNI XDHKG IBDEU DEPRE CCMFG XLRGV KMMKN QPITJ NGDLO OSURO QSGRU SQVNG DEMGI SDQZS MSGLF XMDET BAYDC MMJPS NTPEA BJHUE ENCMF KACCI XVKMF XBQXI ZAEGH BCLJC
diff --git a/2020-early/9a.plaintext b/2020-early/9a.plaintext
new file mode 100644 (file)
index 0000000..2badc44
--- /dev/null
@@ -0,0 +1,18 @@
+harry we received further encouraging reports from swallow about the effects of the usa afraid the
+secondary targets of the attack were the station at rj uk an the industrial tracks and the track to
+ve mork while the railway tracks themselves remain operational a considerable amount of rolling
+stock was seriously damaged with two locomotives eight cargo wagons and seven passenger wagons
+suffering damage our agents in the plant have confirmed that this has slowed the german plan to ship
+the remaining stocks of potassium peroxide to die alchemist en research facilities in berlin in
+preparation for the shipment civilians are no longer allowed access to the railway and patrols have
+been stepped up security at all the railway stations has been significantly increased swallow have
+matched this by increasing their own surveillance on the rj uk an line and proposed a number of
+plans to intercept the shipment but the enhanced security make it very unlikely that a standard
+sabotage would succeed in doing more than delaying the shipment alternatives including the local
+ferry routes are being actively considered as with the air raid civilian casualties area major
+consideration but the plant director bjarne nilssen is sympathetic and maybe able to influence the
+dateandtime of shipment in order to reduce the risk once more our agents have been successful in
+intercepting enemy communications concerning the mission and the enclosed telegram summarising the
+plans confirms our own investigations with this in hand i think the swallow team will be able to
+execute a successful sabotage and hopefully terminate the german nuclear weapons program lets hope
+we can end this soon phil
\ No newline at end of file
diff --git a/2020-early/9b.ciphertext b/2020-early/9b.ciphertext
new file mode 100644 (file)
index 0000000..4577f2b
--- /dev/null
@@ -0,0 +1 @@
+-..- -... --. --. ..-. --- - -.. .. ...- ..- .- - ..- -... --. --. ..-. -- / ...- --.- / ..-. .-. .-. ..- --. .-.. --.- -.. .-- .... / ... - .. ...- . -..- -- ... .-. .-- / -.- - .-- / -.-- -. --- ...- ... -.- - --.. / ...- -- / -... .--. -- / . -. ...- -..- .- - / --.. -... -.-- -. . -- -.. / . --.. / ..-. - --.- / ... -. --. ..- .-. . -.-- -. .- --.- / --. .... -.-. -.. / .-.. - .-- --. -... .--. .-. .-- .. .... .. --. - -..- ..- - -.-. ... -..- - -.-. .... .. / ..-. ..- .... .. . -.. -.. ..- -... / -.- ..-. / . ... .- ..-. .-.. ... .- ..-. / .-.. -- - -- -... .... --. / -- -.-- .-- --- .-.. -.-. -. ... / -. --- .--- -.- / ... .-- -.-- -.. / -.-- -..- --.- -..- ..-. .. .. .-.. -.- / .-. -- / --. --.. ..- -.. / .-. . ... .--. --- -. ... .. -... .. .-.. .. - -.-- / --. .--. ... / ..- --. . .-- - -.- ...- .- / .-. .. / -..- .-.. .. / .-- - --.- --.- -. ... .-.. / -.-- --.. ..- .. --.- / --.. .- ...- .-- / .-.. --.- -- / .--- ..- .-.. --.- -. ...- .-. -... -.-. -. .-- / -.. -.-- / -.-. .--. . .-.. - -.-- / .- .... --.- -.. -- -..- -..- / .--. -... --.. --.. -. .- --.- / -.-. - / .. .-- - / -.-. -.-- .. .. -.-- . -.. / .--- -.- ..-. --. / --. .... .-- .--- ... .-.. .- --. ..-. ... -.. / ...- .... --. -- -.- .... . / ..-. -.-. -.-- -- / .-. -.. --- -.-. / .--. -.. .- / -.-. -... .. .- -.. -... -.- .- -..- --- .--- -... --- ..-. -... / --.- .-. -- -. / ... --.- --.. -... .--- / .- -. -.. / ..- ... -... .--- --- / ..- --. . .-- - -.- ...- .- / .-.. ...- / -..- .-.. .. / .-- .--- -..- ..- - ... -..- -. --. -. --.- -. -.-- -.. / ..- .-.. / --. -... -. -.. .... .--- --- / .- -... .-- -..- / .-.. -..- -.. .-- -.-. -. .- .-. .-- -.-. -. ..- ..- .-. .--. -. .-- .-.. -. / -.. -.-- / -- .--. / ..-. - --.- / . .-. ..-. -.-. -... .- ..-. ...- --- ...- -.-- ...- --. .-.. / -.-. - / .. .-- - / --.- .-. -- ..- -..- .... / .--- -.- ..-. --. / .- ..-. .-.. .-- -.. -.. .- -.-- .-- ..-. ..- .-- / ...- .... --. ...- -..- -.- --. -... --. --.. / ..- ..-. ..-. / ...- -. -.- --.. -..- --- -. / -.- -... / --.- . -... / -.- --. --.- --.- --. -- .-.. / ... -. / -... . / -.. .--. .--. ... . .--- --- -... ..- ..-. . / -..- -.- -.-. / .-- -.- .... / .-- -- --. .-.. .. ...- .-.. .. -- -..- .-- .... -- .. .-. .-- -..- / -..- -.-- - ..- / ...- .-. --. - --.. / -.- .--. -.-- .-.. .--- .- ...- -.-- / .--- .-. .. --.. ...- -- / .-- .-. ..- -... -... -. .-- / ... -.-. / -.-. .--. -.. .- --.. -.-- -.. - -- .-- .--. / .-. .- -.. / -.-. . .-. -.-. -. . -. --. ...- -... .- / -.-. - / .. .-- - / .. -..- -.-- ..-. -.-. ..- -.. .--- / .--- -.- ..-. --. / --.. .-- / .- - .-.. / -.-. .... --.. .. .-.. --. -.-- -..- / .--. -. / .--. -.. .-- .--. / . -... / ..- --. .--- .--- / .- -.. / .-. . .- -.. -.-- / ..- .--. / ..- .--- -.- .-. / .-- -.- .... / -- -..- .. --.- / - ... / -.-- .- - .--- --. . / .- -.. .-.. ..- .- .--. .-.. .- --- / -. -- .--- --.. -.-. .. --.. --. / -... -.-. -..- -.-- / --- ..-. --- -... .. -.-- -..- --- / - -.-- --. --.. .-- --. .--. --- / ..- --.. / --. ..- .-. / --. ...- .-- -.. .- ... -... .... / .. -.. / .-. ..- / -- ...- -.- -.- ...- ..- / - --.- / -- .- -..- / ..-. .. .-- ..- ..-. / -. -..- -.-. .--. --- ..- -. --- ...- .- .- --.. --. / --- .--. -.- .-.. / --- -... -- .-.. --- --.- .--. / -- -.. / --.. -- -..- / .-. . ... .. ... - .- -. -.-. . / -... -.. ..- .--- .-- .--- ..- --.. / -.-. - --. / .-- .-. / ..-. .. / -.- - .-- -... ..-. .-- .. .--- .. / --.. ..- / .- --- .-.. / .. .--- . -- .--. --.. / -... -.-. -..- -.-- / -- -.- -.-. ..- -.-. / . --.. / -. --.- / . .-. .--- .-. ...- - ..- .-. --.- / --- .... / --. -.-- .--- --.. .--. -.-. / .--- . / ...- . .--- .-.. .. ...- / .-.. --.. .-- / . .... - .-- / -... ..- -- / .. .--- --- / -..- .- .- .--- / --.- -..- .--- -- -... --- -... .- / ..- --. .-. ..-. / .-. ... -. --- / .... .- -. -.. --- ...- . .-. / ..- .--. / -.. --. / .--. .-. --.- .-.. .-- .-. ..- .... --. / --. .--. ... .-- .. .--. -.-. / ..-. -.-- / -.- -... -.- -..- . / --.. .- .... -. .-.. / .--- --. / .. -.. .--. ..-. .--- .-.. --.- / -.-. -.. -.-- --.. / .-.. .-- .-- / -.. .- -..- -..- ..- --.. ... / ..-. --. -... .--. -..- / .... -.-. / --.- - / -.-- -.. .. ..-. ..- ... .--- ..- - / -.- -.-- ..-. .. ..-. .-.. -..- -.-- -.-. .--. / - --.- / .--. -..- .- -.- ..-. - ...- .- -- .-.. -- -.- -..- -... -.-- -..- --. .-- -... -..- --. .-.. -- / ...- -.-- --.. .. .-.. -.-- / --. .--- ...- -.-- -.. .. -... / --- .--. -.- .-.. / .. .-.. -..- .- ..-. -.- -.. / -. .--- -.-- .-. -.. -- .--. -.- --.- / ... -. / -... . / .--- --- - --.- ..-. -.. ..- ..-. . / ..-. -.-. -.- -. .- / -..- --.- .-- .-.. --- / -..- .-.. .. / -..- -- -. ..- .-. .--- ... -.-- / --. - .--- / --- ...- -... -.-- ... ..-. / .-.. -.-. --.. --.- ...- --- / -.-. --.- -. / -.-- --.. --- -... -.- -.. ... -.-- -..- / -.. . --.. .- / -..- --.- -- .... --.- / .--. -. .- .--. .-. -.-- -.-- .-. --.- / - -.-. ..-. / .--. .- .- / .--- .... . . ..-. .. / .-. . ..- / .... --. -.. .- ..- .-- / .-.. -- .... .. / -.-- .--. -.-- .-.. ... / ...- -- .... - / --.- .--- . .--. / ..-. -.- / .-. ..-. -.-. / ..- .... -... .... -- .... ... -..- / .. ... / ... ..-. .-. ...- .--- ... ..-. . / ...- --.- / ... ..- .-. -.-- .-.. --. .... / -.- -.-- . ...- .... / ..- ..-. -.-- .-- - --.- -..- / .-.. ..- -..- / -.-- ...- ... ... .--. ..- -. / .- -... .-- -.- ... / .- -..- -.. -.-. -. / -.-. -.. -.-- --.. / -.-- - .--. .-- -.. .--. -.-- / ..-. .- / --- .-. / .-- -... --. .... ..-. .. --.- .... ... .-. / .. -.. / . .... .-- --.- -.. -.-- .. ..- / -.- -.-- ...- / .-.. .--- ... ..-. -.- .... --. .--- .-.. / .... -.-- / -. -... -.-- / -. -.-. -.. -.- .... --.. .. --- / --- .--. -.- .-.. / -.. -... . -... ..-. .--- -... / -.. -.-. .--- -... -. -- .--- --. -..- -.-. --. / ... -. / -- --- -. .. - --- .-. / - ..- -... --. --. / -.-. ...- / .... -.-- .... ..- -... / .-- -..- . -..- -- ... .-. / ..-. ... .. / ..- - / .-.. -.-. .-.. -.-- ..-. / -... --.. .. --.- ...- / -... -.-. -..- -.-- / --- -..- -.. -... .. --. -.- .. -.-. / . --.. / ..-. - --.- / -.-. -.-- -. .- --. / --- -... .-. / --. .--. -..- .- / ...- --.- ... -.-- -... -.-- .--- -.-- ..- .. / -.- ..-. / - .-- / --.. -. - -.- .-- -..- .-- / ...- ... / .-. --.. -.-. -- .... ...- -..- -.-. --- -. --- -- --.. -.. .- --.. .. -.-- -.. --.. .. -. --- / .-.. .- -. --- -.- .--- .--- .- .... / -..- --.- / -.-- .--- .--- / ... .... .-.. -.. .-. / ... - --- .--. / . .--. .--. ... - / ...- --.- / .-- -.- .... / .-- -..- ... ...- . -.- .. / ..-. ... .. / --.. -..- --. - -.-- ...- ..- -..- --.. / -- .... .--- .--. ... .--. .- .--. .-.. --.. / -... .-- / -.- -. / ...- -.-- -- ..- --- -. / .-.. . / -- -..- -..- / --. ...- --.. .-. ..-. / --. .... -.-. -.. / -.. .--- .. .... -..- ... - / .--- -..- ..- / -.-. ..-. -..- --.. .--- -.- --.. - .--- / .-.. .-- ... . / - --. .-- / ..-. .. .-- ..- ..-. / -. --.. -..- .--. -- -.. --- - / -.- .-.. .- -. .-- .--. . -.- .--- --- / .-.. -.- .. ...- / -- -.. -.. --. .- -.-. .--. --.- / -. . / - .... . / - - / -.-. .--. ..-. / .--. .... .--. . .... ..- ...- / ... .--- / .. -. .--- / --. .-. .. -. -.- ... --- -.-- --.. -.- - / .--- .... ..- / .--- -- / .-.. -..- -.-- .-. -. -- / ... -..- -.. -.-- / . ... .--. / -... -..- -- --.. . / ..-. --. -... -.-. / .... .-- -... -... -.-. --. ... .... / .. -.. / .-. ..- / --. .. ...- --. .-. .. ...- ..- / .-.. --. / -.- -..- ...- -..- -... --- -..- / -. -... -.-- / -. -.-. -.. -.- .... --.. .. --- / -..- --.- .--. / -.- .-.. / --. .-.. -... --. .- -.-- .-. --. -- .-.. / .-. --. -. - -.- -.-. / -... . / .... .--- .-- ..-. --- / --.- .... / .-- -.- .... / .-. . -..- -.-- ...- .. / - -.- / --.. -. -.- / .--- .... -.-- -. ...- / .- -... .-- -..- / -..- .- -- -. .- -... / .--. -.-- -... / --.. -.-- .... .-.. -.-. --- -.. / . - ..- -... -.-- --.- --.. ..-. / ... . -... --.. / .... .-- -... -... -.-. --. ... .... / .-.. -..- .- .- / .-. ..- / --. .. ..-. -- --.. ..- ...- ..- / -.- .-- .... ... .--- ... .-.. .-- -.. --.- / .-.. -- .... .. / .-.. -.. --- . ..- .... --.. .. -- / --- .--- / -..- .- / -- --- -... -- -..- --- -... .- / -.. -- .--. / .-. --. .... --- .-.. -.. -- ... / .- ... / -... / ..-. --. . --.- .- / ...- .-- .-. ... / -.- -.-- . ...- .... .-- / -.-- - / .... -.- / .-- ... .... .--- .-.. -.- / --.- ...- / -.-- .- -..- ...- .-. .-- -. .-- -.-. / --.. -.-- -.-. ... -.. ... -.-- -..- -.-. / --.. -.-- / ..-. - ..- . / .. .-. ..-. ..-. .-. -.-- / --. .... -.-. -.. / .... ..- / -..- --- - .... . / -.- ..-. / - .-- / -. .-.. -..- .-- / -. .. / -. -.-. -.. -.- / .--. -.. .- / -- --- .-.. .- .-. --.. --.- / --.- .-. -- -. / -.- -. --.. -.-. .... -- ..-. / .--. .-.. .- -. ... / ..- .--. / -.. --. / .... ...- .-- -.. . --- .-.. ...- -.- .... --. / .--- ... ...- / ..-. / .--- .- ... ... . / .--- .... -.-- -. ...- / .-- ...- / -... --- / -... - . -.- ..- -.- -..- .--. -.-- -.-. / -.. . --.. .- / -- .--. .--. ..- ..-. ..- .- --.. -- -..- / ..-. .-. .--. .... . ...- --. .-.. / .- ... --- --. .. ..-. ... --. / .... .-- -.. .--- .- ... / -.. . .--- / ... ...- / .... -- .-.. / -... --. / .--- ..-. ..- .-- -.-- / .--- .. / .--. -.. .- / .. -..- -.- .- ..-. -.- -.. / --.- .-. -.-- . -.-. / . -. --.- / ... ..-. / .. --.. . ... .--. / ..- ...- --.- .-. / ...- .... ..-. -..- ..- .-.. .-- -... / ...- ... -.-- -..- -- .-. .. .-- / .-. --.. -..- -.-- / .... -.- / - .... .--. ..- .- .... .--. ..- .-.. -.- / --.- ...- / -..- .- -- -. .- / -.. -.-- / -.-. .--. - -.-- --.- --.. -.-. -. .--. / ..-. - --.- / --.- .-. .--. -... .-.. / -.-. -... / --. -.-- .--- --.. .--. -.-. ..- -.. .... / .. .--- . ..-. / -.-- ...- .-. -- .--. / --- ... .-.. .-- .--- / -- .... / ...- -.-- / ..-. --.. -.- --- / --.- .--- --.. .- -. / .-.. -.-- .--. -... --- ... -..- --.- ..-. .-.. -.- / -.-- .-. / --.. -.- -.- / - .. -- . ... / - ..- .--. --.- / --. --.. ...- - -.-. / ...- .... ..-. -..- ..- .-.. .-- -... / -..- ... / --. .--- / ...- -..- ..- -... --- .--- -.- .--- / ...- ..- / .. - - / -.-. .- .--- .-- -... -.-- -..- .- -.-. / . -..- -.. ... ...- / . ... .--. / --- -- -.. ... .- / ..- -. ..-. / ..-. ... --- --.- ...- ... .-. / ... -..- - / --.- -... ... -..- ..- -.-. -.-- .. .--- ..- -.. / .--- -.- ..-. --. / -.. --. ..- ... -.. / .... -.-- -.-- -... ...- -... - . .-.. / ..- .... -..- / --.. .... -.- --. .--- - --.. --.. -. / .-- -. .- / --.- .-.. / --.. -.-. / --.. .-. .-. - .-.. -.. -.-. / - --- / -..- .--. ... .-.. / .... --.- - / .-- -.- .... / ...- .. .-- -- .-- -..- . .-. --. .. / --.. ... --.- .--- -..- -..- / -... -.- --.. --.. -.- .--- / --.. .- ...- .-- / --.- ...- -. .-- --.. ..- .. -... --.- .-- ...- / .--- -.- -..- -.. -.-. / -.. .-. --- / -.. ... - .- -..- .--. -.-- . / . - .- --. -..- .--. / --- .-. / ... -... --.- ..-. -- -.. .... ... .-. / .--- .... -..- -.-. ...- / -..- -.-- .-- -..- / -..- .. .-. ..- ...- / -..- .- .-- -.. ...- / ...- -... .. .- -..- -.- .-.. / -- -. .. .--- / --- --.. .... -.- .--- -- ...- -- - / --- .- -.-- --.- -. . .--. ..- / .--- -... -..- .--. .-. --- -... .--. / .- -.-- .-.. / -. -- -.- -..- / -... . / -- .--- --. ..- ..-. . / --.- .--. . --. / .-- -.- .... / --. . ...- -.- ... / -- ..-. -..- / -..- -.- --. .. -. -.- .--- / .- --- .-.. / ...- -- ..-. -... / -... -.-. .--- .--. .-. .-- .--. / --.. -.-- -.-. -.. / -.. . --.. .- / --.- .--- ..-. -.. -- / . .-. ..-. -... .... . .--. .-. ..-. / --.- --- -... / --.- - / ..-. .... . .-.. -.-- - ..- - / .-- ..-. .. / ... -.. -.. / - .-.. .. -..- ...- -- .-.. / .. --.. / --- -.-. -.. -. / .. . --- --- . -.- .--- / .-.. -.- / .--. -.-. --- ... -.-. --.- .-. / ... -. / -.. .. . / -... -- -.. .. ..-. -. .--- - ..- ..-. --- / ..- ...- --.- .-.
diff --git a/2020-early/9b.plaintext b/2020-early/9b.plaintext
new file mode 100644 (file)
index 0000000..10f16bb
--- /dev/null
@@ -0,0 +1 @@
+WAFFENSCHUTZSTAFFEL TO COORDINATE OPERATIONS FOR SHIPMENT OF THE VEMORK PRODUCT TO THE FATHERLAND STOP WEHRMACHTSTREIFENDIENST PERSONNEL TO MAINTAIN STATION SECURITY STOP WACH BATAILLON TO HAVE RESPONSIBILITY FOR SECURITY OF THE ROLLING STOCK STOP DIE ALCHEMISTEN TO RETAIN OVERALL COMMAND OF THE MISSION STOP OPERATIONAL CONTROL LIES WITH THE FELDGENDARMERIE STOP TRACK AND TRAIN SECURITY IS THE RESPONSIBILITY OF ZUGWACH STOP COUNTERINTELLIGENCE TO BE THE RESPONSIBILITY OF THE ABWEHR STOP INTELLIGENCE CONCERNING ALL ASPECTS OF THE MISSION TO BE COORDINATED VIA THE SICHERHEITSDIENST STOP PLANT DIRECTOR BJARNE NILSSEN IS RESPONSIBLE FOR PREPARATION OF THE SHIPMENT STOP HE HAS INFORMED US THAT HE WILL BE READY TO SHIP THE ITEM ON SUNDAY TWENTIETH FEBRUARY STOP EVERYONE INVOLVED IN THE SHIPMENT TO BE VETTED BY THE LOCAL SCHUTZSTAFFEL STOP REPORTS OF ANY RESISTANCE ACTIVITY ARE TO BE FORWARDED TO THE ABWEHR STOP CASKS TO BE REWEIGHED AT RJUKAN TO ENSURE THE LOAD HAS NOT BEEN TAMPERED WITH STOP HANDOVER TO BE MONITORED CLOSELY AT EVERY STAGE BY ZUGWACH STOP ALL ROLLING STOCK TO BE INSPECTED THOROUGHLY BY WEHRMACHTSTREIFENDIENST BEFORE LOADING STOP LOADING PLATFORMS TO BE INSPECTED DAILY UNTIL THE SHIPMENT AND HOURLY DURING THE OPERATION STOP LEAVE CANCELLED FOR ALL TROOPS AND POLICE STOP EVERY ARMY UNIT IN THE VICINITY IS REQUIRED TO PROVIDE GUARD PATROLS FOR ROLLING STOCK ROUTE STOP NIELSEN TO BE INSTRUCTED TO ORGANISE THE TRANSPORT OF THE SHIPMENT STOP GEHEIME FELDPOLIZEI TO MONITOR STAFF AT EVERY STATION AND ON EVERY TRAIN STOP ENTRYWAYS TO THE PLANT AND RAIL FACILITIES TO BE GUARDED BY WEHRMACHTSTREIFENDIENST PERSONNEL AT ALL TIMES STOP DOORS TO THE STORAGE AND TRANSPORT FACILITIES TO BE LOCKED AT ALL TIMES STOP OUTSIDE THE LOGISTICS TEAM AND LOCAL SECURITY OPERATIONS ONLY OFFICERS OF THE SS AND MEMBERS OF DIE ALCHEMISTEN CAN BE COPIED INTO THE PLANS STOP TINNOSET TO BE PREPARED TO RECEIVE THE SHIPMENT BUT NO INDICATION SHOULD BE GIVEN OF THE NATURE OF THE CARGO STOP ORDERS FOR ONWARDS SHIPMENT FROM TINNOSET WILL BE PROVIDED SEPARATELY STOP RJUKANFOS TO BE PREPARED FOR SHIPMENT AS A DECOY STOP GUARDS TO BE PLACED IN PROMINENT POSITIONS ON THIS VESSEL STOP SF HYDRO TO BE USED TO SHIP THE PRODUCT STOP LOADING PLANS TO BE ESTABLISHED FOR A DUMMY CARGO ON SF RJUAKANFOS STOP ADDITIONAL SECURITY MEASURES SHOULD NOT BE PUT IN PLACE ON THE LANDING STAGE FOR SF HYDRO STOP SECURITY ROUTINES MUST BE MAINTAINED IN ORDER TO REINFORCE THE DECOY ON RJUKANFOS STOP HEAVY WATER TO BE KEPT UNDER OBSERVATION AT ALL TIMES STOP EXTRA SECURITY TO BE PROVIDED ON ALL TRANSPORT UNTIL THE CARGO HAS REACHED DIE ALCHEMISTEN STOP LOCAL OFFICIALS AND EMPLOYEES ARE TO BE ASSUMED TO WORK FOR THE RESISTANCE UNLESS VETTED STOP INFORMATION ABOUT THE SHIPMENT SHOULD BE ENCRYPTED USING HIGH GRADE FIELD CIPHERS STOP TEMPORARY SECURITY MEASURES CAN ONLY BE LIFTED ONCE THE CARGO HAS REACHED THE NEXT STAGING POST STOP EXTRA RESOURCES CAN BE PROVIDED FOR ALL ASPECTS OF THIS MISSION ON REQUEST TO DIE ALCHEMISTEN STOP
\ No newline at end of file
diff --git a/2020-early/morse.txt b/2020-early/morse.txt
new file mode 100644 (file)
index 0000000..578b456
--- /dev/null
@@ -0,0 +1,49 @@
+A      .-
+B      -...
+C      -.-.
+D      -..
+E      .
+F      ..-.
+G      --.
+H      ....
+I      ..
+J      .---
+K      -.-
+L      .-..
+M      --
+N      -.
+O      ---
+P      .--.
+Q      --.-
+R      .-.
+S      ...
+T      -
+U      ..-
+V      ...-
+W      .--
+X      -..-
+Y      -.--
+Z      --..
+0      -----
+1      .----
+2      ..---
+3      ...--
+4      ....-
+5      .....
+6      -....
+7      --...
+8      ---..
+9      ----.
+.      .-.-.-
+,      --..--
+?      ..--..
+-      -....-
+/      -..-.
+:      ---...
+'      .----.
+-      -....-
+)      -.--.-
+;      -.-.-
+(      -.--.
+=      -...-
+@      .--.-.
diff --git a/2020/2020-a-challenge1.ipynb b/2020/2020-a-challenge1.ipynb
new file mode 100644 (file)
index 0000000..17459fa
--- /dev/null
@@ -0,0 +1,173 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {
+    "Collapsed": "false"
+   },
+   "outputs": [],
+   "source": [
+    "from szyfrow.caesar import *\n",
+    "from szyfrow.affine import *"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {
+    "Collapsed": "false"
+   },
+   "outputs": [],
+   "source": [
+    "challenge_number = 1\n",
+    "plaintext_a_filename = f'plaintext.{challenge_number}a.txt'\n",
+    "plaintext_b_filename = f'plaintext.{challenge_number}b.txt'\n",
+    "ciphertext_a_filename = f'ciphertext.{challenge_number}a.txt'\n",
+    "ciphertext_b_filename = f'ciphertext.{challenge_number}b.txt'"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {
+    "Collapsed": "false"
+   },
+   "outputs": [],
+   "source": [
+    "ca = open(ciphertext_a_filename).read()\n",
+    "cb = open(ciphertext_b_filename).read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {
+    "Collapsed": "false"
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "14 \n",
+      "\n",
+      "The British Daily Herald article on so called spyclists has raised concern at government levels that the large increase in travel from the Continent has masked an infiltration operation by the Abwehr.\n",
+      "SIS has received reports that Hitler Youth groups travelling abroad have been asked to complete a detailed questionnaire, including questions on terrain, population, and political views of the population. VK has taken a personal interest in the story but his resources are fully allocated in investigating a number of suspected German agents already living in the UK, so BOSS has been tasked with investigating and reporting on the spyclist touring network.\n",
+      "Harry is currently engaged investigating Die Alchemisten so he has asked our team to take this on. While it is possible that the cycle tourists are operating as a forward observer division in preparation for a future invasion, the small numbers involved, and their travel routes make it seem likely that this is at most a feint designed to draw our resources away from more significant operations. What we do know is that there is an intelligence dimension to this since our operatives in the GPO intercepted the attached encrypted message in a bundle of letters left poste restante for one of the touring parties at a Scottish post office. Our first task is to decipher this message and to analyse its contents. Even if this turns out to be a diversionary tactic it provides us with an opportunity to develop our BOSS home intelligence operation and we will be treating the mission seriously. Operatives from all three BOSS divisions will be working together at the Broadway to intercept, decipher and analyse potentially relevant sources. We will be posting updates here in the mission pages using standard protocols. Since our communications are protected we will, for now, use tier one (Caesar and affine shift) encryption. Your field issue cipher wheel is attached, and your first task is to decipher the attached message and to study it carefully.\n",
+      "Pearl.\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "k_a, score_a = caesar_break(ca)\n",
+    "print(k_a, '\\n')\n",
+    "pa = caesar_decipher(ca, k_a)\n",
+    "print(pa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {
+    "Collapsed": "false"
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2020"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_a_filename, 'w').write(pa)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {
+    "Collapsed": "false"
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "6 \n",
+      "\n",
+      "My dear Jessica, I am writing to wish you well in your new life. I am sure you will not forget us, and you can be sure that we will not forget you. May your business flourish to the great benefit of us all. You might be concerned that with the growing uncertainty in the homeland we will find it difficult to continue to communicate, but love will find a way, and I am sure you love your homeland as much as we do. We trust that our effort to stay in touch will be rewarded by an equal effort on your part. I hope that my nephew Karl, who brings you this message, will be able to help you further with these matters. In the meantime, perhaps you can help him. He is a great lover of trains, canal boats and aeroplanes, and it would be a great kindness if you would agree to help him to explore some of the many transport treasures hidden across the UK. It is an unusual passion but I hope that you will feel able to assist him in this. He is particularly keen to explore the possibility of photographing as many of the intriguing travel sites as he can. I seem to recall that Uncle Wilhelm introduced you to the fascinating hobby of photographic reproduction when you stayed with his family in Tirpitzufer. If you were able to assist Karl by developing his films and forwarding them to his home that would, I am sure, avoid unnecessary delay and a great deal of unpleasant misunderstanding. If there is any way we can assist you in your valuable work please let Karl know and we will endeavour to oblige you. Your dear friend, Nikolaus R.\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "k_b, score_b = caesar_break(cb)\n",
+    "print(k_b, '\\n')\n",
+    "pb = caesar_decipher(cb, k_b)\n",
+    "print(pb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {
+    "Collapsed": "false"
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1539"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open(plaintext_b_filename, 'w').write(pb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "Collapsed": "false"
+   },
+   "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/2020-a-challenge1.md b/2020/2020-a-challenge1.md
new file mode 100644 (file)
index 0000000..cc8955b
--- /dev/null
@@ -0,0 +1,58 @@
+---
+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 Collapsed="false"
+from szyfrow.caesar import *
+from szyfrow.affine import *
+```
+
+```python Collapsed="false"
+challenge_number = 1
+plaintext_a_filename = f'plaintext.{challenge_number}a.txt'
+plaintext_b_filename = f'plaintext.{challenge_number}b.txt'
+ciphertext_a_filename = f'ciphertext.{challenge_number}a.txt'
+ciphertext_b_filename = f'ciphertext.{challenge_number}b.txt'
+```
+
+```python Collapsed="false"
+ca = open(ciphertext_a_filename).read()
+cb = open(ciphertext_b_filename).read()
+```
+
+```python Collapsed="false"
+k_a, score_a = caesar_break(ca)
+print(k_a, '\n')
+pa = caesar_decipher(ca, k_a)
+print(pa)
+```
+
+```python Collapsed="false"
+open(plaintext_a_filename, 'w').write(pa)
+```
+
+```python Collapsed="false"
+k_b, score_b = caesar_break(cb)
+print(k_b, '\n')
+pb = caesar_decipher(cb, k_b)
+print(pb)
+```
+
+```python Collapsed="false"
+open(plaintext_b_filename, 'w').write(pb)
+```
+
+```python Collapsed="false"
+
+```
diff --git a/2020/ciphertext.1a.txt b/2020/ciphertext.1a.txt
new file mode 100644 (file)
index 0000000..794b2e5
--- /dev/null
@@ -0,0 +1,4 @@
+Hvs Pfwhwgv Rowzm Vsfozr ofhwqzs cb gc qozzsr gdmqzwghg vog fowgsr qcbqsfb oh ucjsfbasbh zsjszg hvoh hvs zofus wbqfsogs wb hfojsz tfca hvs Qcbhwbsbh vog aogysr ob wbtwzhfohwcb cdsfohwcb pm hvs Opksvf.
+GWG vog fsqswjsr fsdcfhg hvoh Vwhzsf Mcihv ufcidg hfojszzwbu opfcor vojs pssb ogysr hc qcadzshs o rshowzsr eisghwcbbowfs, wbqzirwbu eisghwcbg cb hsffowb, dcdizohwcb, obr dczwhwqoz jwskg ct hvs dcdizohwcb. JY vog hoysb o dsfgcboz wbhsfsgh wb hvs ghcfm pih vwg fsgcifqsg ofs tizzm ozzcqohsr wb wbjsghwuohwbu o biapsf ct gigdsqhsr Usfaob ousbhg ozfsorm zwjwbu wb hvs IY, gc PCGG vog pssb hogysr kwhv wbjsghwuohwbu obr fsdcfhwbu cb hvs gdmqzwgh hcifwbu bshkcfy.
+Voffm wg qiffsbhzm sbuousr wbjsghwuohwbu Rws Ozqvsawghsb gc vs vog ogysr cif hsoa hc hoys hvwg cb. Kvwzs wh wg dcggwpzs hvoh hvs qmqzs hcifwghg ofs cdsfohwbu og o tcfkofr cpgsfjsf rwjwgwcb wb dfsdofohwcb tcf o tihifs wbjogwcb, hvs gaozz biapsfg wbjczjsr, obr hvswf hfojsz fcihsg aoys wh gssa zwyszm hvoh hvwg wg oh acgh o tswbh rsgwubsr hc rfok cif fsgcifqsg okom tfca acfs gwubwtwqobh cdsfohwcbg. Kvoh ks rc ybck wg hvoh hvsfs wg ob wbhszzwusbqs rwasbgwcb hc hvwg gwbqs cif cdsfohwjsg wb hvs UDC wbhsfqsdhsr hvs ohhoqvsr sbqfmdhsr asggous wb o pibrzs ct zshhsfg zsth dcghs fsghobhs tcf cbs ct hvs hcifwbu dofhwsg oh o Gqchhwgv dcgh cttwqs. Cif twfgh hogy wg hc rsqwdvsf hvwg asggous obr hc obozmgs whg qcbhsbhg. Sjsb wt hvwg hifbg cih hc ps o rwjsfgwcbofm hoqhwq wh dfcjwrsg ig kwhv ob cddcfhibwhm hc rsjszcd cif PCGG vcas wbhszzwusbqs cdsfohwcb obr ks kwzz ps hfsohwbu hvs awggwcb gsfwcigzm. Cdsfohwjsg tfca ozz hvfss PCGG rwjwgwcbg kwzz ps kcfywbu hcushvsf oh hvs Pfcorkom hc wbhsfqsdh, rsqwdvsf obr obozmgs dchsbhwozzm fszsjobh gcifqsg. Ks kwzz ps dcghwbu idrohsg vsfs wb hvs awggwcb dousg igwbu ghobrofr dfchcqczg. Gwbqs cif qcaaibwqohwcbg ofs dfchsqhsr ks kwzz, tcf bck, igs hwsf cbs (Qosgof obr ottwbs gvwth) sbqfmdhwcb. Mcif twszr wggis qwdvsf kvssz wg ohhoqvsr, obr mcif twfgh hogy wg hc rsqwdvsf hvs ohhoqvsr asggous obr hc ghirm wh qofstizzm.
+Dsofz.
diff --git a/2020/ciphertext.1b.txt b/2020/ciphertext.1b.txt
new file mode 100644 (file)
index 0000000..5ed790a
--- /dev/null
@@ -0,0 +1 @@
+Se jkgx Pkyyoig, O gs cxozotm zu coyn eua ckrr ot euax tkc rolk. O gs yaxk eua corr tuz luxmkz ay, gtj eua igt hk yaxk zngz ck corr tuz luxmkz eua. Sge euax hayotkyy lruaxoyn zu znk mxkgz hktkloz ul ay grr. Eua somnz hk iutikxtkj zngz cozn znk mxucotm atikxzgotze ot znk nuskrgtj ck corr lotj oz jolloiarz zu iutzotak zu iussatoigzk, haz rubk corr lotj g cge, gtj O gs yaxk eua rubk euax nuskrgtj gy sain gy ck ju. Ck zxayz zngz uax klluxz zu yzge ot zuain corr hk xkcgxjkj he gt kwagr klluxz ut euax vgxz. O nuvk zngz se tkvnkc Qgxr, cnu hxotmy eua znoy skyygmk, corr hk ghrk zu nkrv eua laxznkx cozn znkyk sgzzkxy. Ot znk skgtzosk, vkxngvy eua igt nkrv nos. Nk oy g mxkgz rubkx ul zxgoty, igtgr hugzy gtj gkxuvrgtky, gtj oz cuarj hk g mxkgz qotjtkyy ol eua cuarj gmxkk zu nkrv nos zu kdvruxk yusk ul znk sgte zxgtyvuxz zxkgyaxky nojjkt gixuyy znk AQ. Oz oy gt atayagr vgyyout haz O nuvk zngz eua corr lkkr ghrk zu gyyoyz nos ot znoy. Nk oy vgxzoiargxre qkkt zu kdvruxk znk vuyyohoroze ul vnuzumxgvnotm gy sgte ul znk otzxomaotm zxgbkr yozky gy nk igt. O ykks zu xkigrr zngz Atirk Cornkrs otzxujaikj eua zu znk lgyiotgzotm nuhhe ul vnuzumxgvnoi xkvxujaizout cnkt eua yzgekj cozn noy lgsore ot Zoxvozfalkx. Ol eua ckxk ghrk zu gyyoyz Qgxr he jkbkruvotm noy lorsy gtj luxcgxjotm znks zu noy nusk zngz cuarj, O gs yaxk, gbuoj attkikyygxe jkrge gtj g mxkgz jkgr ul atvrkgygtz soyatjkxyzgtjotm. Ol znkxk oy gte cge ck igt gyyoyz eua ot euax bgraghrk cuxq vrkgyk rkz Qgxr qtuc gtj ck corr ktjkgbuax zu uhromk eua. Euax jkgx lxoktj, Toqurgay X.
diff --git a/2020/plaintext.1a.txt b/2020/plaintext.1a.txt
new file mode 100644 (file)
index 0000000..d8f8762
--- /dev/null
@@ -0,0 +1,4 @@
+The British Daily Herald article on so called spyclists has raised concern at government levels that the large increase in travel from the Continent has masked an infiltration operation by the Abwehr.
+SIS has received reports that Hitler Youth groups travelling abroad have been asked to complete a detailed questionnaire, including questions on terrain, population, and political views of the population. VK has taken a personal interest in the story but his resources are fully allocated in investigating a number of suspected German agents already living in the UK, so BOSS has been tasked with investigating and reporting on the spyclist touring network.
+Harry is currently engaged investigating Die Alchemisten so he has asked our team to take this on. While it is possible that the cycle tourists are operating as a forward observer division in preparation for a future invasion, the small numbers involved, and their travel routes make it seem likely that this is at most a feint designed to draw our resources away from more significant operations. What we do know is that there is an intelligence dimension to this since our operatives in the GPO intercepted the attached encrypted message in a bundle of letters left poste restante for one of the touring parties at a Scottish post office. Our first task is to decipher this message and to analyse its contents. Even if this turns out to be a diversionary tactic it provides us with an opportunity to develop our BOSS home intelligence operation and we will be treating the mission seriously. Operatives from all three BOSS divisions will be working together at the Broadway to intercept, decipher and analyse potentially relevant sources. We will be posting updates here in the mission pages using standard protocols. Since our communications are protected we will, for now, use tier one (Caesar and affine shift) encryption. Your field issue cipher wheel is attached, and your first task is to decipher the attached message and to study it carefully.
+Pearl.
diff --git a/2020/plaintext.1b.txt b/2020/plaintext.1b.txt
new file mode 100644 (file)
index 0000000..fb1ca93
--- /dev/null
@@ -0,0 +1 @@
+My dear Jessica, I am writing to wish you well in your new life. I am sure you will not forget us, and you can be sure that we will not forget you. May your business flourish to the great benefit of us all. You might be concerned that with the growing uncertainty in the homeland we will find it difficult to continue to communicate, but love will find a way, and I am sure you love your homeland as much as we do. We trust that our effort to stay in touch will be rewarded by an equal effort on your part. I hope that my nephew Karl, who brings you this message, will be able to help you further with these matters. In the meantime, perhaps you can help him. He is a great lover of trains, canal boats and aeroplanes, and it would be a great kindness if you would agree to help him to explore some of the many transport treasures hidden across the UK. It is an unusual passion but I hope that you will feel able to assist him in this. He is particularly keen to explore the possibility of photographing as many of the intriguing travel sites as he can. I seem to recall that Uncle Wilhelm introduced you to the fascinating hobby of photographic reproduction when you stayed with his family in Tirpitzufer. If you were able to assist Karl by developing his films and forwarding them to his home that would, I am sure, avoid unnecessary delay and a great deal of unpleasant misunderstanding. If there is any way we can assist you in your valuable work please let Karl know and we will endeavour to oblige you. Your dear friend, Nikolaus R.