Case study

Let's walk through test-driven development by writing a small, tested, cryptography application. Don't worry–you won't need to understand the mathematics behind complicated modern encryption algorithms such as AES or RSA. Instead, we'll be implementing a sixteenth-century algorithm known as the Vigenère cipher. The application simply needs to be able to encode and decode a message, given an encoding keyword, using this cipher.

If you want a deep dive into how the RSA algorithm works, I wrote one on my blog at https://dusty.phillips.codes/.

First, we need to understand how the cipher works if we apply it manually (without a computer). We start with a table like the following one:

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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 

Given a keyword, TRAIN, we can encode the message ENCODED IN PYTHON as follows:

  1. Repeat the keyword and message together, such that it is easy to map letters from one to the other:
E N C O D E D I N P Y T H O N
T R A I N T R A I N T R A I N
  1. For each letter in the plaintext, find the row that begins with that letter in the table.
  2. Find the column with the letter associated with the keyword letter for the chosen plaintext letter.
  3. The encoded character is at the intersection of this row and column.

For example, the row starting with E intersects the column starting with T at character X. So, the first letter in the ciphertext is X. The row starting with N intersects the column starting with R at character E, leading to the ciphertext XE. C intersects A at C, and O intersects I at W. D and N map to Q, while E and T map to X. The full encoded message is XECWQXUIVCRKHWA.

Decoding follows the opposite procedure. First, find the row with the character for the shared keyword (the T row), then find the location in that row where the encoded character (the X) is located. The plaintext character is at the top of the column for that row (the E).