4 <title>Keyword ciphers
</title>
5 <meta http-equiv=
"Content-Type" content=
"text/html; charset=UTF-8"/>
6 <style type=
"text/css">
15 h1 { font-size:
3em; }
16 h2 { font-size:
2em; }
17 h3 { font-size:
1.6em; }
19 text-decoration: none;
22 -moz-border-radius:
5px;
23 -web-border-radius:
5px;
31 text-shadow:
0 0 20px #
333;
37 text-shadow:
0 0 20px #
333;
51 <textarea id=
"source">
55 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
56 --|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|--
57 k | e | y | w | o | r | d | a | b | c | f | g | h | i | j | l | m | n | p | q | s | t | u | v | x | z
59 * Taking a more Pythonic approach
65 .indexlink[[Index](index.html)]
71 * Still character-by-character substitution, still monosubstitution.
73 Ciphertext alphabet: start with a keyword, write out the rest of the alphabet, removing duplicates.
77 Write out the rest of the alphabet...
79 1. ...starting from 'a' (keywordabcf...)
80 2. ...starting from the last letter of the keyword (keywordfgh...)
81 3. ...starting from the largest letter of the keyword (keywordzabc...)
87 _string_`.translate()` and _string_`.maketrans()`
89 * Make the 'ciphertext' alphabet, relate to the 'plaintext' alphabet (`string.ascii_lowercase`)
90 * Use those to make the translation table
91 * Enciphering is simply applying `plaintext.translate(enciphering_table)`
92 * Deciphering just uses a different table
96 # Making the cipher alphabet from a keyword
100 1. How to say which type of cipher alphabet to use
101 2. Where to start the rest of the alphabet
102 3. Removing duplicate letters
106 1. Keyword arguments for procedures
108 3. Use something like an ordered set
110 Both enciphering and deciphering need the same keyword-based alphabet, so pull this out into another procedure.
118 1. give a default value for a parameter
119 2. allow parameters to be named (not just positional)
121 Give our `keyword_encipher` and `keyword_decipher` procedures a keyword parameter of `wrap_alphabet`.
123 Pass this parameter to the `keyword_alphabet` procedure.
125 ## wrap_alphabet has no inherent meaning
126 Use Python
3.4's `Enum`
128 from enum import Enum
130 class KeywordWrapAlphabet(Enum):
136 (Use integers in earlier Pythons)
139 # Deduplicating a sequence
146 No ordered set in Python, but do have an ordered dict.
148 * Keys of a dict are a set.
149 * Keys in an ordered dict retain their order (subsequent instances are ignored)
151 `deduplicated_list = list(collections.OrderedDict.fromkeys(list))`
158 Write out the rest of the alphabet...
160 1. ...starting from 'a' (keywordabcf...)
161 2. ...starting from the last letter of the keyword (keywordfgh...)
162 3. ...starting from the largest letter of the keyword (keywordzabc...)
164 * Santitise the keyword before we use it
167 # Making the keyword alphabet
170 1. As we're deduplicating anyway, just add the entire alphabet to the end of the keyword, then deduplicate.
171 `deduplicate(keyword + string.ascii_lowercase)`
173 2. and
3. How to find the appropriate letter of the keyword.
175 `deduplicate(keyword + string_ascii_lowercase[from:] + string.ascii_lowercase)`
177 Question: why not take a slice of the second alphabet copy?
179 Question: what do we use as the last letter of 'character'? 'r' or 'e'?
181 `sorted()` will put a string in lexicographical order.
182 `.find()` will find an item in a sequence
186 # Keyword enciphering
188 Now we've got the keyword-based cipher alphabet, simply use `.translate()` to do the enciphering/deciphering.
190 Use `''.maketrans()` to make the translation table.
194 Does it pass the tests?
197 <script src=
"http://gnab.github.io/remark/downloads/remark-0.6.0.min.js" type=
"text/javascript">
200 <script type=
"text/javascript"
201 src=
"http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML&delayStartupUntil=configured"></script>
203 <script type=
"text/javascript">
204 var slideshow = remark.create({ ratio:
"16:9" });
209 skipTags: ['script', 'noscript', 'style', 'textarea', 'pre']
212 MathJax.Hub.Queue(function() {
213 $(MathJax.Hub.getAllJax()).map(function(index, elem) {
214 return(elem.SourceElement());
215 }).parent().addClass('has-jax');
217 MathJax.Hub.Configured();