Shared171 / Crypto / shift_cipher.ipynbOpen in CoCalc
Some exercises in basic cryptography

The Caesar Cipher

An ancient form of cryptography is to encrypt a message by "rotating" the alphabet forward by three places.

For example to encrypt a message M = ATTACKATDAWN, each letter will be replaced by the letter that comes three places later.

That is, AD,BE,CF,...,WA,XB,ZCA \to D, B \to E, C \to F,...,W \to A, X \to B, Z \to C.

In the cells below, use Python to encrypt M using the Caesar cipher.

In order to help, I have created a dictionary that might be useful.

# We can make a codebook for our Caesar cipher using a dictionary
codebook = {'A':'D','B':'E','C':'F','D':'G','E':'H','F':'I','G':'J','H':'K','I':'L','J':'M','K':'N','L':'O','M':'P','N':'Q','O':'R','P':'S','Q':'T','R':'U','S':'V','T':'W','U':'X','V':'Y','W':'Z','X':'A','Y':'B','Z':'C'}
# Use the codebook to encrypt the following message.

M = 'ATTACKATDAWN'
C = ''
for m in M:
    m_encrypted = codebook[m]
    C += m_encrypted
C
'DWWDFNDWGDZQ'
# Exercise:

# Encrypt your own name using the Caesar cipher
# Write your solution here

As a function ...

Now define a function called caesar_encrypt(M) which takes a message M (assumed to be only uppercase Roman letters) and returns the ciphertext resulting from applying the Caesar cipher to M

# Please define the function here

# Solution:

def caesar_encrypt(M,codebook = codebook):
    C = ''
    for m in M:
        m_encrypted = codebook[m]
        C += m_encrypted
    return C

#More generally the Caesar cipher is just a certain substitution cipher...

def substitute(M,codebook):
    """
        Every character in the string M
       is replaced with its encoding codebook[m]
    """
    C = ''
    for m in M:
        m_encoded = codebook[m]
        C += m_encoded
    return C    
caesar_encrypt(M)  #This should encrypt M now that you've defined the function.  
'DWWDFNDWGDZQ'

Decryption

We will now make a new dictionary which is the inverse of the codebook and use it for decryption.

In the cell below, make a new dictionary decodebook which decrypts your encryption of M back to the original message.

# Write your decryption dictionary here.  Try to define it using code, not by hand.
decodebook = dict()
#want decodebook[a]==b  if and only if codebook[b] == a

#  because codebook['A']=='D',  we want decodebook['D']=='A'


#Strategy:  iterate over codebook.items() make decodebook have the opposite entries


# Solution:
for key,value in codebook.items():
    decodebook[value] = key

decodebook.items()

dict_items([('D', 'A'), ('E', 'B'), ('F', 'C'), ('G', 'D'), ('H', 'E'), ('I', 'F'), ('J', 'G'), ('K', 'H'), ('L', 'I'), ('M', 'J'), ('N', 'K'), ('O', 'L'), ('P', 'M'), ('Q', 'N'), ('R', 'O'), ('S', 'P'), ('T', 'Q'), ('U', 'R'), ('V', 'S'), ('W', 'T'), ('X', 'U'), ('Y', 'V'), ('Z', 'W'), ('A', 'X'), ('B', 'Y'), ('C', 'Z')])

Decrypting a real message

Your spies intercept the ciphertext message C = 'PHHWDWWKHWRZHUEHIRUHOXQFK', sent by Caesar.

What is the original message?

# Find the original message here.
substitute(C,decodebook)
'ATTACKATDAWN'
C = 'PHHWDWWKHWRZHUEHIRUHOXQFK'
substitute(C,decodebook)

'MEETATTHETOWERBEFORELUNCH'