Cover page images (keyboard)

Lab 3 - Strings

Sue Evans & Travis Mayberry

Hit the space bar for next slide


Today, we are going to explore string operations and how they can be applied to cryptography.

Objectives for today's lab:

Caesar Cipher

The Caesar cipher is a specific kind of simple substitution cipher where each letter in the input is shifted by a certain number of letters to obtain the output. This is called a 'rotation', like with old-fashioned decoder rings. To get a key, you can take an alphabet and line it up with a shifted one:

Rotate by three to the left (encrypt):
So the string 'COMPUTER' would be encrypted into 'FRPSXWHU'

Notice now how 'rotate' is actually different from 'shift' because the letters towards the end of the alphabet are wrapped around. Decryption is done the same way, but by rotating in the opposite direction:

Rotate by three to the right (decrypt):
And 'FRPSXWHU' would be decrypted into 'COMPUTER'


Program Outline

Your program is going to read in some plaintext from the user as a string, loop over each of the characters in the string and print out their encryption value. For simplicity, our program will convert all of the characters in the input to uppercase characters. Spaces should be ignored. You may assume that the input contains no characters other than letters and spaces.

The psuedocode will look like the following:

read input <string> from user
convert <string> to all uppercase
for each <char>acter in <string>
    if <char> is not a space
        convert <char> to its ASCII <value>
        rotate <value> by a given amount
        convert <value> back to a character, <char>
        print out <char>

Step 0: Setup

The first step is to create a lab3 folder in your cs201/labs directory and make a file to start programming.

From your home directory:

cd 201/labs
mkdir lab3
cd lab3
emacs &

Edit the to look like the following:

# File:
# Written by:  YOUR NAME HERE
# Date:        DATE HERE
# Section:     ?
# Email:       ? 
# Description: Lab 3, Cipher. Encoding/Decoding a string. 
#              Use this as example for our Homework in a few weeks!!

def main():

	#put code here


Step 1: Getting Started

Your program is going to read input from the user and encrypt/decrypt the results, so the first thing it needs to do is read input from the user into a variable. Remember that raw_input() is needed when dealing with strings. For reference, input works as follows:

>>> user_string = raw_input("Please input a string: ")
Please input a string: Hello
>>> user_string

Step 2: Convert to All Uppercase

To make things easier, before starting to convert to ASCII, we'll use the string.upper() function to convert your string to all uppercase letters. This will make the rotation easy because all of the letters will now have their ASCII values between 65 and 90.

Here's an example (that you should not copy directly into your code) of using the string.upper() function. You must import string before calling the function.

>>> original = 'This is the message'
>>> allCaps = original.upper()
>>> print allCaps
>>> print original
This is the message

Step 3: Looping Over Characters

In order to loop over each character in the string, you must use a for loop.
For loops are of the format for <loop variable> in <string variable>:

Your loop variable can be named anything you want, but make sure that the
<string variable> is the variable that you've read your input into.

Inside the for loop, you'll have to do a check to make sure the character is not a space. For this task, you'll use an if statement.

If your loop variable is called 'char' then it would look like this:

if char != ' ': # there is a space between the quotes on this line!!
    #Code here for doing something with a char that isn't a space

Step 4: Rotating Characters

The first step in rotating the characters is to convert them to ASCII using the ord() function. Once we have the ASCII value, how are we going to do the rotation?

You can refer to this ASCII chart as a reference.

Sample Output

travis-laptop-2% python         
Input your plaintext: hello
travis-laptop-2% python
Input your plaintext: uryyb

Bonus Step: Encryption/Decryption

If you are attempting the bonus step, make a copy of your file called Make the modifications as described below to your program in your file. Don't forget to change the name of the file and the description in the file header comment too.

Right now, your program only shifts 13 characters, which is conveniently its own inverse so it can both encrypt and decrypt. (13 encrypts, -13 would decrypt) However, it would be useful to have the user be able to input a key (the number of characters to shift) to encrypt (key), or the inverse of the key to decrypt (-key).

Hint: The modulus operator can be useful and negative numbers can be used with the modulus operator:

>>> -3 % 26

Sample Bonus Output

travis-laptop-2% python
Input your plaintext: hello
Input shift distance: 4
travis-laptop-2% python
Input your plaintext: lipps
Input shift distance: -4

Challenge Step: Variable Rotation

As before, if you are attempting this step, make a copy of named and make your modifications to this new file.

Now that we have created our simple substitution cipher, we can try to make it more secure. Right now, each letter is always encrypted to the same value. This is a disadvantage because someone could use that information to break our cipher through a frequency analysis (noting that certain letters occur more often than others).

One way of making it more secure is to vary the shift amount. If your shift amount is completely random, this is known as a one-time pad and is perfectly secure, because no information can be gained from just having the ciphertext.

It is difficult to make something completely random, but there are ways to approximate it. The way you'll use is called a linear congruential generator. It creates a series of almost-random numbers by taking the previous number, multiplying it by a constant, adding another constant and applying a modulus.

For your program, you will read in a starting number and for each character that you encrypt you will get it's shift by taking the previous number, multiplying it by 7, adding 11 and applying a modulus of 26.

Sample Challenge Output

travis-laptop-2% python
Input your plaintext: hello
Input 'E' for encrypt or 'D' for decrypt: e
Input random seed: 13
travis-laptop-2% python
Input your plaintext: fbbec
Input 'E' for encrypt or 'D' for decrypt: d
Input random seed: 13