Added renamed previous cipher to autokey stream cipher; added non-autokeyed version
[computing-unplugged-book.git] / stream-cipher.ipynb
index 213eb834ee1cdf3d4207f0ef4036acb05bc990c3..21e9316c16fcdc90b7941224855693deb5e1efe8 100644 (file)
@@ -8,12 +8,13 @@
    },
    "outputs": [],
    "source": [
-    "import string"
+    "import string\n",
+    "import itertools"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 40,
+   "execution_count": 6,
    "metadata": {
     "collapsed": true
    },
@@ -25,7 +26,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 41,
+   "execution_count": 7,
    "metadata": {
     "collapsed": false
    },
@@ -36,7 +37,7 @@
        "'thequickbrownfoxjumpedoverthelzydoga'"
       ]
      },
-     "execution_count": 41,
+     "execution_count": 7,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 2,
+   "execution_count": 12,
    "metadata": {
     "collapsed": false
    },
    "outputs": [],
    "source": [
-    "def encipher_letter(previous, current):\n",
-    "    new = (ord(previous) + ord(current) - 2 * ord('a')) % 26\n",
+    "def encipher_letter(key, current):\n",
+    "    new = (ord(key) + ord(current) - 2 * ord('a')) % 26\n",
     "    return chr(new + ord('a'))"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 15,
+   "execution_count": 9,
    "metadata": {
     "collapsed": true
    },
    "outputs": [],
    "source": [
-    "def decipher_letter(previous, current):\n",
-    "    new = (ord(current) - ord(previous) - 2 * ord('a')) % 26\n",
+    "def decipher_letter(key, current):\n",
+    "    new = (ord(current) - ord(key)) % 26\n",
     "    return chr(new + ord('a'))"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 4,
+   "execution_count": 13,
    "metadata": {
     "collapsed": false
    },
@@ -84,7 +85,7 @@
        "'a'"
       ]
      },
-     "execution_count": 4,
+     "execution_count": 13,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -95,7 +96,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 6,
+   "execution_count": 14,
    "metadata": {
     "collapsed": false
    },
        "'abcdefghijklmnopqrstuvwxyz'"
       ]
      },
-     "execution_count": 6,
+     "execution_count": 14,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 7,
+   "execution_count": 15,
    "metadata": {
     "collapsed": false
    },
        "'bcdefghijklmnopqrstuvwxyza'"
       ]
      },
-     "execution_count": 7,
+     "execution_count": 15,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 17,
+   "execution_count": 16,
    "metadata": {
     "collapsed": false
    },
        "'abcdefghijklmnopqrstuvwxyz'"
       ]
      },
-     "execution_count": 17,
+     "execution_count": 16,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 18,
+   "execution_count": 17,
    "metadata": {
     "collapsed": false
    },
     {
      "data": {
       "text/plain": [
-       "'b'"
+       "'zabcdefghijklmnopqrstuvwxy'"
       ]
      },
-     "execution_count": 18,
+     "execution_count": 17,
      "metadata": {},
      "output_type": "execute_result"
     }
    ],
    "source": [
-    "decipher_letter('a', 'b')"
+    "''.join(decipher_letter('b', l) for l in string.ascii_lowercase)"
    ]
   },
   {
-   "cell_type": "markdown",
-   "metadata": {},
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'b'"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
    "source": [
-    "e = (p + c) % 26\n",
-    "c = e - p"
+    "decipher_letter('a', 'b')"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 20,
+   "execution_count": 19,
    "metadata": {
     "collapsed": false
    },
        "'abcdefghijklmnopqrstuvwxyzbcdefghijklmnopqrstuvwxyzacdefghijklmnopqrstuvwxyzabdefghijklmnopqrstuvwxyzabcefghijklmnopqrstuvwxyzabcdfghijklmnopqrstuvwxyzabcdeghijklmnopqrstuvwxyzabcdefhijklmnopqrstuvwxyzabcdefgijklmnopqrstuvwxyzabcdefghjklmnopqrstuvwxyzabcdefghiklmnopqrstuvwxyzabcdefghijlmnopqrstuvwxyzabcdefghijkmnopqrstuvwxyzabcdefghijklnopqrstuvwxyzabcdefghijklmopqrstuvwxyzabcdefghijklmnpqrstuvwxyzabcdefghijklmnoqrstuvwxyzabcdefghijklmnoprstuvwxyzabcdefghijklmnopqstuvwxyzabcdefghijklmnopqrtuvwxyzabcdefghijklmnopqrsuvwxyzabcdefghijklmnopqrstvwxyzabcdefghijklmnopqrstuwxyzabcdefghijklmnopqrstuvxyzabcdefghijklmnopqrstuvwyzabcdefghijklmnopqrstuvwxzabcdefghijklmnopqrstuvwxy'"
       ]
      },
-     "execution_count": 20,
+     "execution_count": 19,
      "metadata": {},
      "output_type": "execute_result"
     }
    ],
    "source": [
-    "''.join(encipher_letter(k, l) for l in string.ascii_lowercase for k in string.ascii_lowercase)"
+    "''.join(encipher_letter(k, l) \n",
+    "        for l in string.ascii_lowercase \n",
+    "        for k in string.ascii_lowercase)"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 21,
+   "execution_count": 20,
    "metadata": {
     "collapsed": false
    },
        " ('j', 'a', 'j')]"
       ]
      },
