Inside the World of Ciphers

Ciphers, a great marvel of mathematics and secrecy. They are the very heart of encryption, but how do we bring this to the world of programming and make some kick ass stuff with them? I had gotten the idea of showing some ciphers through a recent question that had been brought up. So I thought I would throw out some code from the dark corners of encryption for today’s blog on the Programming Underground.

A Vernam cipher was invented by Gilbert Sandford Vernam in 1917. In simple implementations it uses a one-time pad of random or pseudorandom letters (a stream cipher) to encrypt a string of text. Two parties would be given the same pad of papers securely and told to use certain pages on certain days or use them one at a time in order, each page acting as the “key”. After using a key, each party is to then destroy the paper after the message has been sent and received… forever casting the page into oblivion and the encrypted message with it. Ever remember the line in Swordfish where Huge Jackman’s character (Stanley) asks John Travolta’s character (Gabriel) what type of encryption he needed? Gabriel replying “A vernam encryption” only to have Stanley cringe and remind Gabriel that a Vernam key code is destroyed on implementation? This is what he was talking about.

Often times the key would be on flash paper which when burned would leave no ash. Now we are getting into the whole James Bond stuff!

The second cipher we will be talking about is the Vigenere cipher created by Blaise de Vigenère in his 1533 book La cifra del and presented it to the court of King Henry the III of France. This cipher uses a table known simply as “tableau” if you want to get all fancy. It consists of a grid of letters 26 x 26. You then simply take a letter from a key and a letter from a message and use them to lookup the encrypted character. This cipher was considered pretty secretive for nearly 300 years until the 1800’s when it was cracked.

Both of these ciphers are not nearly secure as the hashes used today like Whirlpool, SHA, or MD5. These ciphers can be cracked relatively quickly with computing power, but the Vernam cipher is secure enough for basic home usage like for Wireless communication.

The code and talk about Vernam can be found at the following posting…

Vernam Cipher Discussion and Example Code

Below we will now focus on the Vigenere Cipher. I wrote this code in both Java and ported it over to C# for those in the .NET framework to use. As you will see, the idea behind it is relatively straight forward and given a proper setup we can easily use the table to generate our message. I wanted it noted that these are examples and should be fully tested before deployment in any production environment. They serve as the framework for a more solid and elaborate solution that should be left up to the individual developer.

Java Version – Vigenere Cipher

public class vigenere {

	// Define our tableau letter grid
	static char[][] tableau = fillArray();

	public static void main(String args[]) {
		
		// Lets encrypt and decrypt a message
		System.out.println(encryptText("RELATIONS","TO BE OR NOT TO BE THAT IS THE QUESTION")); 
		System.out.println(decryptText("RELATIONS","KSMEHZBBLKSMEMPOGAJXSEJCSFLZSY"));

	}


	// Encrypts text using a key string and the plain text message.

	private static String encryptText(String key, String plainText) {
		String result = "";

		// Uppercase and trim our strings
		key = key.trim().toUpperCase();
		plainText = plainText.trim().toUpperCase();

		int keyIndex = 0;
		int keylength = key.length();

		for (int i = 0; i < plainText.length(); i++) {
			// Remove anything that isn't a letter.

			if (Character.isLetter(plainText.charAt(i))) {

				// This applies the key to each letter, recycling the key once at its end.
				keyIndex = keyIndex % keylength; 
				result += LookupLetter(key.charAt(keyIndex),plainText.charAt(i));
				keyIndex++;
			}
		}
		return result;

	}


	// Decrypts a string using the key and the encrypted cipher text.

	private static String decryptText(String key, String cipherText) {
		String result = "";

		// Capitalize and trim string values
		key = key.trim().toUpperCase();
		cipherText = cipherText.trim().toUpperCase();

		int keyIndex = 0;
		int keylength = key.length();

		// Loop through cipher text, pulling each character
		for (int i = 0; i < cipherText.length(); i++) {

			// If letter, offset it and then search that column for the cipher chracter
			if (Character.isLetter(cipherText.charAt(i))) {
				keyIndex = keyIndex % keylength;
				int keyChar = key.charAt(keyIndex) - 65;

				// If we found the cipher character in the column
				// Reapply offset and convert to original uncrypted letter index

				for (int find = 0; find < 26; find++) {
					if (tableau[keyChar][find] == cipherText.charAt(i)) {
						result += (char) (find + 65);
					}
				}		
		
				keyIndex++;
			}
		}
		return result;

	}


	// Create our initial "tableau" letter grid.
	private static char[][] fillArray() {
		String letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		int length = letters.length();

		char[][] tableau = new char[length][length];

		for (int i = 0; i < length; i++) {
			for (int j = 0; j < length; j++) {
				// Shift our letters once each row
				int getLetter = j + i;

				// If we reached the end of the letters, start at the beginning again.
				if (getLetter > (length - 1)) { getLetter -= length; }
				tableau[i][j] = letters.charAt(getLetter);
			}
		}

		return tableau;
	}


	// Used by encryptText to find the corresponding "letter" for two given letter coordinates.
	// Returns encrypted letter value.

	private static char LookupLetter(char character1, char character2) {
		int letter1 = (int) Character.toUpperCase(character1);
		int letter2 = (int) Character.toUpperCase(character2);

		// Offset capital letters by 65 (value of 'A') to give us an index value
		letter1 -= 65;
		letter2 -= 65;

		// Check to make sure value is in given alphabet range.
		if ((letter1 >= 0) && (letter1 <= 26)) {
			if ((letter2 >= 0) && (letter2 <= 26)) {
				return tableau[letter1][letter2];
			}
		}
		return ' ';
	}
}

