diff --git a/.ipynb_checkpoints/caesarCipher-checkpoint.ipynb b/.ipynb_checkpoints/caesarCipher-checkpoint.ipynb new file mode 100644 index 0000000..ca6ff8d --- /dev/null +++ b/.ipynb_checkpoints/caesarCipher-checkpoint.ipynb @@ -0,0 +1,280 @@ +{ + "cells": [ + { + "attachments": { + "image.png": { + "image/png": "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" + } + }, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Caesar Cipher\n", + "\n", + "In cryptography, a Caesar cipher, also known as Caesar's cipher, the shift cipher, Caesar's code or Caesar shift, is one of the simplest and most widely known encryption techniques. The method is named after Julius Caesar, who used it in his private correspondence\n", + "\n", + "It is a type of **substitution** cipher in which each letter in the plaintext is replaced by a letter some fixed number of positions down the alphabet. \n", + "\n", + "### For example:\n", + "with a **left** shift of 3, D would be replaced by A, E would become B, and so on.\n", + "\n", + "![image.png](attachment:image.png)\n", + "\n", + "The 3 is called the **key** and needs to be kept secret\n", + "The algorithm or cipher is the rules for encryption and can be publicly known\n", + "\n", + "Caesar cipher is a type of **symmetrical** encryption as the same key is used to encrypt and to decrypt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Exercise: Write a Caesar Cipher function\n", + "\n", + "Here is an algorithm to follow:\n", + "\n", + "- outside of the calling function\n", + " - Ask the user to enter the plaintext\n", + " - Ask the user to enter the key\n", + "\n", + "- BEGIN caesarCipher with the **plaintext** and **key**\n", + "- intialise a ciphertext string to the empty string\n", + "- change plaintext into all CAPS\n", + "- For every letter in the plaintext\n", + "- if the letter is alphabetic\n", + " - convert the letter into a number (alphabet number A=0, B=1... Z=25 or ASCII number A=65 B=66...Z=90 )\n", + " - add the shift value\n", + " - if the number is now beyond the alphabet (beyond 25 or 90 (ASCII)) then loop back to the beginning \n", + " - convert the number back into a character\n", + "- add the character to the cipherttext\n", + "- are there more letters in the plaintext? \n", + "- return the ciphertext to the calling program\n", + "- END\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Some useful code snippets" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n" + ] + } + ], + "source": [ + "#defining the alphabet\n", + "import string\n", + "alpha = string.ascii_uppercase\n", + "print(alpha)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "HELLO WORLD\n" + ] + } + ], + "source": [ + "# converting to uppercase\n", + "test = \"hello world\"\n", + "test = test.upper()\n", + "print(test)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "65,66,67,32,88,89,90," + ] + } + ], + "source": [ + "# changing a character into ascii values:\n", + "myString = \"abc xyz\".upper()\n", + "for i in range(len(myString)):\n", + " asciiNum = ord (myString[i])\n", + " print(asciiNum, end= \",\")" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "result without any special chars, only alpha: THISISAMESSAGEWITHLOTSOFSPECIALCHARS\n" + ] + } + ], + "source": [ + "#only interested in alphabetic characters\n", + "message = \"this is %$ a message with 123 lots of ^%: special chars\".upper()\n", + "newMessage = \"\"\n", + "for i in range(len(message)):\n", + " if message[i] in alpha: # use the in operator\n", + " newMessage += message[i]\n", + "\n", + "print(\"result without any special chars, only alpha: \", newMessage)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "result with only special chars, inclduing all the spaces: *!&££ @>= 1 and key <= MAX_KEY_SIZE):\n", + " return key\n", + " \n", + "def getTranslatedMessage(mode, message, key):\n", + " if mode[0] == 'd':\n", + " key = -key\n", + " translated = ''\n", + " \n", + " for symbol in message:\n", + " if symbol.isalpha():\n", + " num = ord(symbol)\n", + " num += key\n", + " \n", + " if symbol.isupper():\n", + " if num > ord('Z'):\n", + " num -= 26\n", + " elif num < ord('A'):\n", + " num += 26\n", + " elif symbol.islower():\n", + " if num > ord('z'):\n", + " num -= 26\n", + " elif num < ord('a'):\n", + " num += 26\n", + " \n", + " translated += chr(num)\n", + " else:\n", + " translated += symbol\n", + " return translated\n", + "\n", + "mode = getMode()\n", + "message = getMessage()\n", + "key = getKey()\n", + "\n", + "print('Your translated text is:')\n", + "print(getTranslatedMessage(mode, message, key))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/caesarCipher.ipynb b/caesarCipher.ipynb index 86737ad..ca6ff8d 100644 --- a/caesarCipher.ipynb +++ b/caesarCipher.ipynb @@ -178,125 +178,81 @@ }, { "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "#function that will create ciphertext from plaintext and a key\n", - "def caesarCipher(plaintext, key):\n", - " ciphertext = \"\"\n", - " \n", - " #implement caesar cipher here\n", - " \n", - " \n", - " return ciphertext\n", - "\n", - " " - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "your encrypted message = \n" - ] - } - ], - "source": [ - "#test your caeserCipher function here\n", - "secret = caesarCipher(\"this is a secret\", 9) # this should return : CQRB RB J BNLANC\n", - "print(\"your encrypted message = \", secret)" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "your encrypted message = \n" - ] - } - ], - "source": [ - "secret = caesarCipher(\"this is a secret\", 22) # should return PDEO EO W OAYNAP\n", - "print(\"your encrypted message = \", secret)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, + "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "please enter your message to encodehello world\n", - "please enter the key - between 1 and 25100\n", - "that was not a valid key range, please try again\n", - "please enter the key - between 1 and 25r\n", - "you did not enter a number, the key must be a number, try again\n", - "please enter the key - between 1 and 2512\n", - "that was not a valid key range, please try again\n", - "please enter the key - between 1 and 2512\n", - "that was not a valid key range, please try again\n", - "please enter the key - between 1 and 25\n", - "you did not enter a number, the key must be a number, try again\n", - "please enter the key - between 1 and 25\n", - "you did not enter a number, the key must be a number, try again\n" - ] - }, - { - "ename": "KeyboardInterrupt", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/usr/local/lib/python3.5/dist-packages/ipykernel/kernelbase.py\u001b[0m in \u001b[0;36m_input_request\u001b[0;34m(self, prompt, ident, parent, password)\u001b[0m\n\u001b[1;32m 729\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 730\u001b[0;31m \u001b[0mident\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mreply\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msession\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrecv\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstdin_socket\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 731\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mException\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m/usr/local/lib/python3.5/dist-packages/jupyter_client/session.py\u001b[0m in \u001b[0;36mrecv\u001b[0;34m(self, socket, mode, content, copy)\u001b[0m\n\u001b[1;32m 795\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 796\u001b[0;31m \u001b[0mmsg_list\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msocket\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrecv_multipart\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmode\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcopy\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mcopy\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 797\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mzmq\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mZMQError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m/usr/local/lib/python3.5/dist-packages/zmq/sugar/socket.py\u001b[0m in \u001b[0;36mrecv_multipart\u001b[0;34m(self, flags, copy, track)\u001b[0m\n\u001b[1;32m 394\u001b[0m \"\"\"\n\u001b[0;32m--> 395\u001b[0;31m \u001b[0mparts\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrecv\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mflags\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcopy\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mcopy\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtrack\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtrack\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 396\u001b[0m \u001b[0;31m# have first part already, only loop while more to receive\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32mzmq/backend/cython/socket.pyx\u001b[0m in \u001b[0;36mzmq.backend.cython.socket.Socket.recv (zmq/backend/cython/socket.c:7683)\u001b[0;34m()\u001b[0m\n", - "\u001b[0;32mzmq/backend/cython/socket.pyx\u001b[0m in \u001b[0;36mzmq.backend.cython.socket.Socket.recv (zmq/backend/cython/socket.c:7460)\u001b[0;34m()\u001b[0m\n", - "\u001b[0;32mzmq/backend/cython/socket.pyx\u001b[0m in \u001b[0;36mzmq.backend.cython.socket._recv_copy (zmq/backend/cython/socket.c:2344)\u001b[0;34m()\u001b[0m\n", - "\u001b[0;32m/usr/local/lib/python3.5/dist-packages/zmq/backend/cython/checkrc.pxd\u001b[0m in \u001b[0;36mzmq.backend.cython.checkrc._check_rc (zmq/backend/cython/socket.c:9621)\u001b[0;34m()\u001b[0m\n", - "\u001b[0;31mKeyboardInterrupt\u001b[0m: ", - "\nDuring handling of the above exception, another exception occurred:\n", - "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mvalid\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 7\u001b[0;31m \u001b[0mkey\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minput\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"please enter the key - between 1 and 25\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 8\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mkey\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32min\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m25\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"that was not a valid key range, please try again\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m/usr/local/lib/python3.5/dist-packages/ipykernel/kernelbase.py\u001b[0m in \u001b[0;36mraw_input\u001b[0;34m(self, prompt)\u001b[0m\n\u001b[1;32m 703\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_parent_ident\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 704\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_parent_header\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 705\u001b[0;31m \u001b[0mpassword\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 706\u001b[0m )\n\u001b[1;32m 707\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m/usr/local/lib/python3.5/dist-packages/ipykernel/kernelbase.py\u001b[0m in \u001b[0;36m_input_request\u001b[0;34m(self, prompt, ident, parent, password)\u001b[0m\n\u001b[1;32m 733\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mKeyboardInterrupt\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 734\u001b[0m \u001b[0;31m# re-raise KeyboardInterrupt, to truncate traceback\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 735\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mKeyboardInterrupt\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 736\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 737\u001b[0m \u001b[0;32mbreak\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + "Do you wish to encrypt or decrypt a message?\n", + "e\n", + "Enter your message:\n", + "hello world\n", + "Enter the key number (1-26)\n", + "3\n", + "Your translated text is:\n", + "khoor zruog\n" ] } ], "source": [ - "# now test the function with user input (think about your test cases!!)\n", - "plaintext = input(\"please enter your message to encode\")\n", - "valid = False # assume the user does not enter a validkey - validate!!\n", - "#validate that the key is 1) a number and 2) within the valid range 1-25\n", - "while not valid:\n", - " try:\n", - " key = int(input(\"please enter the key - between 1 and 25\"))\n", - " if key not in range(1,25]:\n", - " print(\"that was not a valid key range, please try again\")\n", - " else:\n", - " valid=True\n", - " except ValueError:\n", - " print(\"you did not enter a number, the key must be a number, try again\")\n", + "#Ceaser Cipher Code\n", + "MAX_KEY_SIZE = 26\n", + "\n", + "def getMode():\n", + " while True:\n", + " print('Do you wish to encrypt or decrypt a message?')\n", + " mode = input().lower()\n", + " if mode in 'encrypt e decrypt d'.split():\n", + " return mode\n", + " else:\n", + " print('Enter either \"encrypt\" or \"e\" or \"decrypt\" or \"d\"')\n", + "\n", + "def getMessage():\n", + " print('Enter your message:')\n", + " return input()\n", + " \n", + "def getKey():\n", + " key = 0\n", + " while True:\n", + " print('Enter the key number (1-%s)' %(MAX_KEY_SIZE))\n", + " key = int(input())\n", + " if (key >= 1 and key <= MAX_KEY_SIZE):\n", + " return key\n", + " \n", + "def getTranslatedMessage(mode, message, key):\n", + " if mode[0] == 'd':\n", + " key = -key\n", + " translated = ''\n", + " \n", + " for symbol in message:\n", + " if symbol.isalpha():\n", + " num = ord(symbol)\n", + " num += key\n", + " \n", + " if symbol.isupper():\n", + " if num > ord('Z'):\n", + " num -= 26\n", + " elif num < ord('A'):\n", + " num += 26\n", + " elif symbol.islower():\n", + " if num > ord('z'):\n", + " num -= 26\n", + " elif num < ord('a'):\n", + " num += 26\n", + " \n", + " translated += chr(num)\n", + " else:\n", + " translated += symbol\n", + " return translated\n", + "\n", + "mode = getMode()\n", + "message = getMessage()\n", + "key = getKey()\n", "\n", - "ciphertext = caesarCipher(plaintext, key)\n", - "print(\"your encoded message is:\", ciphertext)\n", - " " + "print('Your translated text is:')\n", + "print(getTranslatedMessage(mode, message, key))" ] } ],