Substitution Ciphers

Another encryption example is the substitution cipher.  With a substitution cipher, each character in an alphabet maps to a cryptabet with different characters in the same position.  The simplest example of this is the Atbash or reverse-alphabet cipher.  

Alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZ
Cryptabet: ZYXWVUTSRQPONMLKJIHGFEDCBA

Example script: substitution_cipher_atbash

  • Enter substitution_cipher_atbash into the micro:bit Python Editor
  • Set the project's name to substitution_cipher_atbash.
  • Click Save.
  • Click the Send to micro:bit button.
# substitution_cipher_atbash
 
from microbit import *
 
# Atbash cipher.
def atbash(text):
    alpha  = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    crypta = "ZYXWVUTSRQPONMLKJIHGFEDCBA"
    result = ""
 
    for letter in text:
        letter = letter.upper()
        index = alpha.find(letter)
        result = result + crypta[index]
 
    return result
 
# The script starts executing statements from here.
 
sleep(1000)
 
print("Set your keyboard to CAPS LOCK.")
print()
 
while True:
    plaintext = input("Enter a CAPS LOCK string: ")
    
    result = atbash(plaintext)
 
    print("result =", result)
  • Make sure your keyboard is set to CAPS LOCK, or be prepared to hold down the SHIFT key as you type letters.
  • Click in the the serial monitor.  
  • Try typing ABCD and then pressing Enter.  The result should be ZYXW.
  • Now, try ZYXW, the result should be ABCD.


How It Works - substitution_cipher_atbash

Your code has to use result = atbash(plaintext) to get the ciphertext—no key required.

The atbash function has one parameter, text.  The built-in key is the cryptabet, a reverse alphabet in this case.  Like the other cipher functions, this one also declares an empty string named result to store the result.

def atbash(text):
    alpha  = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    crypta = "ZYXWVUTSRQPONMLKJIHGFEDCBA"
    result = ""

Inside the loop that generates the ciphertext, it starts the same way, by finding the index of the letter in the alphabet with index = alpha.find(letter).  What’s different is ciphertext = ciphertext + crypta[index].  This grabs the character with the same index in the cryptabet, and adds it to the result.

    for letter in text:
        letter = letter.upper()
        index = alpha.find(letter)
        result = result + crypta[index]

    return result

Example: Let’s say that letter is E.  It’s index in the alphabet is 4.  The character at crypta[4] is V, so V would be added to the result string.

Your Turn – Custom Cryptabet

Here is an alphabet that also includes digits, a space and some characters that would be useful for making a dictionary.

Alphabet: abcdefghijklmnopqrstuvwxyz 123456789:,{}'

  • Make a cryptabet by scrambling all 41 characters.  

Your Cryptabet: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

  • After making your custom cryptabet, substitute the alphabet and cryptabet into the atbash function.
  • Rename it scrambled_alphabet.
  • Update the function call accordingly.
  • Save your script as scrambled_alphabet_cipher.
  • Test to make sure that you can encrypt and decrypt this string: {'start' : 3, 'after' : 'Liftoff! '}.