Simplest Cryptography - Caesar Cipher
Understanding and implementation in Python
Introduction
Caesar Cipher is one of the most straightforward and earliest encryption and decryption techniques.
This technique is based on the mono-alphabetic ciphers known as shift or additive ciphers. This is a sort of substitute method that replaces all text letters with others.
Julius Caesar used the Shift Cipher effectively to hide messages from his enemies, he used it with a shift of three to protect messages of military significance.
Encryption
Encryption using the Shift Cipher is very easy. First, we must create the ciphertext alphabet, as discussed above is simply found by ‘shifting’ the alphabet to the left by the number of places given by the key. Thus a shift of 1 move “A” to the end of the ciphertext alphabet, and “B” to the left one place into the first position. As the key gets bigger, the letters shift further along, until we get to a shift of 26, when “A” has found its way back to the front.
Once we have created the table, the encryption process is easy, as we just replace each occurrence within the plaintext of a letter with the corresponding ciphertext letter as given by the ciphertext alphabet. Hence, if we wanted to encrypt the plaintext “hello” with the key, we look along the plaintext alphabet row in the first table to find the corresponding cipher letter and combine all letters to form a cipher text.
Coding the Caesar Cipher
# Initialise a list with all 26 alphabets.
alphabet = ['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']
Populate a list of ‘alphabet’ with all 26 letters.
direction = input("Type 'encode' to encrypt, type 'decode' to decrypt:\n")
text = input("Type your message:\n").lower()
shift = int(input("Type the shift number:\n"))
Next, we take direction input for ‘encoding’ or ‘decoding’, text input for plain text or cipher text, and shift input for the number of shifts.
'''
Defining encryption(encoding) function which takes plain text and number
of shifts as parameters
'''
def encrypt(plain_text, shift_amount):
cipher_text = "" #empty cipher string
for letter in plain_text:
position = alphabet.index(letter)
new_position = (position + shift_amount) % 26
cipher_text += alphabet[new_position]
print(f"The encoded text is {cipher_text}")
This encryption function generates a cipher text from plain text.
'''
Defining decryption(decoding) function which takes ciphertext and number
of shifts as parameters
'''
def decrypt(cipher_text, shift_amount):
plain_text = ""
for letter in cipher_text:
position = alphabet.index(letter)
new_position = (position - shift_amount) % 26
plain_text += alphabet[new_position]
print(f"The decoded text is {plain_text}")
This decrypt() function decrypts the cipher text to plain text.
'''
Check if the user wanted to encrypt or decrypt the message by checking
the 'direction' variable.
'''
if direction == "encode":
encrypt(plain_text=text, shift_amount=shift)
elif direction == "decode":
decrypt(cipher_text=text, shift_amount=shift)
That is how you get the encrypted and decrypted version of your original text. Try it for yourself!
Improving the Code
Instead of having 2 different functions which almost do the same thing, we combine both of them in a single function i.e caesar(start_text, shift_amount, cipher_direction)
def caesar(start_text, shift_amount, cipher_direction):
end_text = ""
if cipher_direction == "decode":
shift_amount *= -1
for letter in start_text:
position = alphabet.index(letter)
new_position = position + shift_amount
end_text += alphabet[new_position]
print(f"The {cipher_direction}d text is {end_text}")
caesar(start_text=text, shift_amount=shift, cipher_direction=direction)
Finally, we got rid of 2 different functions
Thank you for reading!