Learner
Learner

Reputation: 43

Columnar Transposition decryption algorithm in Java

Is anyone able to give the reverse/decryption algorithm for this Columnar cipher? The key length may vary, but here it is given as 4 for the encryption.

String input = "Hello World"

String output = "Hore llWdlo"

int key =4;

public static String encrypt(int key, String plainT) {

     String outString= "";

        for (int j = 0; j < key; j++) {
            for (int i = j; i < plainT.length(); i += key) {
                outString+= plainT.charAt(i);

            }
        }
        return outString;
    }

Upvotes: 0

Views: 5856

Answers (1)

M Oehm
M Oehm

Reputation: 29126

Java Strings are immutable, so you can't operate on their data. But if you could rewrite your encoding function to use an array of chars:

public static String encrypt(int key, String plainT)
{
     char[] res = new char[plainT.length()];
     int k = 0;

     for (int j = 0; j < key; j++) {
         for (int i = j; i < plainT.length(); i += key) {
             res[k++] = plainT.charAt(i);
        }
    }

    return String.copyValueOf(res);
}

Then you can easily revert the process:

public static String decrypt(int key, String encT)
{
     char[] res = new char[encT.length()];
     int k = 0;

     for (int j = 0; j < key; j++) {
         for (int i = j; i < encT.length(); i += key) {
             res[i] = encT.charAt(k++);
        }
    }

    return String.copyValueOf(res);
}

Concatenation is implemented here with an auxiliary char array and an additional index k. Reverting the process is then the same as reverting the indices. (This means that the decrypted array is not populated in order, just like the original string is not read from in order on encrypting.)

(Caveat: I'm not familiar with Java, so I hope that changing the char array and converting it to a string works as I expect and also that I haven't told any outright nonsense about Java Strings.)


Addendum You can also use your original concatenation code as base, but it will be a bit more complicated. Your column-wise encryption can be represented as:

H o r
e _ l
l W d
l o

The encrypted string is read horizontally, the decrypted original string vertically. If your string were "Hello World!", with an excamation mark, you'd have a string of length 12 and you could use your original code with a reverted key of 12 / 4 == 3.

But we actually have a variable key: 3 for the first lines and 2 for the last line.

public static String decrypt(int key, String str)
{
    String out = "";

    int skip = str.length() / key;
    int rest = str.length() % key * (skip + 1);

    for (int j = 0; j < skip; j++) {    
        int i = j;

        while (i < str.length()) {
            out += str.charAt(i);

            i += skip;
            if (i < rest) i++;
        }
    }

    for (int i = skip; i < rest; i += skip + 1) {
        out += str.charAt(i);
    }

    return out;
}

The inner loop now has a key of skip or skip + 1, depending on the region of the string. The last column (of the sketch above) is treated in a separate loop, because it looked tidier.

Upvotes: 1

Related Questions