Tidied up keyword ciphers and writeups
authorNeil Smith <neil.git@njae.me.uk>
Wed, 4 Jun 2014 19:12:10 +0000 (20:12 +0100)
committerNeil Smith <neil.git@njae.me.uk>
Wed, 4 Jun 2014 19:12:10 +0000 (20:12 +0100)
cipher.py
cipherbreak.py
slides/keyword-break.html
slides/keyword-encipher.html

index ba62d411a902e40f6bc1b259d2733111f891407d..e39abce8adf96fa495b631370057ba1470bc6525 100644 (file)
--- a/cipher.py
+++ b/cipher.py
@@ -242,9 +242,9 @@ def affine_decipher(message, multiplier=1, adder=0, one_based=True):
 
 
 class Keyword_wrap_alphabet(Enum):
 
 
 class Keyword_wrap_alphabet(Enum):
-    from_a = 0
-    from_last = 1
-    from_largest = 2
+    from_a = 1
+    from_last = 2
+    from_largest = 3
 
 
 def keyword_cipher_alphabet_of(keyword, wrap_alphabet=Keyword_wrap_alphabet.from_a):
 
 
 def keyword_cipher_alphabet_of(keyword, wrap_alphabet=Keyword_wrap_alphabet.from_a):
index 0d3fd7828d5d3fbd69f86453298975dd176a33e1..2a70ceebbadb3ae3303545219420f4866ae6dd83 100644 (file)
@@ -133,7 +133,7 @@ def keyword_break(message, wordlist=keywords, fitness=Pletters):
     >>> keyword_break(keyword_encipher('this is a test message for the ' \
           'keyword decipherment', 'elephant', Keyword_wrap_alphabet.from_last), \
           wordlist=['cat', 'elephant', 'kangaroo']) # doctest: +ELLIPSIS
     >>> keyword_break(keyword_encipher('this is a test message for the ' \
           'keyword decipherment', 'elephant', Keyword_wrap_alphabet.from_last), \
           wordlist=['cat', 'elephant', 'kangaroo']) # doctest: +ELLIPSIS
-    (('elephant', <Keyword_wrap_alphabet.from_last: 1>), -52.834575011...)
+    (('elephant', <Keyword_wrap_alphabet.from_last: 2>), -52.834575011...)
     """
     best_keyword = ''
     best_wrap_alphabet = True
     """
     best_keyword = ''
     best_wrap_alphabet = True
@@ -164,7 +164,7 @@ def keyword_break_mp(message, wordlist=keywords, fitness=Pletters, chunksize=500
     >>> keyword_break_mp(keyword_encipher('this is a test message for the ' \
           'keyword decipherment', 'elephant', Keyword_wrap_alphabet.from_last), \
           wordlist=['cat', 'elephant', 'kangaroo']) # doctest: +ELLIPSIS
     >>> keyword_break_mp(keyword_encipher('this is a test message for the ' \
           'keyword decipherment', 'elephant', Keyword_wrap_alphabet.from_last), \
           wordlist=['cat', 'elephant', 'kangaroo']) # doctest: +ELLIPSIS
-    (('elephant', <Keyword_wrap_alphabet.from_last: 1>), -52.834575011...)
+    (('elephant', <Keyword_wrap_alphabet.from_last: 2>), -52.834575011...)
     """
     with Pool() as pool:
         helper_args = [(message, word, wrap, fitness) 
     """
     with Pool() as pool:
         helper_args = [(message, word, wrap, fitness) 
index 46dded537677c2b3b1c032524452af24bdbbc9c7..4a2772c03ddfad8a2ece4bfee7b8f5b086c4be47 100644 (file)
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html>
   <head>
 <!DOCTYPE html>
 <html>
   <head>
-    <title>Affine ciphers</title>
+    <title>Breaking keyword ciphers</title>
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
     <style type="text/css">
       /* Slideshow styles */
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
     <style type="text/css">
       /* Slideshow styles */
@@ -77,6 +77,7 @@ Thread-safe shared-memory code is hard.
 Python's Global Interpreter Lock prevents shooting yourself in the foot.
 
 Where you want true parallelism, need different threads (Python processes).
 Python's Global Interpreter Lock prevents shooting yourself in the foot.
 
 Where you want true parallelism, need different threads (Python processes).
+
 * Thread-safe shared-memory code is hard.
 
 The `multiprocessing` library makes this easier.
 * Thread-safe shared-memory code is hard.
 
 The `multiprocessing` library makes this easier.
@@ -126,7 +127,7 @@ How do you write a function that takes this many arguments?
 ## Positional, keyword
 
 * Common or garden parameters, as you're used to.
 ## Positional, keyword
 
 * Common or garden parameters, as you're used to.
-* `def keyword_encipher(message, keyword, wrap_alphabet=0):`
+* `def keyword_encipher(message, keyword, Keyword_wrap_alphabet.from_a):`
 
 ## Excess positional
 * `def mean(x, *xs):`
 
 ## Excess positional
 * `def mean(x, *xs):`
index 7258e9c88e6ae818f0f076ec7b2675d8a7a25125..bb9e679775b9163bd9b19f9e636d3ee6fc1d3262 100644 (file)
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html>
   <head>
 <!DOCTYPE html>
 <html>
   <head>
-    <title>Affine ciphers</title>
+    <title>Keyword ciphers</title>
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
     <style type="text/css">
       /* Slideshow styles */
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
     <style type="text/css">
       /* Slideshow styles */
@@ -103,6 +103,7 @@ Both enciphering and deciphering need the same keyword-based alphabet, so pull t
 # Keyword arguments
 
 Used to:
 # Keyword arguments
 
 Used to:
+
 1. give a default value for a parameter
 2. allow parameters to be named (not just positional)
 
 1. give a default value for a parameter
 2. allow parameters to be named (not just positional)
 
@@ -110,8 +111,18 @@ Give our `keyword_encipher` and `keyword_decipher` procedures a keyword paramete
 
 Pass this parameter to the `keyword_alphabet` procedure.
 
 
 Pass this parameter to the `keyword_alphabet` procedure.
 
-## Note: `Enum` introduced in Python 3.4. This is a better solution. 
+## 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
 ---
 
 # Deduplicating a sequence
@@ -141,6 +152,9 @@ Write out the rest of the alphabet...
 
 * Santitise the keyword before we use it
 
 
 * 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)`
 ## 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)`
@@ -148,6 +162,7 @@ Write out the rest of the alphabet...
 2. and 3. How to find the appropriate letter of the keyword.
 
 Indexing pulls out letters. `'keyword'[0]` = 'k' ; `'keyword'[3]` = 'w' ; `'keyword'[-1]` = 'd'
 2. and 3. How to find the appropriate letter of the keyword.
 
 Indexing pulls out letters. `'keyword'[0]` = 'k' ; `'keyword'[3]` = 'w' ; `'keyword'[-1]` = 'd'
+
 Slices pulls out substrings. `'keyword'[1:4]` = 'eyw' ; `'keyword'[:3]` = 'key' ; `'keyword'[5:]` = 'rd'
 
 `deduplicate(keyword + string_ascii_lowercase[from:] + string.ascii_lowercase)`
 Slices pulls out substrings. `'keyword'[1:4]` = 'eyw' ; `'keyword'[:3]` = 'key' ; `'keyword'[5:]` = 'rd'
 
 `deduplicate(keyword + string_ascii_lowercase[from:] + string.ascii_lowercase)`