Cryptography - Columnar Transposition



One type of transposition cipher that represents plaintext in matrix form is called the Columnar Transposition Cipher. Writing the plaintext out in rows and reading the ciphertext out one column at a time is known as columnar transposition. In this tutorial, we have described the columnar transposition cipher's encryption and decryption methods. Probably the most researched transposition cipher is columnar transposition.

Columnar Transposition

How it Works?

The message is structured as a 2-dimensional array. The length of the message determines how many rows and columns there will be. If the message is 30 characters long (including spaces), there is a 50% chance that there will be 15 rows and 2 columns, 10 rows, 3 rows, 5 rows, or 6 rows.

Keep in mind that we have to append a dummy letter at the end of the message if its length exceeds 29.

Encryption

See the encryption process of Columnar transposition cipher below −

  • First, the plaintext is written in the rows that are defined in advance, with the key determining the length.
  • The order in which the plaintext's columns are transposed can be determined using the key.
  • The ciphertext is then created by reading the transposed plaintext column by column.

Decryption

So the decryption process of the columnar transposition cipher is as follows −

  • Using the same key that was used for encryption, the ciphertext is first transposed by columns.
  • The plaintext can be retrieved by reading the transposed ciphertext row by row.

Example of Columnar Transposition

If the message says, "The attack will start on Monday," so as we can see that it is 28 characters long. However, if we add the dummy letters "x" and "x" at the end, the message will be 30 characters long. We can figure out 30 = 10 X 3 and In the case that (2,3,1) is the key, the columns are arranged as follows −

The Plaintext: "the attack will start on Monday"

Columnar Transposition Example

The Ciphertext − "HAA LSROMDXETCWLTTNOAXT TKI A NY" is the Ciphertext, which is calculated from the reading on the table by columns. We rearrange the letters of a keyword, like "TWO," in an alphabetical order to make the key easier to recall. Thus, the array columns will be rearranged using the key (2,3,1).

Key Features

The key features for Columnar Transposition cipher is as follows −

  • One kind of transposition cipher is the columnar cipher, which requires rearranging the plaintext into columns before encryption.
  • Since the key is symmetric, it can be used for both encryption and decryption.
  • The columnar transposition cipher allows for a variable key size. The key comprises of a permutation of the integers 1 to N, where N is the plaintext's length.
  • Cryptanalysis can break a columnar transposition cipher, particularly when the plaintext has repetitive patterns or the key is short.

Use Cases of Columnar Transposition Cipher

  • Applications for columnar transposition cipher are many like data protection, military communications, and espionage.
  • It works particularly well for situations when the plaintext includes long, repetitive patterns, like binary data or DNA sequences.
  • To increase the security of the encrypted data, columnar transposition ciphers can also be used when combined with other encryption techniques, like substitution ciphers.

Implementation

Now we will implement the Columnar Transposition Cipher using Python, Java, C++ and Javascript.

Implement using Python

The code will demonstrate how to encrypt a plaintext message and then decrypt the ciphertext back to plaintext using the Columnar Transposition Cipher in Python programming language.

Example

def columnar_encrypt(plaintext, keyword):
   matrix = create_encryption_matrix(len(keyword), plaintext)
   keyword_sequence = get_keyword_sequence(keyword)

   ciphertext = ""
   for num in range(len(keyword_sequence)):
      pos = keyword_sequence.index(num + 1)
      for row in range(len(matrix)):
         if len(matrix[row]) > pos:
            ciphertext += matrix[row][pos]
   return ciphertext

def create_encryption_matrix(width, plaintext):
   r = 0
   c = 0
   matrix = [[]]
   for pos, ch in enumerate(plaintext):
      matrix[r].append(ch)
      c += 1
      if c >= width:
         c = 0
         r += 1
         matrix.append([])

   return matrix

def get_keyword_sequence(keyword):
   sequence = []
   for pos, ch in enumerate(keyword):
      previous_letters = keyword[:pos]
      new_number = 1
      for previous_pos, previous_ch in enumerate(previous_letters):
         if previous_ch > ch:
            sequence[previous_pos] += 1
         else:
            new_number += 1
      sequence.append(new_number)
   return sequence

def columnar_decrypt(ciphertext, keyword):
   matrix = create_encryption_matrix(len(keyword), ciphertext)
   keyword_sequence = get_keyword_sequence(keyword)

   plaintext = ""
   index = 0
   for num in range(len(keyword_sequence)):
      pos = keyword_sequence.index(num + 1)
      for row in range(len(matrix)):
         if len(matrix[row]) > pos:
            matrix[row][pos] = ciphertext[index]
            index += 1

   for row in range(len(matrix)):
      for col in range(len(matrix[row])):
         plaintext += matrix[row][col]

   return plaintext

