The ADFGVX Cipher

The first in a series of many blog posts I hope to be making as I go on an adventure of learning Cryptography through Programming. Today’s entry is about the ADFGVX cipher, used in World War 1, and first used by me because it was the first on the list.

History

The ADFGVX cipher was invented and used by the Germans during World War 1. It is considered a Fractionating Transposition Cipher, and is in fact based off an earlier cipher, invented by Col. Fritz Nebel in 1918 called ADFGX. The V was added to allow for the use of the full alphabet, and the numbers 0-9, instead of combining the letters i and j. The letters A, D, F, G, V, and X were chosen because of how dissimilar they sounded using Morse code, to make it easier to distinguish the various parts of the message.

The cipher was broken on April 5th, 1918, using complex cryptanalysis algorithms by a French Army Lieutenant, Georges Painvin. This is generally attributed to the French Army’s stop to the German’s Spring Offensive of 1918, as the code was broken a few weeks after wards and thus told the French about the Germans’ plans to attack Ludendorff, however looking at the dates, by April 5th, the attack had already petered out and so this claim is generally regarded as false.

Today the ADFGVX cipher is considered technologically and cryptographically insecure, however it’s security can be increased (as with almost any other cipher) by taking the output and sending it through multiple other ciphers as desired. It still will not make it unbreakable, but it will take longer to break, which may be key enough to get a distinct advantage over whoever is trying to break your code.

How It Works

