Added transposition cipher slides
[cipher-training.git] / slides / keyword-encipher.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <title>Keyword ciphers</title>
5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
6 <style type="text/css">
7 /* Slideshow styles */
8 body {
9 font-size: 20px;
10 }
11 h1, h2, h3 {
12 font-weight: 400;
13 margin-bottom: 0;
14 }
15 h1 { font-size: 3em; }
16 h2 { font-size: 2em; }
17 h3 { font-size: 1.6em; }
18 a, a > code {
19 text-decoration: none;
20 }
21 code {
22 -moz-border-radius: 5px;
23 -web-border-radius: 5px;
24 background: #e7e8e2;
25 border-radius: 5px;
26 font-size: 16px;
27 }
28 .plaintext {
29 background: #272822;
30 color: #80ff80;
31 text-shadow: 0 0 20px #333;
32 padding: 2px 5px;
33 }
34 .ciphertext {
35 background: #272822;
36 color: #ff6666;
37 text-shadow: 0 0 20px #333;
38 padding: 2px 5px;
39 }
40 .float-right {
41 float: right;
42 }
43 </style>
44 </head>
45 <body>
46 <textarea id="source">
47
48 # Keyword ciphers
49
50 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
51 --|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|--
52 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
53
54 * Taking a more Pythonic approach
55
56 ---
57
58 # The cipher
59
60 * Still character-by-character substitution, still monosubstitution.
61
62 Ciphertext alphabet: start with a keyword, write out the rest of the alphabet, removing duplicates.
63
64 ## Three variants
65
66 Write out the rest of the alphabet...
67
68 1. ...starting from 'a' (keywordabcf...)
69 2. ...starting from the last letter of the keyword (keywordfgh...)
70 3. ...starting from the largest letter of the keyword (keywordzabc...)
71
72 ---
73
74 # A more Pythonic way
75
76 _string_`.translate()` and _string_`.maketrans()`
77
78 * Make the 'ciphertext' alphabet, relate to the 'plaintext' alphabet (`string.ascii_lowercase`)
79 * Use those to make the translation table
80 * Enciphering is simply applying `plaintext.translate(enciphering_table)`
81 * Deciphering just uses a different table
82
83 ---
84
85 # Making the cipher alphabet from a keyword
86
87 Three challenges:
88
89 1. How to say which type of cipher alphabet to use
90 2. Where to start the rest of the alphabet
91 3. Removing duplicate letters
92
93 Solutions:
94
95 1. Keyword arguments for procedures
96 2. sort and slices
97 3. Use something like an ordered set
98
99 Both enciphering and deciphering need the same keyword-based alphabet, so pull this out into another procedure.
100
101 ---
102
103 # Keyword arguments
104
105 Used to:
106
107 1. give a default value for a parameter
108 2. allow parameters to be named (not just positional)
109
110 Give our `keyword_encipher` and `keyword_decipher` procedures a keyword parameter of `wrap_alphabet`.
111
112 Pass this parameter to the `keyword_alphabet` procedure.
113
114 ## wrap_alphabet has no inherent meaning
115 Use Python 3.4's `Enum`
116 ```python
117 from enum import Enum
118
119 class Keyword_wrap_alphabet(Enum):
120 from_a = 1
121 from_last = 2
122 from_largest = 3
123 ```
124
125 (Use integers in earlier Pythons)
126 ---
127
128 # Deduplicating a sequence
129
130 We need
131
132 * Something set-like
133 * Something ordered
134
135 No ordered set in Python, but do have an ordered dict.
136
137 * Keys of a dict are a set.
138 * Keys in an ordered dict retain their order (subsequent instances are ignored)
139
140 `deduplicated_list = list(collections.OrderedDict.fromkeys(list))`
141
142 ---
143
144 # Sorts and slices
145
146 ## Recap
147 Write out the rest of the alphabet...
148
149 1. ...starting from 'a' (keywordabcf...)
150 2. ...starting from the last letter of the keyword (keywordfgh...)
151 3. ...starting from the largest letter of the keyword (keywordzabc...)
152
153 * Santitise the keyword before we use it
154
155 ---
156 # Making the keyword alphabet
157
158 ## Cases
159 1. As we're deduplicating anyway, just add the entire alphabet to the end of the keyword, then deduplicate.
160 `deduplicate(keyword + string.ascii_lowercase)`
161
162 2. and 3. How to find the appropriate letter of the keyword.
163
164 `deduplicate(keyword + string_ascii_lowercase[from:] + string.ascii_lowercase)`
165
166 Question: why not take a slice of the second alphabet copy?
167
168 Question: what do we use as the last letter of 'character'? 'r' or 'e'?
169
170 `sorted()` will put a string in lexicographical order.
171 `.find()` will find an item in a sequence
172
173 ---
174
175 # Keyword enciphering
176
177 Now we've got the keyword-based cipher alphabet, simply use `.translate()` to do the enciphering/deciphering.
178
179 Use `''.maketrans()` to make the translation table.
180
181 Sorted!
182
183 Does it pass the tests?
184
185 </textarea>
186 <script src="http://gnab.github.io/remark/downloads/remark-0.6.0.min.js" type="text/javascript">
187 </script>
188
189 <script type="text/javascript"
190 src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML&delayStartupUntil=configured"></script>
191
192 <script type="text/javascript">
193 var slideshow = remark.create({ ratio: "16:9" });
194
195 // Setup MathJax
196 MathJax.Hub.Config({
197 tex2jax: {
198 skipTags: ['script', 'noscript', 'style', 'textarea', 'pre']
199 }
200 });
201 MathJax.Hub.Queue(function() {
202 $(MathJax.Hub.getAllJax()).map(function(index, elem) {
203 return(elem.SourceElement());
204 }).parent().addClass('has-jax');
205 });
206 MathJax.Hub.Configured();
207 </script>
208 </body>
209 </html>