Cifrado de transposición columnar

Dado un mensaje de texto sin formato y una clave numérica, cifrar/descifrar el texto dado utilizando Cifrado de transposición en columnas

El Cifrado de Transposición en Columnas es una forma de cifrado de transposición al igual que el Cifrado de Valla de Ferrocarril . La transposición en columnas implica escribir el texto sin formato en filas y luego leer el texto cifrado en columnas una por una.

Ejemplos:

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

Cifrado

En un cifrado por transposición, el orden de los alfabetos se reorganiza para obtener el texto cifrado.

  1. El mensaje se escribe en filas de una longitud fija y luego se vuelve a leer columna por columna, y las columnas se eligen en algún orden codificado.
  2. El ancho de las filas y la permutación de las columnas generalmente se definen mediante una palabra clave.
  3. Por ejemplo, la palabra HACK tiene una longitud de 4 (por lo que las filas tienen una longitud de 4) y la permutación se define por el orden alfabético de las letras en la palabra clave. En este caso, el orden sería “3 1 2 4”.
  4. Los espacios libres se rellenan con nulos, se dejan en blanco o se colocan con un carácter (Ejemplo: _).
  5. Finalmente, el mensaje se lee en columnas, en el orden especificado por la palabra clave.

columnar-transposition-cipher

Descifrado

  1. Para descifrarlo, el destinatario tiene que calcular la longitud de las columnas dividiendo la longitud del mensaje por la longitud de la clave.
  2. Luego, escriba el mensaje en columnas nuevamente, luego reordene las columnas reformando la palabra clave.
  3. C++

    // CPP program for illustrating
    // Columnar Transposition Cipher
    #include<bits/stdc++.h>
    using namespace std;
      
    // Key for Columnar Transposition
    string 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 Program
    int 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 Transposition
    import math
      
    key = "HACK"
      
    # Encryption
    def 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
      
    # Decryption
    def 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 Code
    msg = "Geeks for Geeks"
      
    cipher = encryptMessage(msg)
    print("Encrypted Message: {}".
                   format(cipher))
      
    print("Decryped Message: {}".
           format(decryptMessage(cipher)))
      
    # This code is contributed by Aditya K

    Producción:

    Encrypted Message: e  kefGsGsrekoe_
    Decrypted Message: Geeks for Geeks
    

    Pruébelo usted mismo: una transposición de columna doble (fue utilizada por el ejército de los EE. UU. en la Primera Guerra Mundial, y es solo una transposición de columna seguida de otra transposición de columna).

    Este artículo es una contribución de Yasin Zafar . Si le gusta GeeksforGeeks y le gustaría contribuir, también puede escribir un artículo usando contribuya.geeksforgeeks.org o envíe su artículo por correo a contribuya@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.

    Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *