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 Shared Function GetShiftIndexes(key As String) As Integer()
	Dim keyLength As Integer = key.Length
	Dim indexes As Integer() = New Integer(keyLength - 1) {}
	Dim sortedKey As New List(Of KeyValuePair(Of Integer, Char))()
	Dim i As Integer

	For i = 0 To keyLength - 1
		sortedKey.Add(New KeyValuePair(Of Integer, Char)(i, key(i)))
	Next

	sortedKey.Sort(Function(pair1 As KeyValuePair(Of Integer, Char), pair2 As KeyValuePair(Of Integer, Char)) pair1.Value.CompareTo(pair2.Value))

	For i = 0 To keyLength - 1
		indexes(sortedKey(i).Key) = i
	Next

	Return indexes
End Function

Public Shared Function Encipher(input As String, key As String, padChar As Char) As String
	input = If((input.Length Mod key.Length = 0), input, input.PadRight(input.Length - (input.Length Mod key.Length) + key.Length, padChar))
	Dim output As New StringBuilder()
	Dim totalChars As Integer = input.Length
	Dim totalColumns As Integer = key.Length
	Dim totalRows As Integer = CInt(Math.Truncate(Math.Ceiling(CDbl(totalChars) / totalColumns)))
	Dim rowChars As Char(,) = New Char(totalRows - 1, totalColumns - 1) {}
	Dim colChars As Char(,) = New Char(totalColumns - 1, totalRows - 1) {}
	Dim sortedColChars As Char(,) = New Char(totalColumns - 1, totalRows - 1) {}
	Dim currentRow As Integer, currentColumn As Integer, i As Integer, j As Integer
	Dim shiftIndexes As Integer() = GetShiftIndexes(key)

	For i = 0 To totalChars - 1
		currentRow = i \ totalColumns
		currentColumn = i Mod totalColumns
		rowChars(currentRow, currentColumn) = input(i)
	Next

	For i = 0 To totalRows - 1
		For j = 0 To totalColumns - 1
			colChars(j, i) = rowChars(i, j)
		Next
	Next

	For i = 0 To totalColumns - 1
		For j = 0 To totalRows - 1
			sortedColChars(shiftIndexes(i), j) = colChars(i, j)
		Next
	Next

	For i = 0 To totalChars - 1
		currentRow = i \ totalRows
		currentColumn = i Mod totalRows
		output.Append(sortedColChars(currentRow, currentColumn))
	Next

	Return output.ToString()
End Function

Public Shared Function Decipher(input As String, key As String) As String
	Dim output As New StringBuilder()
	Dim totalChars As Integer = input.Length
	Dim totalColumns As Integer = CInt(Math.Truncate(Math.Ceiling(CDbl(totalChars) / key.Length)))
	Dim totalRows As Integer = key.Length
	Dim rowChars As Char(,) = New Char(totalRows - 1, totalColumns - 1) {}
	Dim colChars As Char(,) = New Char(totalColumns - 1, totalRows - 1) {}
	Dim unsortedColChars As Char(,) = New Char(totalColumns - 1, totalRows - 1) {}
	Dim currentRow As Integer, currentColumn As Integer, i As Integer, j As Integer
	Dim shiftIndexes As Integer() = GetShiftIndexes(key)

	For i = 0 To totalChars - 1
		currentRow = i \ totalColumns
		currentColumn = i Mod totalColumns
		rowChars(currentRow, currentColumn) = input(i)
	Next

	For i = 0 To totalRows - 1
		For j = 0 To totalColumns - 1
			colChars(j, i) = rowChars(i, j)
		Next
	Next

	For i = 0 To totalColumns - 1
		For j = 0 To totalRows - 1
			unsortedColChars(i, j) = colChars(i, shiftIndexes(j))
		Next
	Next

	For i = 0 To totalChars - 1
		currentRow = i \ totalRows
		currentColumn = i Mod totalRows
		output.Append(unsortedColChars(currentRow, currentColumn))
	Next

	Return output.ToString()
End Function
								


Example

									Dim text As String = "The quick brown fox jumps over the lazy dog"
Dim key As String = "pangram"
Dim cipherText As String = Encipher(text, key, "-"c)
Dim plainText As String = 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------"