The inline code tells most of the story. We take the message character by character along with a key which repeats. In this situation we are using the key “RELATIONS”. We take the first letter “R” and the first letter of our string “TO BE OR NOT TO BE THAT IS THE QUESTION” which is “T” and use them to lookup a character in our table called “Tableau”. The table contains 26 rows of 26 (each row has the alphabet). It looks like the table below.

		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

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

Using the two letters we would then go over to column “R” and down to row “T” to find the letter “K”. To decrypt we would go to column “R” and find which row the letter “K” was on, then take the index of that row “T”.

For our implementations we are making sure to strip out non letters. If you wish to expand it to include other characters in your “tableau” it will get much bigger. However it can be done with relative ease and with little modification. I am just sticking with the basic implementation here so that you can get the idea.

Below is the C# implementation so that those on the .NET framework can play around with it.

C# Version – Vigenere Cipher

namespace vigenere
{
	public partial class Form1 : Form
	{
		static char[,] tableau = fillArray();

		public Form1()
		{
			InitializeComponent();
		}

		private void button1_Click(object sender, EventArgs e)
		{
			MessageBox.Show(encryptText("RELATIONS", "TO BE OR NOT TO BE THAT IS THE QUESTION"));
			MessageBox.Show(decryptText("RELATIONS", "KSMEHZBBLKSMEMPOGAJXSEJCSFLZSY"));
		}

		// Encrypts text using a key string and the plain text message.

		private static String encryptText(String key, String plainText)
		{
			String result = "";

			// Uppercase and trim our strings
			key = key.Trim().ToUpper();
			plainText = plainText.Trim().ToUpper();

			int keyIndex = 0;
			int keylength = key.Length;

			if ((keylength <= 0)) { return result; } 

			for (int i = 0; i < plainText.Length; i++)
			{
				// Remove anything that isn't a letter.

				if (Char.IsLetter(plainText,i))
				{

					// This applies the key to each letter, recycling the key once at its end.
					keyIndex = keyIndex % keylength;
					result += LookupLetter(key.Substring(keyIndex,1), plainText.Substring(i,1));
					keyIndex++;
				}
			}
			return result;

		}


		// Decrypts a string using the key and the encrypted cipher text.

		private static String decryptText(String key, String cipherText)
		{
			String result = "";

			// Capitalize and trim string values
			key = key.Trim().ToUpper();;
			cipherText = cipherText.Trim().ToUpper();

			int keyIndex = 0;
			int keylength = key.Length;

			if (keylength <= 0) { return result; }

			// Loop through cipher text, pulling each character
			for (int i = 0; i < cipherText.Length; i++)
			{

				// If letter, offset it and then search that column for the cipher chracter
				if (Char.IsLetter(cipherText, i))
				{
					keyIndex = keyIndex % keylength;
					int keyChar = Convert.ToInt32(Convert.ToChar(key.Substring(keyIndex,1))) - 65;

					// If we found the cipher character in the column
					// Reapply offset and convert to original uncrypted letter index

					for (int find = 0; find < 26; find++)
					{
						if (tableau[keyChar,find].ToString().CompareTo(cipherText.Substring(i,1)) == 0)
						{
							result += (char)(find + 65);
						}
					}

					keyIndex++;
				}
			}
			return result;

		}

		// Fill our tableau array
		private static char[,] fillArray() {
				String letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
				int length = letters.Length;

				tableau = new char[length, length];

				for (int i = 0; i < length; i++) {
					for (int j = 0; j < length; j++) {
						// Shift our letters once each row
						int getLetter = j + i;

						// If we reached the end of the letters, start at the beginning again.
						if (getLetter > (length - 1)) { getLetter -= length; }
						tableau[i,j] = Convert.ToChar(letters.Substring(getLetter,1));
					}
				}

				return tableau;
		}


		// Used by encryptText to find the corresponding "letter" for two given letter coordinates.
		// Returns encrypted letter value.

		private static char LookupLetter(String character1, String character2)
		{
			int letter1 = Convert.ToInt32(Convert.ToChar(character1)); 
			int letter2 = Convert.ToInt32(Convert.ToChar(character2));

			// Offset capital letters by 65 (value of 'A') to give us an index value
			letter1 -= 65;
			letter2 -= 65;

			// Check to make sure value is in given alphabet range.
			if ((letter1 >= 0) && (letter1 <= 26))
			{
				if ((letter2 >= 0) && (letter2 <= 26))
				{
					return tableau[letter1,letter2];
				}
			}
			return ' ';
		}
	}
}

And that is all there is to it! Use it to encrypt messages in class or write a love poem that only a hacker could do it. The code presented here is in the public domain and freely available for unrestricted use. Please though, try to understand what is going on before using it so, in the future, you can modify it with some cool new features.

About The Author

Martyr2 is the founder of the Coders Lexicon and author of the new ebooks "The Programmers Idea Book" and "Diagnosing the Problem" . He has been a programmer for over 25 years. He works for a hot application development company in Vancouver Canada which service some of the biggest tech companies in the world. He has won numerous awards for his mentoring in software development and contributes regularly to several communities around the web. He is an expert in numerous languages including .NET, PHP, C/C++, Java and more.