Question

I am writing a program for a class to first encrypt a string with a predetermined key. That part is done. Next part is where i have a problem or not a problem per se. its a question of redundancy. After this I am supposed to do a KPA on the string and the encrypted string to find the key. Which is working but i am using like 15 nested for loops for the brute force. Is there another way to do this? without doing it recursively!

static String Key = null;

public static void main(String[] args) {
    long startTime = System.nanoTime();
    long startTime1 = System.currentTimeMillis();
    int cntr = 0;
    String key = "AAAAAAAAAAADDDAM";
    String plaintext = "Secretfoemotherd";
    StringBuilder cipher = new StringBuilder();
    StringBuilder brutus = new StringBuilder();


    byte[] ciphertext = encrypt(byteT(key), byteT(plaintext));
    for (int i = 0; i < ciphertext.length; i++) {
        cipher.append(ciphertext[i]);
    }

    while (true) {
        char[] nkey = new char[16];
        for (int i1 = 65; i1 < 122; i1++) {
            nkey[0] = (char) i1;
            for (int i2 = 65; i2 < 122; i2++) {
                nkey[1] = (char) i2;
                for (int i3 = 65; i3 < 122; i3++) {
                    nkey[2] = (char) i3;
                    for (int i4 = 65; i4 < 122; i4++) {
                        nkey[3] = (char) i4;
                        for (int i5 = 65; i5 < 122; i5++) {
                            nkey[4] = (char) i5;
                            for (int i6 = 65; i6 < 122; i6++) {
                                nkey[5] = (char) i6;
                                for (int i7 = 65; i7 < 122; i7++) {
                                    nkey[6] = (char) i7;
                                    for (int i8 = 65; i8 < 122; i8++) {
                                        nkey[7] = (char) i8;
                                        for (int i9 = 65; i9 < 122; i9++) {
                                            nkey[8] = (char) i9;
                                            for (int i10 = 65; i10 < 122; i10++) {
                                                nkey[9] = (char) i10;
                                                for (int i11 = 65; i11 < 122; i11++) {
                                                    nkey[10] = (char) i11;
                                                    for (int i12 = 65; i12 < 122; i12++) {
                                                        nkey[11] = (char) i12;
                                                        for (int i13 = 65; i13 < 122; i13++) {
                                                            nkey[12] = (char) i13;
                                                            for (int i14 = 65; i14 < 122; i14++) {
                                                                nkey[13] = (char) i14;
                                                                for (int i15 = 65; i15 < 122; i15++) {
                                                                    nkey[14] = (char) i15;
                                                                    for (int i16 = 65; i16 < 122; i16++) {
                                                                        nkey[15] = (char) i16;

                                                                        cntr++;

                                                                        byte[] brutusCipher = Crack(
                                                                                byteC(nkey),
                                                                                byteT(plaintext));

                                                                        for (int k = 0; k < brutusCipher.length; k++) {
                                                                            brutus.append(brutusCipher[k]);

                                                                        }

                                                                        if (brutus
                                                                                .toString()
                                                                                .equals(cipher
                                                                                        .toString())) {
                                                                            System.out
                                                                                    .println("found it");
                                                                            System.out
                                                                                    .println("Key: "
                                                                                            + Key);
                                                                            System.out
                                                                                    .println("Brutus: "
                                                                                            + brutus);
                                                                            System.out
                                                                                    .println("i ran: "
                                                                                            + cntr
                                                                                            + "times");

                                                                            long endTime = System
                                                                                    .nanoTime();
                                                                            System.out
                                                                                    .println("time:"
                                                                                            + (endTime - startTime)
                                                                                            + " ns");
                                                                            long endTime1 = System
                                                                                    .currentTimeMillis();
                                                                            System.out
                                                                                    .println("Took "
                                                                                            + (endTime1 - startTime1)
                                                                                            + " ms");
                                                                            return;
                                                                        }
                                                                        brutus.setLength(0);

                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

public static byte[] byteT(String s) {
    return s.getBytes();
}

public static byte[] byteC(char[] s) {
    StringBuilder temp = new StringBuilder();
    for (int i = 0; i < s.length; i++) {
        temp.append(s[i]);
    }
    Key = temp.toString();
    return temp.toString().getBytes();
}

public static byte[] encrypt(byte[] key, byte[] plaintext) {
    byte[] d = new byte[key.length];
    System.out.println(key.length);
    for (int i = 0; i < key.length; i++) {
        d[i] = (byte) (key[i] ^ plaintext[i]);
    }

    return d;
}

public static byte[] Crack(byte[] key, byte[] plaintext) {
    byte[] n = new byte[key.length];
    for (int i = 0; i < key.length; i++) {
        n[i] = (byte) (key[i] ^ plaintext[i]);
    }
    return n;
}

}
Was it helpful?

Solution

Here is my suggestion on how you can improve your code:

char[] nkey = new char[16];
for (int i =0 ;i<16;++i) {
  nkey[i] = 65;
}

while (true) {
  //... do the stuff you do in the inner of the cycle
  int index = 15;  
  nkey[index]++;
  while (index >= 0 && nkey[index] >= 122) {
    nkey[index] = 65;
    index--;
    if (index < 0) {
      break;
    }
    nkey[index]++;
  }
}

You can imagine what I do as representing what you iterate upon as a number in base 122-65 and adding one to it.

OTHER TIPS

You could create a class like this (not tested):

class IncrementableCharArray {

    private final char[] array;

    IncrementableCharArray(int size) {
        array = new char[size];
        Arrays.fill(array, 'A');
    }

    boolean increment() {
        //here logic to increment the array
        int index = 0;
        while(index < array.length && array[index] == 'z') index++;
        if (index == array.length) return false;
        array[index]++;
        return true;
    }

    char[] get() { return array; }

}

The performance won't be better but it will be a little bit more readable. And you can use it like this:

IncrementableCharArray array = new IncrementableCharArray(16);
while(array.increment()) {
    char[] nkey = array.get();
    //your test here
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top