Merged slides from presentation-slides branch
[cipher-training.git] / slides / keyword-encipher.html
diff --git a/slides/keyword-encipher.html b/slides/keyword-encipher.html
new file mode 100644 (file)
index 0000000..168bb5f
--- /dev/null
@@ -0,0 +1,209 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Keyword ciphers</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+    <style type="text/css">
+      /* Slideshow styles */
+      body {
+        font-size: 20px;
+      }
+      h1, h2, h3 {
+        font-weight: 400;
+        margin-bottom: 0;
+      }
+      h1 { font-size: 3em; }
+      h2 { font-size: 2em; }
+      h3 { font-size: 1.6em; }
+      a, a > code {
+        text-decoration: none;
+      }
+      code {
+        -moz-border-radius: 5px;
+        -web-border-radius: 5px;
+        background: #e7e8e2;
+        border-radius: 5px;
+        font-size: 16px;
+      }
+      .plaintext {
+        background: #272822;
+        color: #80ff80;
+        text-shadow: 0 0 20px #333;
+        padding: 2px 5px;
+      }
+      .ciphertext {
+        background: #272822;
+        color: #ff6666;
+        text-shadow: 0 0 20px #333;
+        padding: 2px 5px;
+      }
+       .float-right {
+        float: right;
+      }
+    </style>
+  </head>
+  <body>
+    <textarea id="source">
+
+# Keyword ciphers
+
+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
+--|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|--
+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
+
+* Taking a more Pythonic approach
+
+---
+
+# The cipher
+
+* Still character-by-character substitution, still monosubstitution.
+
+Ciphertext alphabet: start with a keyword, write out the rest of the alphabet, removing duplicates.
+
+## Three variants
+
+Write out the rest of the alphabet...
+
+1. ...starting from 'a' (keywordabcf...)
+2. ...starting from the last letter of the keyword (keywordfgh...)
+3. ...starting from the largest letter of the keyword (keywordzabc...)
+
+---
+
+# A more Pythonic way
+
+_string_`.translate()` and _string_`.maketrans()`
+
+* Make the 'ciphertext' alphabet, relate to the 'plaintext' alphabet (`string.ascii_lowercase`)
+* Use those to make the translation table
+* Enciphering is simply applying `plaintext.translate(enciphering_table)`
+* Deciphering just uses a different table
+
+---
+
+# Making the cipher alphabet from a keyword
+
+Three challenges:
+
+1. How to say which type of cipher alphabet to use
+2. Where to start the rest of the alphabet
+3. Removing duplicate letters
+
+Solutions:
+
+1. Keyword arguments for procedures
+2. sort and slices
+3. Use something like an ordered set
+
+Both enciphering and deciphering need the same keyword-based alphabet, so pull this out into another procedure.
+
+---
+
+# Keyword arguments
+
+Used to:
+
+1. give a default value for a parameter
+2. allow parameters to be named (not just positional)
+
+Give our `keyword_encipher` and `keyword_decipher` procedures a keyword parameter of `wrap_alphabet`.
+
+Pass this parameter to the `keyword_alphabet` procedure.
+
+## wrap_alphabet has no inherent meaning
+Use Python 3.4's `Enum`
+```python
+from enum import Enum
+
+class Keyword_wrap_alphabet(Enum):
+    from_a = 1
+    from_last = 2
+    from_largest = 3
+```
+
+(Use integers in earlier Pythons)
+---
+
+# Deduplicating a sequence
+
+We need
+
+* Something set-like
+* Something ordered
+
+No ordered set in Python, but do have an ordered dict.
+
+* Keys of a dict are a set. 
+* Keys in an ordered dict retain their order (subsequent instances are ignored)
+
+`deduplicated_list = list(collections.OrderedDict.fromkeys(list))`
+
+---
+
+# Sorts and slices
+
+## Recap 
+Write out the rest of the alphabet...
+
+1. ...starting from 'a' (keywordabcf...)
+2. ...starting from the last letter of the keyword (keywordfgh...)
+3. ...starting from the largest letter of the keyword (keywordzabc...)
+
+* Santitise the keyword before we use it
+
+---
+# Making the keyword alphabet
+
+## Cases
+1. As we're deduplicating anyway, just add the entire alphabet to the end of the keyword, then deduplicate. 
+`deduplicate(keyword + string.ascii_lowercase)`
+
+2. and 3. How to find the appropriate letter of the keyword.
+
+`deduplicate(keyword + string_ascii_lowercase[from:] + string.ascii_lowercase)`
+
+Question: why not take a slice of the second alphabet copy?
+
+Question: what do we use as the last letter of 'character'? 'r' or 'e'?
+
+`sorted()` will put a string in lexicographical order.
+`.find()` will find an item in a sequence
+
+---
+
+# Keyword enciphering
+
+Now we've got the keyword-based cipher alphabet, simply use `.translate()` to do the enciphering/deciphering.
+
+Use `''.maketrans()` to make the translation table.
+
+Sorted!
+
+Does it pass the tests?
+
+    </textarea>
+    <script src="http://gnab.github.io/remark/downloads/remark-0.6.0.min.js" type="text/javascript">
+    </script>
+
+    <script type="text/javascript"
+      src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML&delayStartupUntil=configured"></script>
+
+    <script type="text/javascript">
+      var slideshow = remark.create({ ratio: "16:9" });
+
+      // Setup MathJax
+      MathJax.Hub.Config({
+        tex2jax: {
+        skipTags: ['script', 'noscript', 'style', 'textarea', 'pre']
+        }
+      });
+      MathJax.Hub.Queue(function() {
+        $(MathJax.Hub.getAllJax()).map(function(index, elem) {
+            return(elem.SourceElement());
+        }).parent().addClass('has-jax');
+      });
+      MathJax.Hub.Configured();
+    </script>
+  </body>
+</html>