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