2013-06-12 13 views
6

Piszę program dla klasy, aby najpierw szyfrować ciąg z ustalonym kluczem. Ta część jest zrobiona. Następna część to miejsce, w którym mam problem lub nie mam problemu jako takiego. to kwestia zwolnień. Po tym mam zrobić KPA na łańcuchu i zaszyfrowanym ciągu, aby znaleźć klucz. Który działa, ale używam jak 15 zagnieżdżonych dla pętli dla brutalnej siły. Czy jest inny sposób na zrobienie tego? bez robienia tego rekurencyjnie!Brute wymusza własne szyfrowanie w Javie

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

że jest zdecydowanie najbardziej zagnieżdżonej strukturze pętli widziałem :) –

+1

Yeeeeeah to dlaczego im tutaj :) – Becktor

Odpowiedz

4

Oto moja propozycja w jaki sposób można poprawić swój kod:

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

Można sobie wyobrazić, co robię jako reprezentujący co iteracyjne na jak numer w bazie 122-65 i dodając jeden do niego.

+1

Niesamowite prace podobny pewien urok! dzięki, buch! – Becktor

1

Można by utworzyć klasę tak (nie sprawdzone)

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

} 

Spektakl nie będzie lepiej, ale będzie to trochę bardziej czytelne. I można go używać tak:

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

Uwaga: metoda inkrementacji nie działa tak jak jest, ale masz pomysł. – assylias

+1

Tak, dziękuję za odpowiedź! – Becktor