CODEX: My First Foray Into Cryptology & AJAX

I know, it sounds like a bit of a weird coupling, but I’ve been meaning to start learning AJAX for a while now and well, my ongoing code-system desperately needed some TLC.

I’ve been interested in codes and such like since an early age, what kid doesn’t like making secret messages to send to friends. So when a mates younger step-brother asked me if I could make him a simple program to transcode messages I happily obliged and knocked up a dead simple app in PHP. But this got me thinking, if it was so easy to make a simple shift cipher then how hard could it be to make a more advanced version, say a poly-alphabetic substitution cipher? Like this one that I’ve been reading about for years off and on.

Vigenere cipher

Now anyone with a bit of knowledge about cryptology will tell you that a substation cipher can be cracked dead easily (Charles Babbage was the first to crack this particular version), but still, as a starting point it seemed ripe to try. The basic operation of the cipher is very simple, a message (the Plaintext) is encrypted using a Keyword. The keyword is repeated until its length matches that of the Plaintext. Now, each letter of the plaintext is taken in turn and encoded using the corresponding letter in the keyword. The table on the right helps explain this a lot better than I can. To encrypt any letter you find its column, then find the row of the keyword. WikiPedia provides a much better explanation than me, so if you’re lost just head over there. My problem now was finding a way of taking that table of 676 cells and creating a feasible application in PHP.

The Crypto Bit

After dismissing the idea of writing almost 700 switch statements I settled on the idea of a large multi-dimensional array representing the table and then some simple functions to input and output the letters I wanted.

The actual array took up most of the development time, writing out 676 separate rows, one for each individual cell. Thank goodness for copy and paste is all I can say. The array contained two dimensions, the first of these representing the column (plaintext) and the second representing the row (keyword). The value of each item corresponded to the cipher text. The diagram below illustrates this in much better detail.

Vigenere cipher

Once I had the array done I could move on to actually encoding and decoding the data. I began with one of my most common functions used in almost all of my recent projects, the aptly named string2array. This is one of the things that really annoyed me previously, PHP with its big and mighty explode() function couldn’t even split a string. So I came up with this:

function string2array($string){ // Takes a string and splits it into an array
	$strlen = strlen($string); // Get string length
	$i=0;
	while($i<$strlen){ // Go through each character
		$output[] = $string[$i]; // Add each character to an array
		$i++;
	} // End while
	return $output;
}

Very simplistic, but almost invaluable in this project. With this in place I can break down the message and keyword into a nice array to loop through. Well I say message and keyword, but unless your message is less than or equal in length to the keyword you'll be in a bit of bother. In comes str_pad() to save the day, making the keyword the same length as the message. Now I can split them into arrays.

With all three of my arrays at the ready (the cipher table, message and keyword) I can begin the encoding phase. The encode() function is simplicity in itself, forget massive switch statements, these 6 lines are all you need. Firstly I make all the arrays accessible to the function hence the global ($code contains the cipher table array just to clear that up). Then it is simply a case of looping through each message letter replacing it with the corresponding cipher letter. The ternary operator is simply there in the event that no cipher text is returned i.e. it wasn't a letter we were encoding. In that even the output is simply whatever the input was. The final step is to take all the array items returned and join them together into one cohesive sentence. The entire function is shown below.

function encode(){ // Encodes the string
	global $message_array, $code, $key_array;
	foreach($message_array as $key=>$letter){
		$output_arr[] = ($code[$letter][$key_array[$key]]!='')?$code[$letter][$key_array[$key]]:$letter;
	}
	$output = implode('',$output_arr);
	return $output;
}

The decode part I hadn't put much thought into and as I came to approach it I wasn't sure how best to tackle the problem, there was no way I was going to write another 676 lines of code simply swapping around two values. And that's when it hit me, I was simply swapping around values I already had.

foreach ($code as $col=>$row){
	$decode[$col] = array_flip($row);
}

This tiny little piece of code placed under the main cipher table simply takes that array and swaps around the second identifier (the key letter) and the value (the cipher text). Simplicity in itself. Now all I had to do was copy the encode function, change a few variable names and I was done! Please note, this script doesn't include any user input sanitizing and for ease of use I put the cipher table in a separate file. You can grab the entire source at the end.

I now had a fully working poly-alphabetic substitution cipher that could encode and decode messages using a given keyword. To see a working example of this script, just click here. And this is how I left the project for a few months until I got talking to Neo Geek and began experimenting with AJAX.

Abracadabra

Returning to the project after a few months I was left with some nicely commented code (a rarity for me) and a desire to improve upon everything I wanted to do before but just couldn't be arsed to. The first thing I did was spruce up the eye candy; colours, borders, nice arrangements. It's still no looker, but the new version is definitely an improvement over v1.0. With that out the way I could began trying my hand at AJAX.

And before we move on, I have to admit something. My experience with JavaScript is limited. Really limited. As in I've written about 50 lines in my entire life. Yes. I was a complete novice. And I pretty much still am, but I can at least pretend to know what I'm talking about and I can read other peoples scripts fairly easily.

I began with the simplest of tasks, automatically setting the focus to the message input box, a tiny bit of code I had used before. Following this came the harder stuff, the actual AJAX portion of the file. Using the advice given to me by Neo Geek and various online tutorials I ended up with three basic functions; createRequestObject() created my XMLHttpRequest, transcode() sent the data off to the PHP script and handleResponse() displayed the results. As an afterthought I created a fourth function to decode the result given by handleResponse(), this involved hiding the result in a separate element and then handing it back to the transcode function as needed.

With that complete I moved the files from my home dev server to my account with Dreamhost so everyone could have a look at my work. And that's when it all broke. I instantly knew it had to be something to do with the AJAX and the way Dreamhost treated it. Every attempt was met with a "Page Temporarily Unavailable" message and no amount of tweaking my code could change it. Earlier versions had worked fine, but add in AJAX and it was a no-go.

A bit of searching later and I found the answer. Due to the mod_security module enabled on Dreamhosts servers, certain requests and the like are blocked with a 503 error. The solution? Disable certain options in the control panel (link here for those who wish to know all the details). And voila, CODEX worked perfectly, happily transcoding any message put in.

It might not be the prettiest, the code may not be to certain peoples opinions, but it works and serves its purpose, both as a simple tool and as a learning experience. The final product can be found here and the source code here.

  • 11 jul 19:41