Columnar Transposition Cipher - GeeksforGeeks

30 Aug, 2019
Given a plain-text message and a numeric key, cipher/de-cipher the given text using Columnar Transposition Cipher
The Columnar Transposition Cipher is a form of transposition cipher just like Rail Fence Cipher. Columnar Transposition involves writing the plaintext out in rows, and then reading the ciphertext off in columns one by one.
Examples:
Encryption
Input : Geeks for Geeks
Key = HACK
Output : e  kefGsGsrekoe_
Decryption
Input : e  kefGsGsrekoe_
Key = HACK
Output : Geeks for Geeks 

Encryption
Input :  Geeks on work
Key = HACK
Output : e w_eoo_Gs kknr_
Decryption
Input : e w_eoo_Gs kknr_
Key = HACK
Output : Geeks on work

Encryption
In a transposition cipher, the order of the alphabets is re-arranged to obtain the cipher-text.
The message is written out in rows of a fixed length, and then read out again column by column, and the columns are chosen in some scrambled order.Width of the rows and the permutation of the columns are usually defined by a keyword.For example, the word HACK is of length 4 (so the rows are of length 4), and the permutation is defined by the alphabetical order of the letters in the keyword. In this case, the order would be “3 1 2 4”.Any spare spaces are filled with nulls or left blank or placed by a character (Example: _).Finally, the message is read off in columns, in the order specified by the keyword.
The message is written out in rows of a fixed length, and then read out again column by column, and the columns are chosen in some scrambled order.
Width of the rows and the permutation of the columns are usually defined by a keyword.
For example, the word HACK is of length 4 (so the rows are of length 4), and the permutation is defined by the alphabetical order of the letters in the keyword. In this case, the order would be “3 1 2 4”.
Any spare spaces are filled with nulls or left blank or placed by a character (Example: _).
Finally, the message is read off in columns, in the order specified by the keyword.
Decryption
To decipher it, the recipient has to work out the column lengths by dividing the message length by the key length.Then, write the message out in columns again, then re-order the columns by reforming the key word.C++Python3C++// CPP program for illustrating// Columnar Transposition Cipher#include<bits/stdc++.h>using namespace std;  // Key for Columnar Transpositionstring const key = "HACK"; map<int,int> keyMap;  void setPermutationOrder(){                 // Add the permutation order into map     for(int i=0; i < key.length(); i++)    {        keyMap[key[i]] = i;    }}  // Encryption string encryptMessage(string msg){    int row,col,j;    string cipher = "";          /* calculate column of the matrix*/    col = key.length();           /* calculate Maximum row of the matrix*/    row = msg.length()/col;           if (msg.length() % col)        row += 1;      char matrix[row][col];      for (int i=0,k=0; i < row; i++)    {        for (int j=0; j<col; )        {            if(msg[k] == '\0')            {                /* Adding the padding character '_' */                matrix[i][j] = '_';                     j++;            }                          if( isalpha(msg[k]) || msg[k]==' ')            {                 /* Adding only space and alphabet into matrix*/                matrix[i][j] = msg[k];                j++;            }            k++;        }    }      for (map<int,int>::iterator ii = keyMap.begin(); ii!=keyMap.end(); ++ii)    {        j=ii->second;                  // getting cipher text from matrix column wise using permuted key        for (int i=0; i<row; i++)        {            if( isalpha(matrix[i][j]) || matrix[i][j]==' ' || matrix[i][j]=='_')                cipher += matrix[i][j];        }    }      return cipher;}  // Decryption string decryptMessage(string cipher){    /* calculate row and column for cipher Matrix */    int col = key.length();      int row = cipher.length()/col;    char cipherMat[row][col];      /* add character into matrix column wise */    for (int j=0,k=0; j<col; j++)        for (int i=0; i<row; i++)            cipherMat[i][j] = cipher[k++];      /* update the order of key for decryption */    int index = 0;    for( map<int,int>::iterator ii=keyMap.begin(); ii!=keyMap.end(); ++ii)        ii->second = index++;      /* Arrange the matrix column wise according     to permutation order by adding into new matrix */    char decCipher[row][col];    map<int,int>::iterator ii=keyMap.begin();    int k = 0;    for (int l=0,j; key[l]!='\0'; k++)    {        j = keyMap[key[l++]];        for (int i=0; i<row; i++)        {            decCipher[i][k]=cipherMat[i][j];        }    }      /* getting Message using matrix */    string msg = "";    for (int i=0; i<row; i++)    {        for(int j=0; j<col; j++)        {            if(decCipher[i][j] != '_')                msg += decCipher[i][j];        }    }    return msg;}  // Driver Programint main(void){    /* message */    string msg = "Geeks for Geeks";       setPermutationOrder();          // Calling encryption function    string cipher = encryptMessage(msg);    cout << "Encrypted Message: " << cipher << endl;          // Calling Decryption function    cout << "Decrypted Message: " << decryptMessage(cipher) << endl;      return 0;}Python3# Python3 implementation of # Columnar Transpositionimport math  key = "HACK"  # Encryptiondef encryptMessage(msg):    cipher = ""      # track key indices    k_indx = 0      msg_len = float(len(msg))    msg_lst = list(msg)    key_lst = sorted(list(key))      # calculate column of the matrix    col = len(key)          # calculate maximum row of the matrix    row = int(math.ceil(msg_len / col))      # add the padding character '_' in empty    # the empty cell of the matix     fill_null = int((row * col) - msg_len)    msg_lst.extend('_' * fill_null)      # create Matrix and insert message and     # padding characters row-wise     matrix = [msg_lst[i: i + col]               for i in range(0, len(msg_lst), col)]      # read matrix column-wise using key    for _ in range(col):        curr_idx = key.index(key_lst[k_indx])        cipher += ''.join([row[curr_idx]                           for row in matrix])        k_indx += 1      return cipher  # Decryptiondef decryptMessage(cipher):    msg = ""      # track key indices    k_indx = 0      # track msg indices    msg_indx = 0    msg_len = float(len(cipher))    msg_lst = list(cipher)      # calculate column of the matrix    col = len(key)          # calculate maximum row of the matrix    row = int(math.ceil(msg_len / col))      # convert key into list and sort     # alphabetically so we can access     # each character by its alphabetical position.    key_lst = sorted(list(key))      # create an empty matrix to     # store deciphered message    dec_cipher = []    for _ in range(row):        dec_cipher += [[None] * col]      # Arrange the matrix column wise according     # to permutation order by adding into new matrix    for _ in range(col):        curr_idx = key.index(key_lst[k_indx])          for j in range(row):            dec_cipher[j][curr_idx] = msg_lst[msg_indx]            msg_indx += 1        k_indx += 1      # convert decrypted msg matrix into a string    try:        msg = ''.join(sum(dec_cipher, []))    except TypeError:        raise TypeError("This program cannot",                        "handle repeating words.")      null_count = msg.count('_')      if null_count > 0:        return msg[: -null_count]      return msg  # Driver Codemsg = "Geeks for Geeks"  cipher = encryptMessage(msg)print("Encrypted Message: {}".               format(cipher))  print("Decryped Message: {}".       format(decryptMessage(cipher)))  # This code is contributed by Aditya KOutput:Encrypted Message: e  kefGsGsrekoe_
Decrypted Message: Geeks for Geeks
Try it yourself: A double columnar transposition( It was used by the U.S. Army in World War I, and it is just a columnar transposition followed by another columnar transposition).This article is contributed by Yasin Zafar. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.My Personal Notes
arrow_drop_upSave
To decipher it, the recipient has to work out the column lengths by dividing the message length by the key length.
Then, write the message out in columns again, then re-order the columns by reforming the key word.C++Python3C++// CPP program for illustrating// Columnar Transposition Cipher#include<bits/stdc++.h>using namespace std;  // Key for Columnar Transpositionstring const key = "HACK"; map<int,int> keyMap;  void setPermutationOrder(){                 // Add the permutation order into map     for(int i=0; i < key.length(); i++)    {        keyMap[key[i]] = i;    }}  // Encryption string encryptMessage(string msg){    int row,col,j;    string cipher = "";          /* calculate column of the matrix*/    col = key.length();           /* calculate Maximum row of the matrix*/    row = msg.length()/col;           if (msg.length() % col)        row += 1;      char matrix[row][col];      for (int i=0,k=0; i < row; i++)    {        for (int j=0; j<col; )        {            if(msg[k] == '\0')            {                /* Adding the padding character '_' */                matrix[i][j] = '_';                     j++;            }                          if( isalpha(msg[k]) || msg[k]==' ')            {                 /* Adding only space and alphabet into matrix*/                matrix[i][j] = msg[k];                j++;            }            k++;        }    }      for (map<int,int>::iterator ii = keyMap.begin(); ii!=keyMap.end(); ++ii)    {        j=ii->second;                  // getting cipher text from matrix column wise using permuted key        for (int i=0; i<row; i++)        {            if( isalpha(matrix[i][j]) || matrix[i][j]==' ' || matrix[i][j]=='_')                cipher += matrix[i][j];        }    }      return cipher;}  // Decryption string decryptMessage(string cipher){    /* calculate row and column for cipher Matrix */    int col = key.length();      int row = cipher.length()/col;    char cipherMat[row][col];      /* add character into matrix column wise */    for (int j=0,k=0; j<col; j++)        for (int i=0; i<row; i++)            cipherMat[i][j] = cipher[k++];      /* update the order of key for decryption */    int index = 0;    for( map<int,int>::iterator ii=keyMap.begin(); ii!=keyMap.end(); ++ii)        ii->second = index++;      /* Arrange the matrix column wise according     to permutation order by adding into new matrix */    char decCipher[row][col];    map<int,int>::iterator ii=keyMap.begin();    int k = 0;    for (int l=0,j; key[l]!='\0'; k++)    {        j = keyMap[key[l++]];        for (int i=0; i<row; i++)        {            decCipher[i][k]=cipherMat[i][j];        }    }      /* getting Message using matrix */    string msg = "";    for (int i=0; i<row; i++)    {        for(int j=0; j<col; j++)        {            if(decCipher[i][j] != '_')                msg += decCipher[i][j];        }    }    return msg;}  // Driver Programint main(void){    /* message */    string msg = "Geeks for Geeks";       setPermutationOrder();          // Calling encryption function    string cipher = encryptMessage(msg);    cout << "Encrypted Message: " << cipher << endl;          // Calling Decryption function    cout << "Decrypted Message: " << decryptMessage(cipher) << endl;      return 0;}Python3# Python3 implementation of # Columnar Transpositionimport math  key = "HACK"  # Encryptiondef encryptMessage(msg):    cipher = ""      # track key indices    k_indx = 0      msg_len = float(len(msg))    msg_lst = list(msg)    key_lst = sorted(list(key))      # calculate column of the matrix    col = len(key)          # calculate maximum row of the matrix    row = int(math.ceil(msg_len / col))      # add the padding character '_' in empty    # the empty cell of the matix     fill_null = int((row * col) - msg_len)    msg_lst.extend('_' * fill_null)      # create Matrix and insert message and     # padding characters row-wise     matrix = [msg_lst[i: i + col]               for i in range(0, len(msg_lst), col)]      # read matrix column-wise using key    for _ in range(col):        curr_idx = key.index(key_lst[k_indx])        cipher += ''.join([row[curr_idx]                           for row in matrix])        k_indx += 1      return cipher  # Decryptiondef decryptMessage(cipher):    msg = ""      # track key indices    k_indx = 0      # track msg indices    msg_indx = 0    msg_len = float(len(cipher))    msg_lst = list(cipher)      # calculate column of the matrix    col = len(key)          # calculate maximum row of the matrix    row = int(math.ceil(msg_len / col))      # convert key into list and sort     # alphabetically so we can access     # each character by its alphabetical position.    key_lst = sorted(list(key))      # create an empty matrix to     # store deciphered message    dec_cipher = []    for _ in range(row):        dec_cipher += [[None] * col]      # Arrange the matrix column wise according     # to permutation order by adding into new matrix    for _ in range(col):        curr_idx = key.index(key_lst[k_indx])          for j in range(row):            dec_cipher[j][curr_idx] = msg_lst[msg_indx]            msg_indx += 1        k_indx += 1      # convert decrypted msg matrix into a string    try:        msg = ''.join(sum(dec_cipher, []))    except TypeError:        raise TypeError("This program cannot",                        "handle repeating words.")      null_count = msg.count('_')      if null_count > 0:        return msg[: -null_count]      return msg  # Driver Codemsg = "Geeks for Geeks"  cipher = encryptMessage(msg)print("Encrypted Message: {}".               format(cipher))  print("Decryped Message: {}".       format(decryptMessage(cipher)))  # This code is contributed by Aditya KOutput:Encrypted Message: e  kefGsGsrekoe_
Decrypted Message: Geeks for Geeks
Try it yourself: A double columnar transposition( It was used by the U.S. Army in World War I, and it is just a columnar transposition followed by another columnar transposition).This article is contributed by Yasin Zafar. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.My Personal Notes
arrow_drop_upSave
C++
Python3
// CPP program for illustrating// Columnar Transposition Cipher#include<bits/stdc++.h>using namespace std;  // Key for Columnar Transpositionstring const key = "HACK"; map<int,int> keyMap;  void setPermutationOrder(){                 // Add the permutation order into map     for(int i=0; i < key.length(); i++)    {        keyMap[key[i]] = i;    }}  // Encryption string encryptMessage(string msg){    int row,col,j;    string cipher = "";          /* calculate column of the matrix*/    col = key.length();           /* calculate Maximum row of the matrix*/    row = msg.length()/col;           if (msg.length() % col)        row += 1;      char matrix[row][col];      for (int i=0,k=0; i < row; i++)    {        for (int j=0; j<col; )        {            if(msg[k] == '\0')            {                /* Adding the padding character '_' */                matrix[i][j] = '_';                     j++;            }                          if( isalpha(msg[k]) || msg[k]==' ')            {                 /* Adding only space and alphabet into matrix*/                matrix[i][j] = msg[k];                j++;            }            k++;        }    }      for (map<int,int>::iterator ii = keyMap.begin(); ii!=keyMap.end(); ++ii)    {        j=ii->second;                  // getting cipher text from matrix column wise using permuted key        for (int i=0; i<row; i++)        {            if( isalpha(matrix[i][j]) || matrix[i][j]==' ' || matrix[i][j]=='_')                cipher += matrix[i][j];        }    }      return cipher;}  // Decryption string decryptMessage(string cipher){    /* calculate row and column for cipher Matrix */    int col = key.length();      int row = cipher.length()/col;    char cipherMat[row][col];      /* add character into matrix column wise */    for (int j=0,k=0; j<col; j++)        for (int i=0; i<row; i++)            cipherMat[i][j] = cipher[k++];      /* update the order of key for decryption */    int index = 0;    for( map<int,int>::iterator ii=keyMap.begin(); ii!=keyMap.end(); ++ii)        ii->second = index++;      /* Arrange the matrix column wise according     to permutation order by adding into new matrix */    char decCipher[row][col];    map<int,int>::iterator ii=keyMap.begin();    int k = 0;    for (int l=0,j; key[l]!='\0'; k++)    {        j = keyMap[key[l++]];        for (int i=0; i<row; i++)        {            decCipher[i][k]=cipherMat[i][j];        }    }      /* getting Message using matrix */    string msg = "";    for (int i=0; i<row; i++)    {        for(int j=0; j<col; j++)        {            if(decCipher[i][j] != '_')                msg += decCipher[i][j];        }    }    return msg;}  // Driver Programint main(void){    /* message */    string msg = "Geeks for Geeks";       setPermutationOrder();          // Calling encryption function    string cipher = encryptMessage(msg);    cout << "Encrypted Message: " << cipher << endl;          // Calling Decryption function    cout << "Decrypted Message: " << decryptMessage(cipher) << endl;      return 0;}
# Python3 implementation of # Columnar Transpositionimport math  key = "HACK"  # Encryptiondef encryptMessage(msg):    cipher = ""      # track key indices    k_indx = 0      msg_len = float(len(msg))    msg_lst = list(msg)    key_lst = sorted(list(key))      # calculate column of the matrix    col = len(key)          # calculate maximum row of the matrix    row = int(math.ceil(msg_len / col))      # add the padding character '_' in empty    # the empty cell of the matix     fill_null = int((row * col) - msg_len)    msg_lst.extend('_' * fill_null)      # create Matrix and insert message and     # padding characters row-wise     matrix = [msg_lst[i: i + col]               for i in range(0, len(msg_lst), col)]      # read matrix column-wise using key    for _ in range(col):        curr_idx = key.index(key_lst[k_indx])        cipher += ''.join([row[curr_idx]                           for row in matrix])        k_indx += 1      return cipher  # Decryptiondef decryptMessage(cipher):    msg = ""      # track key indices    k_indx = 0      # track msg indices    msg_indx = 0    msg_len = float(len(cipher))    msg_lst = list(cipher)      # calculate column of the matrix    col = len(key)          # calculate maximum row of the matrix    row = int(math.ceil(msg_len / col))      # convert key into list and sort     # alphabetically so we can access     # each character by its alphabetical position.    key_lst = sorted(list(key))      # create an empty matrix to     # store deciphered message    dec_cipher = []    for _ in range(row):        dec_cipher += [[None] * col]      # Arrange the matrix column wise according     # to permutation order by adding into new matrix    for _ in range(col):        curr_idx = key.index(key_lst[k_indx])          for j in range(row):            dec_cipher[j][curr_idx] = msg_lst[msg_indx]            msg_indx += 1        k_indx += 1      # convert decrypted msg matrix into a string    try:        msg = ''.join(sum(dec_cipher, []))    except TypeError:        raise TypeError("This program cannot",                        "handle repeating words.")      null_count = msg.count('_')      if null_count > 0:        return msg[: -null_count]      return msg  # Driver Codemsg = "Geeks for Geeks"  cipher = encryptMessage(msg)print("Encrypted Message: {}".               format(cipher))  print("Decryped Message: {}".       format(decryptMessage(cipher)))  # This code is contributed by Aditya K
Encrypted Message: e  kefGsGsrekoe_
Decrypted Message: Geeks for Geeks

Try it yourself: A double columnar transposition( It was used by the U.S. Army in World War I, and it is just a columnar transposition followed by another columnar transposition).
This article is contributed by Yasin Zafar. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
lakshaygupta2807
AdiK
cryptography
Algorithms
cryptography
Algorithms
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
SDE SHEET - A Complete Guide for SDE Preparation
DSA Sheet by Love Babbar
Introduction to Algorithms
How to Start Learning DSA?
Recursive Practice Problems with Solutions
Difference between NP hard and NP complete problem
Converting Roman Numerals to Decimal lying between 1 to 3999
Quick Sort vs Merge Sort
Difference between Algorithm, Pseudocode and Program
Generate all permutation of a set in Python