Search code examples
javaencryptiontranspose

Java CIpher Columnar Transposition


I am not having a good time decrypting the encrypted txt.

public class Practica2 {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("Enter a text: ");
        String txt = input.nextLine();
        System.out.println("Enter a num of columns: ");
        int num = input.nextInt();
        String cipher = cipherTrans(txt, num);
        System.out.println("Coded: " + cipher);
        String decipher = decipherTrans(cipher, num);
        System.out.println("Decoded: " + decipher);
    }

    //This method encrypts
    private static String cipherTrans(String txt, int num) {
        String output = "";
        //takes the length of the string and divides by the num of columns
        int num2 = (int) Math.ceil(txt.length()*1.0/num);
        //2d array 
        char[][] buffer = new char[num2][num];
        int k = 0;
        //loop which will store and rearrange the letter of the txt 
        for (int i = 0; i < num2; i++) {
            for (int j = 0; j < num; j++, k++) {
                if (txt.length() > k) {
                    buffer[i][j] = txt.charAt(k);
                }
            }
        }
    
        //loop which will store the rearrenged txt and output the encrypted txt
        for (int j = 0; j < num; j++) {
            for (int i = 0; i < num2; i++) {
                output += buffer[i][j];
            }
        }
        return output;
    }

    //this method will decrypt the encrypted txt
    private static String decipherTrans(String txt, int num) {
        String output = "";
        int num2 = (int) Math.ceil(txt.length() * 1.0 / num);
        char[][] buffer = new char[num2][num];
        int k = 0;
        for (int i = 0; i < num2; i++) {
            for (int j = 0; j < num; j++, k++) {
                if (txt.length() > k) {
                    buffer[i][j] = txt.charAt(k);
                }
            }
        }
        for (int i = 0; i < num; i++){
            for (int j = 0; j < num2; j++){
                txt += buffer[j][i];
            }
        }
        return output;
    }
}

CURRENT OUTPUT:

Enter a text: 

my name is dani

Enter a num of columns: 

5

Coded: mm yed  aninasi

Decoded: mdim n  ayaseni

EXPECTED OUTPUT:

Enter a text: 

my name is dani

Enter a num of columns: 

5

Coded: mm yed  aninasi

Decoded: my name is dani

Solution

  • The transposition table

    This is your ciphertext: mm yed aninasi; key length is 5.

    The transposition table for your particular case looks like this:

    char[][] buffer = {
        {'m', 'y', ' ', 'n', 'a'},
        {'m', 'e', ' ', 'i', 's'},
        {' ', 'd', 'a', 'n', 'i'}
    };
    

    How to generate the transposition table?

    "... the recipient has to work out the column lengths by dividing the message [ciphertext] length by the key length. Then they can write the message out in columns again, ..."

    From: https://en.wikipedia.org/wiki/Transposition_cipher#Columnar_transposition

    How to decipher the message?

    Once you have generated the transposition table, simply read it row by row, from left to right.

    Solution

    The working decipher method, based on your code, could look like this:

    private static String decipherTrans(String txt, int num) {
        int num2 = (int) Math.ceil(txt.length() * 1.0 / num);
    
        char[][] buffer = new char[num2][num];
        int k = 0;
        for (int i = 0; i < num; i++) {
            for (int j = 0; j < num2; j++, k++) {
                if (txt.length() > k) {
                    buffer[j][i] = txt.charAt(k);
                }
            }
        }
    
        String output = "";
        for (int i = 0; i < num2; i++){
            for (int j = 0; j < num; j++){
                output += buffer[i][j];
            }
        }
        return output;
    }
    

    You just have to have a clear idea of what you are doing to use the array indices correctly.