< Back

Lab 22: Encryption

As usual, create a directory to hold today's files. All programs that you write today should be stored in this directory.

$ cd ~/cs120/labs
$ mkdir lab22 
$ cd lab22 


Vigenere Cipher

Cryptography is the science of hiding secrets. A typical cryptographic protocol takes some plaintext message P and some key k, and produces a ciphertext C that is unreadable by any entity that does not know the key k

We observed a very simplistic encryption scheme in the last class: Caesar cipher. This encryption scheme has been in use since Roman times, and is very easily breakable. As such, we likely want a stronger encryption scheme to make our messages even more secure.

The key in caesar is \(3\). To encrypt, you chose the letter \(3\) spaces further in the alphabet of the entered character. In Vigenere, the key is a word. For each character in the plaintext, you use the corresponding letter in the key to determine how much to shift that character by.

Consider the plaintext "hello", with a key of "hi". This means to encrypt the "h" in hello, you use the letter "h" as the shift (Which is a shift of \(7\), since h is the 7th character of the alphabet). Then, for the letter "e" in hello, you would use the letter "i" as the shift (which is a shift of \(8\)). But, now we have run out of letters in the key. In this case, you wrap back around to the beginning of the key string, using "h" as the key for the first "l" in hello.

Details

In a file called vigenere.py, write a function called encode_vigenere(plaintext, key). This function takes two strings as a parameter, and returns a string which is the encryption of plaintext using key.

Make sure you test your program well. How many test cases do you need? Include your test cases in your program file.

Sample Test Cases

Function Parameters Expected Output
"hello", "hi" omstv
"goodbye", "hello" nszopfi

Hint

  • The ord function gives you the ASCII representation of a character. If you subtract the ord('a') from this, you will get the position in alphabet a character is.

  • The actual encryption of this will be very similar to the caesar cipher, with a change to the shift that occurs.

  • The chr function takes an integer, and returns to you the character that represents the ASCII value.

  • In order to account for the wrapping around of the key, use the % operator. You will likely want to mod by the length of your key.

Challenge

The vigenere cipher is possibly the strongest classical cipher you will encounter. Which means that writing a decryption function is of the utmost importance. Write a function called decode_vigenere(ciphertext, key), which decrypts the ciphertext with the associated key.


Substitution Cipher

Another common technique for encryption is known as the Substitution Cipher. Instead of defining a linear equation between the plaintext and ciphertext, you can define a map that translates characters using a specified order. Crypograms use this technique, for example.

The key in the substitution cipher is a string of characters in the range [a, z]. For example, the string "abcdefghijklmnopqrstuvwxyz" is one possible key in the substitution cipher. It maps the letter 'a' to the letter 'a', the letter 'b' to 'b', and so on. A more interesting example would be "zyxwvutsrqponmlkjihgfedcba", which maps 'a' to 'z', 'b' to 'y', and so on. For example, "hello world" would become "svool dliow" under this key. Notice that characters that are not alphabetic are not encoded, and their normal value is included.

Details

In a file called substitution.py, define a function called encode_substitution(plaintext, key). This function takes two parameters: the plaintext as a string of lowercase characters, and a key as a string of lowercase characters. Your function will return a string of lowercase characters, which is the plaintext with each character substituted with its corresponding letter.

Sample Test Cases

Function Parameters Expected Output
"hello", "zyxwvutsrqponmlkjihgfedcba" svool
"goodbye", "acegikmoqsuwybdfhjlnprtvxz" mddgcxi

Hint

  • Given a character, you can compute its position in the alphabet by subtracting the ord('a') from the ordinal value of that character.

Challenge

Write a function decode_substitution(ciphertext, key), which returns the decryption of the specified ciphertext with the associated key.