Another substitution cipher is the Vigenère cipher. In this post, I give you an explanation of the cipher and a python implementation.
The Vigenère cipher is categorized under polyalphabetic substitution ciphers. This type of cipher works as follows[1]:
- They use related monoalphabetic substitution rules.
- The key is used to determine what rule to apply for a given transformation.
The Vigenère cipher
This cipher is quite easy to understand.
We apply the Caesar cipher to each letter of the plain message. Using as the shift the corresponding value of the key. Here is an example.
Message = “Hello”
Key = “key”
As you should know, the key is a numeric value. So, we transform the value “key” into its numeric value 10,4,24. These values are just the position (from 0 to 25) of the letter in the English alphabet, e is in position 4 (a,b,c,d,e).
To calculate the cipher text, we do as follow:
message | h | e | l | l | o |
key | 10 | 4 | 24 | 10 | 4 |
ciphertext | Caesar(10,”h”) | Caesar(4,”e”) | Caesar(24,”l”) | Caesar(10,”l”) | Caesar(4,”o”) |
r | i | j | v | s |
Notice that once we used all the numbers in the key, we start over until we encrypt every letter of the plaintext message.
To decrypt the message, we just need to use the negative values of the key. To decrypt using the example above, we can use the same procedure with the key=[-10,-4,-24].
Let’s now examine the python implementation.
Practicing the Vigenere cipher
I always recommend to my students that before implementing a cipher in a specific programming language, they should know how to do it themselves (what some programmers call doing it by hand).
This is useful because it gives you a deeper knowledge of the algorithm. Also, it can show you before the time, some possible bugs you can get in your code.
A common question from my students is this one: “Do I need to use the ASCII code of each letter to try the cipher using pen and paper?”
My answer to that question is no. You can just assign values to each letter (0 to 25), and execute the algorithm yourself.
The values that you assign do not matter much. All that matters is that you use the same values for encryption and decryption.
Notice that not all algorithms are meant to be done “by hand”. For instance, it is not expected that a student can simulate, by hand (on paper), the execution of DES or AES for a specific input. I recommend doing it only for simple algorithms as it is beneficial for the students.
Python implementation of the Vigenère cipher
See below the implementation.
def vigenere(key, message):
message = message.lower()
message = message.replace(' ','')
m = len(key)
cipher_text = ''
for i in range(len(message)):
letter = message[i]
k= key[i % m]
cipher_text = cipher_text + chr ((ord(letter) - 97 + k ) % 26 + 97)
return cipher_text
Notice that the parameter key is a list that contains numbers, not letters.
And the variable message is just a string.
You can test this implementation with the following python console app.
if __name__=='__main__':
# a sample of encryption and decryption
print ('Encripting')
key = 'key'
key = [ord(letter)-97 for letter in key]
cipher_text = vigenere(key, 'hello')
print ('cipher text: ',cipher_text)
print ('Decrypting')
key = [-1*k for k in key]
plain_text = vigenere(key, cipher_text)
print ('Plain text: ', plain_text)
In this example, I first assign a string value to the key and later convert it to numbers. This is kind of an easy way to use a string as the key.
But, you can use numbers straight as the key and avoid 1 line of code if you prefer so.
Always remember, that before you try to decrypt, you should update the key to the negative values.
And that’s it.
I hope this is a helpful explanation and you can understand better with the python code for this cipher.
[1] Cryptography and Network Security by William Stallings