A predetermined, random, alphabet of letters is given (referred to as a Mixed Alphabet, in the case of this program, it is generally:

"MBJYA,Z(?PS.)NX; DURITW:!HGLFECVO'KQ"

as the random shuffle used by the computer is seeded the same way each time the program runs. This alphabet is then transposed into a Polybius Square, using the letters A, D, F, G, V, X as coordinates for the square.


  A D F G V X
A M B J Y A ,
D Z ( ? P S .
F ) N X ; D
G U R I T W :
V ! H G L F E
X C V O ' K Q

We then acquire what is called a plaintext (the message to be enciphered), and a transposition key (a collection of non-repeating letters to help obfuscate the message).

With the plaintext, we go through each letter, and find it’s respective coordinates on the polybius square. So, if the plaintext were:

HELLO, WORLD.

Going through it would generate the string:

DVXVGVGVFXXAVFVGFXDGGVXFXD

Then, we take that string, and then start listing it under the key, going across, before going down.

The key in this case is: “FUBAR”

F U B A R
D V X V G
V G V F X
X A V F V
G F X D G
G V X F X
D

We then take the key word, and organize the letters in alphabetic order, keeping the related values under it’s correlated letter:


A B F R U
V X D G V
F V V X G
F V X V A
D X G G F
F X G X V
    D

Then we take the resulting string order, and translate it into a ciphertext, separating each bit with a space, that looks like this:

VFFDF XVVXX DVXGGD GXVGX VGAFV

And of course, to decode it you reverse the process.

The Code

If you’re still here, this is probably why you’re here in the first place. I wrote the program in C++ using Microsoft’s Visual Studio (Professional Edition). You can find the zipped version of the solution here if you wish to look at it. However if you don’t wanna go through all that trouble, here’s the encode and decode functions for your viewing pleasure.

Encode Function:

/**
 * Encodes a plaintext message using the given key, and polybius square
 */
void	ADFGVX::encode( )
{
	//Local Variables to help encoding.
	string	coordinates = "";
 
	//Create polybius square coordinates for each letter in the phrase.
	for( unsigned int i = 0; i < plaintext.length(); i++ )
	{
		char c = plaintext.at( i );
		for( int y = 0; y < 6; y++ )
		{
			for( int x = 0; x < 6; x++ )
			{
				if( polybius.at(y).at(x) == c )
				{
					coordinates.append( 1, squaremap.at( x ) );
					coordinates.append( 1, squaremap.at( y ) );
				}
			}
		}
	}
 
	//Create Sorted key character, and index pairs.
	//Maps are auto sorted, so we need the index as the second half of the
	//pair to make a successful mapping.
	map< char, int > m;
	for( unsigned int i = 0; i < key.length(); i++ )
	{
		pair<char, int> p( key.at( i ), i );
		m.insert( p );
	}
 
	//Preparing the table to be filled with "coordinates".
	vector< string > v;
	for( unsigned int i = 0; i < key.length(); i++ )
		v.push_back( "" );
 
	//Fill it with coordinates
	for( unsigned int i = 0; i < coordinates.length(); i++ )
		v.at( i % key.length() ).append( 1, coordinates.at( i ) );
 
	//Generate The Cipher Text
	ciphertext = ""; //Clear it out first, in case there's one already there.
	map< char, int >::iterator k; //Iterator through the key map.
 
	//Loop through the map, using the vector to get the proper values to append
	//to the cipher text.
	for( k = m.begin(); k != m.end(); k++ )
	{
		ciphertext.append( v.at( k->second ) );
		ciphertext.append( " " );
	}
}

Decode Function:

/**
 * Decodes a cipher text using the given key, and polybius square.
 */
void	ADFGVX::decode( )
{
	//Temporary variables to help with the decoding.
	vector< string > v, v1;
	string	s;
 
	//Separate each piece into bits in the vector to un-map.
	for( unsigned int i = 0; i < ciphertext.length(); i++ )
	{
		char c = ciphertext.at( i );
		//If we hit a space, we're at the end of a piece, so push it onto the vector.
		if( c == ' ' )
		{
			v.push_back( s );
			s = "";
		}
		else
		{
			s.append( 1, ciphertext.at( i ) );
		}
	}
	//Since the end isn't blocked by a space, we need to push it
	//as it wasn't detected.
	v.push_back( s );
 
	//Re-map the key to get the coordinates in their proper places.
	map< char, int > m;
	for( unsigned int i = 0; i < key.length(); i++ )
	{
		pair<char, int> p( key.at( i ), i );
		m.insert( p );
	}
 
	//Go through the key to get the correct mappings.
	map< char, int >::iterator k;
	for( unsigned int i = 0; i < key.length(); i++ )
	{
		//k is an iterator, and we can't get it's relative position while 
		//looping through, so we have j to keep track of that for us.
		int j = 0; 
		for( k = m.begin(); k != m.end(); k++ )
		{
			if( k->first == key.at( i ) )
				v1.push_back( v.at( j ) );
			j++;
		}
	}
 
	//Peel off the letters to recreate the non-mapped version
	//of the cipher text.
	s = "";
	for( unsigned int i = 0; i < ciphertext.length(); i++ )
	{
		int location = i % v.size();
		string at = v1.at( location );
 
		//This is to make sure we're not dealing with any strings that are
		//already translated and are shorter than other strings being
		//translated.
		if( at.length() > 0 )
		{
			char c = at.at( 0 );
			s.append( 1, c );
			string n_at = at.substr( 1 ); //Chop off the first character
			v1.at( location ) = n_at; //And reset the string to the new value.
		}
	}
 
	//Decode the resulting text from the polybius square.
	plaintext = "";
	for( unsigned int i = 0; i < s.length(); i += 2 )
	{
		int x, y;
		char cx = s.at( i );
		char cy = s.at( i + 1 );
 
		//We need the numerical positions of the coordinate letters.
		for( int k = 0; k < 6; k++ )
			if( cx == squaremap.at( k ) )
				x = k;
		for( int k = 0; k < 6; k++ )
			if( cy == squaremap.at( k ) )
				y = k;
 
		plaintext.append( 1, polybius.at(y).at(x) );
	}
}
  1. Great goods from you, man. I’ve understand your stuff previous to and you are just too great. I actually like what you have acquired here, certainly like what you are saying and the way in which you say it. You make it entertaining and you still take care of to keep it sensible. I cant wait to read much more from you. This is really a terrific site.

  2. ADFGVX Redux – Shifted Bits Blog - pingback on Saturday, November 19th, 2011 at 7:52 am
  3. Hello! I have one question or it’s better to say one request.
    Can you send me the all program code on my e-mail?
    I will be very thankful!!!
    My e-mail: MariAnnaZakorchemna@mail.ru

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Trackbacks and Pingbacks:

© 2013 - Sitemap - Privacy Policy