Vigenere Cipher in Swift

Here is another classic cipher in Swift. This time it’s Vigenere. Similar to the way Caesar cipher works, Vigenere cipher improves on a couple of things. If you can recall my previous article, Caesar cipher works by shifting each letter in the plaintext a certain number of places down the alphabet. Vigenere cipher tries to improve on that approach by utilizing the keyword to offset each plain text letter by the keyword letter. This, of course, requires the keyword to be of the same length as the plain text.

But before we dive into code, let’s make sure we understand how Vigenere cipher works in detail.

The above example demonstrates Vigenere cipher at work. What I would like to focus your attention on is the original (plain) text and the key. Observe first letter of the original text and the first letter of the keyword. They are:

The location of the “W” letter in english alphabet is “22” if you count from 0 (typical). The location of the letter “M” in english alphabet is “12”. It is important to note that you can create your own map and give each letter it’s own location. However, for the sake of this tutorial, we will use the 0 – 25 index where “A” is “0”. Knowing this, the encryption happens by adding both “W” and “M” locations to produce cipher letter location:

There are only 26 letters in the english alphabet which means “34” is not a valid index. To solve this, we need to use modulo operation to create a new index that we could use. This is rather simple:

Having this understanding is vital when encrypting or decrypting Vigenere cipher text.

Another important point I’ve made earlier that I would like to reiterate is the fact that the keyword should be of the same length as the actual plain text. This, of course, requires us to write a function that would take the keyword and repeat it multiple times until the length of the “new” keyword is the same as the length of the plain text.

So… I am going to begin by creating a couple of private functions to do the following:

  1. Create a valid keyword.
  2. Create encryption / decryption map to encrypt or decrypt text.
  3. Implement cipher.

As you can see below, I am creating a private constant called alphabet consisting of lower case, english letters. Next, I declare and implement a “key” function for generating the correct length keyword based on the length of the plain text supplied by the user.

Function “map” enumerates through the array of letters and creates a forward map where the key is the letter and the value is the location of the letter; reversed map uses the location as the key and the letter as the value. I also keep track of the location of the last letter in the alphabet. Forward, reversed and last index data is returned as a tuple. This is great since to generate this data I only need to enumerate through the array once.

Next, I am going to create Action enum with .Encyption and .Decryption values. This will allow me to write a single function for encrypting and decrypting text.

And here is the final piece of the puzzle:

The only difference between encrypting and decrypting text is how we calculate the outputIndex. Alternatively, I could have written separate functions to perform encryption and decryption… but there is really no good reason to do that.

If you are at all interested in a fully working sample code, you can find it on my Github page.

Vigenere Cipher in Swift