-     "execution_count": 21,
+     "execution_count": 20,
      "metadata": {},
      "output_type": "execute_result"
     }
    ],
    "source": [
-    "encrypted = [(k, l, encipher_letter(k, l)) for l in string.ascii_lowercase for k in string.ascii_lowercase]\n",
+    "encrypted = [(k, l, encipher_letter(k, l)) \n",
+    "             for l in string.ascii_lowercase \n",
+    "             for k in string.ascii_lowercase]\n",
     "encrypted[:10]"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 22,
+   "execution_count": 21,
    "metadata": {
     "collapsed": false
    },
        "True"
       ]
      },
-     "execution_count": 22,
+     "execution_count": 21,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 55,
+   "execution_count": 32,
    "metadata": {
     "collapsed": true
    },
    "outputs": [],
    "source": [
-    "def encipher_message(plaintext, key='a'):\n",
+    "def encipher_message(plaintext, keystring='key'):\n",
+    "    key = itertools.cycle(keystring)\n",
     "    ciphertext = ''\n",
-    "    previous = key\n",
-    "    for letter in plaintext:\n",
-    "        cipherletter = encipher_letter(previous, letter)\n",
+    "    previous = keystring[0]\n",
+    "    for letter, keychar in zip(plaintext, key):\n",
+    "        cipherletter = encipher_letter(keychar, letter)\n",
     "        ciphertext += cipherletter\n",
     "        previous = cipherletter\n",
     "        # previous = letter\n",
   },
   {
    "cell_type": "code",
-   "execution_count": 56,
+   "execution_count": 23,
    "metadata": {
     "collapsed": false
    },
     {
      "data": {
       "text/plain": [
-       "'hlwhv'"
+       "'hecoj'"
       ]
      },
-     "execution_count": 56,
+     "execution_count": 23,
      "metadata": {},
      "output_type": "execute_result"
     }
    ],
    "source": [
-    "encipher_message('hello')"
+    "encipher_message('hello', 'aardvark')"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 57,
+   "execution_count": 24,
    "metadata": {
     "collapsed": false
    },
     {
      "data": {
       "text/plain": [
-       "'xbmxl'"
+       "'xubbe'"
       ]
      },
-     "execution_count": 57,
+     "execution_count": 24,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 54,
+   "execution_count": 33,
    "metadata": {
     "collapsed": true
    },
    "outputs": [],
    "source": [
-    "def decipher_message(ciphertext, key='a'):\n",
+    "def decipher_message(ciphertext, keystring='key'):\n",
+    "    key = itertools.cycle(keystring)\n",
     "    plaintext = ''\n",
-    "    previous = key\n",
-    "    for letter in ciphertext:\n",
-    "        plainletter = decipher_letter(previous, letter)\n",
+    "    previous = keystring[0]\n",
+    "    for letter, keychar in zip(ciphertext, key):\n",
+    "        plainletter = decipher_letter(keychar, letter)\n",
     "        plaintext += plainletter\n",
     "        previous = letter\n",
     "        # previous = plainletter\n",
   },
   {
    "cell_type": "code",
-   "execution_count": 58,
+   "execution_count": 27,
    "metadata": {
     "collapsed": false
    },
        "'hello'"
       ]
      },
-     "execution_count": 58,
+     "execution_count": 27,
      "metadata": {},
      "output_type": "execute_result"
     }
    ],
    "source": [
-    "decipher_message('hlwhv')"
+    "decipher_message('hecoj', 'aardvark')"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 59,
+   "execution_count": 28,
    "metadata": {
     "collapsed": false
    },
     {
      "data": {
       "text/plain": [
-       "'xello'"
+       "'hello'"
       ]
      },
-     "execution_count": 59,
+     "execution_count": 28,
      "metadata": {},
      "output_type": "execute_result"
     }
    ],
    "source": [
-    "decipher_message('xbmxl')"
+    "decipher_message('xubbe', 'q')"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 60,
+   "execution_count": 31,
    "metadata": {
     "collapsed": false
    },
     {
      "data": {
       "text/plain": [
-       "'hello'"
+       "'romyt'"
       ]
      },
-     "execution_count": 60,
+     "execution_count": 31,
      "metadata": {},
      "output_type": "execute_result"
     }
    ],
    "source": [
-    "decipher_message('xbmxl', 'q')"
+    "decipher_message('hecoj', 'q')"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 61,
+   "execution_count": 34,
    "metadata": {
     "collapsed": false
    },
     {
      "data": {
       "text/plain": [
-       "'hlwhvjxlznbpdrfthvjxlznbpd'"
+       "'rijvsmysmysmysmysmysmysmys'"
       ]
      },
-     "execution_count": 61,
+     "execution_count": 34,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 62,
+   "execution_count": 35,
    "metadata": {
     "collapsed": false
    },
        "'helloooooooooooooooooooooo'"
       ]
      },
-     "execution_count": 62,
+     "execution_count": 35,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "decipher_message('rijvsmysmysmysmysmysmysmys')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 36,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'qhiurlxrlxrlxrlxrlxrlxrlxr'"
+      ]
+     },
+     "execution_count": 36,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "decipher_message('rijvsmysmysmysmysmysmysmys', 'b')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 37,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'dlghpjalicxktzjayi'"
+      ]
+     },
+     "execution_count": 37,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "encipher_message(sanitised('This is a test message'), 'keyphrase')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 38,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'thisisatestmessage'"
+      ]
+     },
+     "execution_count": 38,
      "metadata": {},
      "output_type": "execute_result"
     }
    ],
    "source": [
-    "decipher_message('hlwhvjxlznbpdrfthvjxlznbpd')"
+    "decipher_message('dlghpjalicxktzjayi', 'keyphrase')"
    ]
   },
   {