2013-06-12 17 views
6

Sto scrivendo un programma per una classe per crittografare prima una stringa con una chiave predeterminata. Quella parte è fatta. La prossima parte è dove ho un problema o non un problema di per sé. è una questione di ridondanza. Dopo questo dovrei fare un KPA sulla stringa e la stringa crittografata per trovare la chiave. Che funziona, ma sto usando 15 loop nidificati per la forza bruta. c'è un altro modo per fare ciò? senza farlo in modo ricorsivo!Crittografia propria della forza bruta in Java

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; 
} 

} 
+4

che è di gran lunga la struttura più annidata loop che ho visto :) –

+1

Yeeeeeah ecco perché im qui :) – Becktor

risposta

4

Ecco il mio suggerimento su come è possibile migliorare il tuo codice:

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]++; 
    } 
} 

Potete immaginare quello che faccio come rappresentare quello di eseguire iterazioni su un numero in base di 122-65 e aggiungendo uno ad esso.

+1

funziona impressionante come un fascino! grazie mille! – Becktor

1

si potrebbe creare una classe come questa (non testato):

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; } 

} 

la prestazione non sarà migliore, ma sarà un po 'più leggibile. E si può usare in questo modo:

IncrementableCharArray array = new IncrementableCharArray(16); 
while(array.increment()) { 
    char[] nkey = array.get(); 
    //your test here 
} 
+0

Nota: il metodo di incremento non funziona così com'è, ma si ottiene l'idea. – assylias

+1

Sì, grazie per la tua risposta! – Becktor

Problemi correlati