# Execution of the functions
plaintext = "Tutorialspoint is best"
keyword = "railfence"
ciphertext = columnar_encrypt(plaintext, keyword)
print("The Encrypted Text:", ciphertext)
decrypted_text = columnar_decrypt(ciphertext, keyword)
print("The Decrypted Text:", decrypted_text)

Following is the output of the above example −

Input/Output
The Encrypted Text: uoelsi s rttisontaiTpb
The Decrypted Text: Tutorialspoint is best

Implement using Java

So now we will implement the Columnar transposition cipher using Java programming language. And we will use util package of java which is used to import the Map interface and the HashMap class. So the code is as follows −

Example

import java.util.*;

public class ColumnarCipher {
   // Define the Key 
   static final String encryptionKey = "BEST";
   static Map<Character, Integer> keyMap = new HashMap<>();

   static void setPermutationOrder() {
      // Add the permutation order into the map
      for (int i = 0; i < encryptionKey.length(); i++) {
         keyMap.put(encryptionKey.charAt(i), i);
      }
   }

   // Encryption Function
   static String encrypt(String plaintext) {
   int rows, columns;
   StringBuilder ciphertext = new StringBuilder();

   // Number of columns in the matrix
   columns = encryptionKey.length();

   // Maximum number of rows in the matrix 
   rows = (int) Math.ceil((double) plaintext.length() / columns);

   char[][] matrix = new char[rows][columns];

   for (int i = 0, k = 0; i < rows; i++) {
      for (int j = 0; j < columns; ) {
         if (k < plaintext.length()) {
            char ch = plaintext.charAt(k);
            if (Character.isLetter(ch) || ch == ' ') {
            matrix[i][j] = ch;
            j++;
            }
            k++;
         } else {
            /* Add padding character '_' */
            matrix[i][j] = '_';
            j++;
         }
      }
   }

      for (Map.Entry<Character, Integer> entry : keyMap.entrySet()) {
         int columnIndex = entry.getValue();

         // Get the cipher text 
         for (int i = 0; i < rows; i++) {
            if (Character.isLetter(matrix[i][columnIndex]) || matrix[i][columnIndex] == ' ' || matrix[i][columnIndex] == '_') {
               ciphertext.append(matrix[i][columnIndex]);
            }
         }
      }
      return ciphertext.toString();
   }

   // Decryption Function
   static String decrypt(String ciphertext) {
      int columns = encryptionKey.length();

      int rows = (int) Math.ceil((double) ciphertext.length() / columns);
      char[][] cipherMat = new char[rows][columns];

      // Add characters into the matrix column-wise 
      int k = 0;
      for (int j = 0; j < columns; j++) {
         for (int i = 0; i < rows; i++) {
            if (k < ciphertext.length()) {
               cipherMat[i][j] = ciphertext.charAt(k);
               k++;
            } else {
               cipherMat[i][j] = '_'; 
            }
         }
      }

      // Update the order of the key 
      int index = 0;
      for (Map.Entry<Character, Integer> entry : keyMap.entrySet()) {
         entry.setValue(index++);
      }

      char[][] decCipher = new char[rows][columns];
      for (int l = 0; l < encryptionKey.length(); l++) {
         int columnIndex = keyMap.get(encryptionKey.charAt(l));
         for (int i = 0; i < rows; i++) {
            decCipher[i][l] = cipherMat[i][columnIndex];
         }
      }

      // Get the message with the help of the matrix
      StringBuilder msg = new StringBuilder();
      for (int i = 0; i < rows; i++) {
         for (int j = 0; j < columns; j++) {
            if (decCipher[i][j] != '_') {
               msg.append(decCipher[i][j]);
            }
         }
      }
      return msg.toString();
   }


   public static void main(String[] args) {
      /* Plain text message */
      String plaintext = "This is a secret message.";

      setPermutationOrder();

      // Call the encryption function
      String ciphertext = encrypt(plaintext);
      System.out.println("The Encrypted Message: " + ciphertext);

      // Call the Decryption function
      System.out.println("The Decrypted Message: " + decrypt(ciphertext));
   }
}

Following is the output of the above example −

Input/Output
The Encrypted Message: T ac s_isseeg_s etse_hi rma_
The Decrypted Message: This is a secret message

Implement using C++

Now we will use the same concept and implement the code in C++ for Columnar transposition cipher. So check the code below −

Example

#include<bits/stdc++.h>
using namespace std;

// Encryption key
string const encryptionKey = "BEST"; 
map<int,int> keyMap;

// Set the permutation order 
void setPermutationOrder() {			 
	// Add the permutation order into map 
	for(int i=0; i < encryptionKey.length(); i++) {
		keyMap[encryptionKey[i]] = i;
	}
}

// Encryption function
string encrypt(string plaintext) {
	int numRows, numCols, j;
	string ciphertext = "";
	
    // Calculate the number of columns in the matrix
	numCols = encryptionKey.length(); 
	
	// Calculate the maximum number of rows in the matrix 
	numRows = plaintext.length() / numCols; 
	
	if (plaintext.length() % numCols)
		numRows += 1;

	char matrix[numRows][numCols];

	for (int i=0, k=0; i < numRows; i++){
		for (int j=0; j < numCols; ){
			if(plaintext[k] == '\0'){
				// Add the padding character
				matrix[i][j] = '_';	 
				j++;
			}
			
			if(isalpha(plaintext[k]) || plaintext[k] == ' '){ 
				// Add only spaces and alphabets
				matrix[i][j] = plaintext[k];
				j++;
			}
			k++;
		}
	}

	for (map<int,int>::iterator it = keyMap.begin(); it != keyMap.end(); ++it){
		j = it->second;
		
		for (int i = 0; i < numRows; i++){
         if(isalpha(matrix[i][j]) || matrix[i][j] == ' ' || matrix[i][j] == '_')
            ciphertext += matrix[i][j];
		}
	}
	return ciphertext;
}

// Decryption function
string decrypt(string ciphertext){
	// Calculate the row and column 
	int numCols = encryptionKey.length();

	int numRows = ciphertext.length() / numCols;
	char cipherMat[numRows][numCols];

    // Add characters into the matrix column-wise
	for (int j = 0, k = 0; j < numCols; j++)
		for (int i = 0; i < numRows; i++)
			cipherMat[i][j] = ciphertext[k++];

	// Update the order of the key 
	int index = 0;
	for(map<int,int>::iterator it = keyMap.begin(); it != keyMap.end(); ++it)
		it->second = index++;

	// Arrange the matrix column-wise 
	char decCipher[numRows][numCols];
	map<int,int>::iterator it = keyMap.begin();
	int k = 0;
	for(int l = 0, j; encryptionKey[l] != '\0'; k++){
		j = keyMap[encryptionKey[l++]];
		for(int i = 0; i < numRows; i++){
			decCipher[i][k] = cipherMat[i][j];
		}
	}

	// Get the plaintext message 
	string plaintext = "";
	for(int i = 0; i < numRows; i++){
		for(int j = 0; j < numCols; j++){
			if(decCipher[i][j] != '_')
				plaintext += decCipher[i][j];
		}
	}
	return plaintext;
}

// Driver program
int main(void){
   string plaintext = "I am using Tutorialspoint"; 

   setPermutationOrder();
   string ciphertext = encrypt(plaintext);
   cout << "The Encrypted Message: " << ciphertext << endl;
   cout << "The Decrypted Message: " << decrypt(ciphertext) << endl;

   return 0;
}

Following is the output of the above example −

Input/Output

The Encrypted Message: I nuipt ugtao_as oli_miTrsn_
The Decrypted Message: I am using Tutorialspoint

Security of Columnar Transposition

Up to the early half of the 20th century, Columnar Transposition was being used widely over the whole world.

An attacker should attempt to make tables of various sizes, enter the encrypted message into the columns, and search each table for anagrams that exist in rows in order to decipher the ciphertext.

Advantages

Like any encryption method, the Columnar Transposition Cipher also has its own set of advantages.

  • The Columnar Transposition Cipher gives a basic level of safety by rearranging the order of characters in the given plaintext. This property makes it hard to unauthorized users for deciphering without the knowledge of key.
  • It is very easy to implement the Columnar Transposition Cipher algorithm because it need minimal resources.
  • It supports many key lengths means it allows users to customize the level of security as per their specific needs.
  • Unlike other substitution ciphers, the Columnar Transposition Cipher is not preserve the frequency of characters which makes it strong to frequency analysis attacks.

Disadvantages

Despite having advantages the Columnar Transposition Cipher also has some disadvantages −

  • Columnar Transposition Cipher provides basic security but is vulnerable to brute force attacks, especially in limited or weakly selected key spaces.
  • Proper management is critical to that protection, but it is difficult, especially in large systems.
  • A known plaintext attack can compromise cipher security by revealing the details of the encryption key.
  • Despite its suitability for basic encryption needs, the cipher cannot withstand determined adversaries or advanced cryptanalysis techniques.
  • Furthermore, its performance decreases with large explicit texts, especially when using manual saving methods due to the complexity of matrix creation and transformation.

Conclusion

So a columnar transposition cipher is a kind of transposition cipher in which the plaintext is rearranged by columns before encryption. It is a commonly used encryption technique that is easy to use and effective for a variety of purposes, like data protection and military communications. It can be used in combination with other encryption techniques to increase the security of the encrypted data, while being vulnerable to cryptanalysis. So it is critical to use the columnar transposition cipher selectively and to put the right precautions in place to reduce its vulnerabilities.

Advertisements