 Shared171 / Crypto / substitution_cipher.ipynbOpen in CoCalc
Author: Hunter Johnson
Description: Some exercises in basic cryptography

The Caesar cipher was silly. It was effective mainly against illiterate people.

A more serious (but still silly) cipher is a substitution cipher.

In this kind of cipher, any plaintext letter can be mapped to any ciphertext letter.

We'll define one of these below (and eventually see how to crack such a cipher).

## We'll need a copy of the alphabet to work with.
## Let's use this as our main alphabet
alphabet = tuple( "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
print(alphabet)

## And here we'll make a copy of the alphabet that we don't mind destroying (with pop() operations, for example).
alpha_copy = list(alphabet[:])
print(alpha_copy)

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

##  In this cell we'll make a "codebook" dictionary similar to the one we made for the Caesar cipher.
##  Try to understand how it works.
import random
random.seed(0)  ##  This will make us all get the same "random" numbers.
substitutions = dict()
for letter in alphabet:
r = random.randint(0,len(alpha_copy)-1)
ciphertext_letter = alpha_copy.pop(r)
substitutions[letter] = ciphertext_letter
print(substitutions)

{'A': 'M', 'B': 'Z', 'C': 'O', 'D': 'B', 'E': 'J', 'F': 'U', 'G': 'T', 'H': 'Q', 'I': 'L', 'J': 'X', 'K': 'R', 'L': 'N', 'M': 'E', 'N': 'P', 'O': 'D', 'P': 'H', 'Q': 'F', 'R': 'C', 'S': 'S', 'T': 'V', 'U': 'Y', 'V': 'W', 'W': 'G', 'X': 'I', 'Y': 'A', 'Z': 'K'}
##  Here is our encoding function.  Be sure you understand how it works.

def encode(codebook,message):
ciphertext = ""
for letter in message:
if ord(letter) not in range(ord('A'),ord('Z')+1):
print("Invalid message:  Only uppercase letters allowed.")
return
ciphertext += codebook[letter]
return ciphertext

# We practice using the function correctly

encode(substitutions,"ILOVELUCY")

'LNDWJNYOA'
# We also see what happens when we use the function incorrectly.

encode(substitutions,"I LOVE LUCY")

Invalid message: Only uppercase letters allowed.
#  Use your knowledge of Python string processing to convert the following message into an all caps version with no punctuation or spaces.

M = "It rained and it rained and it rained. Piglet told himself that never in all his life, and he was goodness knows how old - three, was it, or four? - never had he seen so much rain. Days and days and days. With Piglet trapped by the flood, his Missage in a bottle may be the only hope."

import string
string.punctuation,string.whitespace
M=M.upper()
for badchar in (string.punctuation + string.whitespace):
M

#   Encrypt the message here.
encode(substitutions,M)


'LVCMLPJBMPBLVCMLPJBMPBLVCMLPJBHLTNJVVDNBQLESJNUVQMVPJWJCLPMNNQLSNLUJMPBQJGMSTDDBPJSSRPDGSQDGDNBVQCJJGMSLVDCUDYCPJWJCQMBQJSJJPSDEYOQCMLPBMASMPBBMASMPBBMASGLVQHLTNJVVCMHHJBZAVQJUNDDBQLSELSSMTJLPMZDVVNJEMAZJVQJDPNAQDHJ'


## Don't run this cell!
print(encode(substitutions,M))

## In case you do, here's what it said:

C = 'ENEOENFLEOKFXAQNOFDEMTPXOQONPOKPOPOJEOHEXIVWFVWQXKEOKIPHOSFMVMPOPUEMCWPPNAEMVFXEVESFFNFZFOWFDPOEMCWPNEXMWQYVPVWFDFMVAQOMVFXMCWPPNWFDFOVPOVPEVVFOKCEATXQKSFHOQZFXMQVIEOKTFCEAFVWFFKQVPXPUVWFHOKFXSXEKHEVFYEYFXSXEOVEEUVFXSXEKHEVQOSUXPACEATXQKSFQOAQNOFAPZFKTECGVPNPOKPODQVWFOPHSWMEZQOSMVPNQZFUPXPOFIFEXWFDEMKFVFXAQOFKVPTFCPAFEDXQVFXTIWFWEKTFFOPUUFXFKVWFYPMQVQPOPUEMMQMVEOVFKQVPXEVYHOCWECNEMMQCTXQVQMWWHAPXAESERQOFWFXFAEQOFKEVYHOCWUPXVWFOFLVFQSWVIFEXM'

ENEOENFLEOKFXAQNOFDEMTPXOQONPOKPOPOJEOHEXIVWFVWQXKEOKIPHOSFMVMPOPUEMCWPPNAEMVFXEVESFFNFZFOWFDPOEMCWPNEXMWQYVPVWFDFMVAQOMVFXMCWPPNWFDFOVPOVPEVVFOKCEATXQKSFHOQZFXMQVIEOKTFCEAFVWFFKQVPXPUVWFHOKFXSXEKHEVFYEYFXSXEOVEEUVFXSXEKHEVQOSUXPACEATXQKSFQOAQNOFAPZFKTECGVPNPOKPODQVWFOPHSWMEZQOSMVPNQZFUPXPOFIFEXWFDEMKFVFXAQOFKVPTFCPAFEDXQVFXTIWFWEKTFFOPUUFXFKVWFYPMQVQPOPUEMMQMVEOVFKQVPXEVYHOCWECNEMMQCTXQVQMWWHAPXAESERQOFWFXFAEQOFKEVYHOCWUPXVWFOFLVFQSWVIFEXM
## Try to decrypt the above message by hand.  We'll soon learn techniques that work faster.

## This will be helpful:  https://www3.nd.edu/~busiforc/handouts/cryptography/Letter%20Frequencies.html