Transposition Cipher

In cryptography, a transposition cipher, also known as columnar transposition cipher, is a simple and easy to implement cipher. This cipher follows a simple rule for mixing up the characters in the plaintext to form the ciphertext. Although this cipher is weak on its own, but it can be combined with other ciphers, such as a substitution cipher, the combination of which can be more difficult to break than either cipher on it's own.

 

Example:

The key for the transposition cipher is a keyword e.g. 'pangram'. To encrypt a piece of text, e.g. 'The quick brown fox jumps over the lazy dog', we write it out in a special way in a number of rows:

p a n g r a m
T h e   q u i
c k   b r o w
n   f o x   j
u m p s   o v
e r   t h e  
l a z y   d o
g - - - - - -

The columns are now reordered such that the letters in the key word are ordered alphabetically.

a a g m n p r
h u   i e T q
k o b w   c r
    o j f n x
m o s v p u  
r e t     e h
a d y o z l  
- - - - - g -

The ciphertext is read off along the columns: 'hk mra-uo oed- bosty-iwjv o-e fp z-Tcnuelgqrx h -'



									private static int[] GetShiftIndexes(string key)
{
	int keyLength = key.Length;
	int[] indexes = new int[keyLength];
	List<KeyValuePair<int, char>> sortedKey = new List<KeyValuePair<int, char>>();
	int i;

	for (i = 0; i < keyLength; ++i)
		sortedKey.Add(new KeyValuePair<int, char>(i, key[i]));

	sortedKey.Sort(
		delegate (KeyValuePair<int, char> pair1, KeyValuePair<int, char> pair2) {
			return pair1.Value.CompareTo(pair2.Value);
		}
	);

	for (i = 0; i < keyLength; ++i)
		indexes[sortedKey[i].Key] = i;

	return indexes;
}

public static string Encipher(string input, string key, char padChar)
{
	input = (input.Length % key.Length == 0) ? input : input.PadRight(input.Length - (input.Length % key.Length) + key.Length, padChar);
	StringBuilder output = new StringBuilder();
	int totalChars = input.Length;
	int totalColumns = key.Length;
	int totalRows = (int)Math.Ceiling((double)totalChars / totalColumns);
	char[,] rowChars = new char[totalRows, totalColumns];
	char[,] colChars = new char[totalColumns, totalRows];
	char[,] sortedColChars = new char[totalColumns, totalRows];
	int currentRow, currentColumn, i, j;
	int[] shiftIndexes = GetShiftIndexes(key);

	for (i = 0; i < totalChars; ++i)
	{
		currentRow = i / totalColumns;
		currentColumn = i % totalColumns;
		rowChars[currentRow, currentColumn] = input[i];
	}

	for (i = 0; i < totalRows; ++i)
		for (j = 0; j < totalColumns; ++j)
			colChars[j, i] = rowChars[i, j];

	for (i = 0; i < totalColumns; ++i)
		for (j = 0; j < totalRows; ++j)
			sortedColChars[shiftIndexes[i], j] = colChars[i, j];

	for (i = 0; i < totalChars; ++i)
	{
		currentRow = i / totalRows;
		currentColumn = i % totalRows;
		output.Append(sortedColChars[currentRow, currentColumn]);
	}

	return output.ToString();
}

public static string Decipher(string input, string key)
{
	StringBuilder output = new StringBuilder();
	int totalChars = input.Length;
	int totalColumns = (int)Math.Ceiling((double)totalChars / key.Length);
	int totalRows = key.Length;
	char[,] rowChars = new char[totalRows, totalColumns];
	char[,] colChars = new char[totalColumns, totalRows];
	char[,] unsortedColChars = new char[totalColumns, totalRows];
	int currentRow, currentColumn, i, j;
	int[] shiftIndexes = GetShiftIndexes(key);

	for (i = 0; i < totalChars; ++i)
	{
		currentRow = i / totalColumns;
		currentColumn = i % totalColumns;
		rowChars[currentRow, currentColumn] = input[i];
	}

	for (i = 0; i < totalRows; ++i)
		for (j = 0; j < totalColumns; ++j)
			colChars[j, i] = rowChars[i, j];

	for (i = 0; i < totalColumns; ++i)
		for (j = 0; j < totalRows; ++j)
			unsortedColChars[i, j] = colChars[i, shiftIndexes[j]];

	for (i = 0; i < totalChars; ++i)
	{
		currentRow = i / totalRows;
		currentColumn = i % totalRows;
		output.Append(unsortedColChars[currentRow, currentColumn]);
	}

	return output.ToString();
}
								


Example

									string text = "The quick brown fox jumps over the lazy dog";
string key = "pangram";
string cipherText = Encipher(text, key, '-');
string plainText = Decipher(cipherText, key);
								


Output

									cipherText:	"hk mra-uo oed- bosty-iwjv o-e fp z-Tcnuelgqrx h -"
plainText:	"The quick brown fox jumps over the lazy dog------"