2011-02-09 12 views
5

Chociaż jest to zadanie uniwersyteckie (praca domowa), doszedłem do najlepszego rozwiązania, jakie mogłem wymyślić. Osiągnęłabym pełne znaki z tym kodem, ponieważ pasuje to do pytania, jednak zostałem specjalnie dopuszczony do rozwijania go w C#, a nie wszyscy inni używający Java, coś w rodzaju "yeh, show what C# can do" challenge ;-)Dostrajanie wydajności C# permutacji i kodu SHA1

Pytanie:

Utwórz program, aby znaleźć hasło dla skrótu SHA1 za pomocą techniki brute force, zakładając, że hasła mają długość 6 znaków i mogą zawierać tylko małe litery ai cyfry 0-9.

Utworzyłem zapytanie LINQ i po tym, jak mam możliwe kombinacje, muszę przeprowadzić je przez SHA1, aby uzyskać skrót i porównać go z podanym hasłem hasła.

Stworzyłem ten kod:

public static string BruteForceHash(string hash) 
     { 

       var results = from c0 in Enumerable.Range(0, 36) 
           from c1 in Enumerable.Range(0, 36) 
           from c2 in Enumerable.Range(0, 36) 
           from c3 in Enumerable.Range(0, 36) 
           from c4 in Enumerable.Range(0, 36) 
           from c5 in Enumerable.Range(0, 36) 
           select new string(
            new[] 
           { 
            Characters[c0], 
            Characters[c1], 
            Characters[c2], 
            Characters[c3], 
            Characters[c4], 
            Characters[c5], 
           } 
           ); 

       string found = null; 
       Parallel.ForEach(results, (result, loopstate, a) => 
               { 
                string hashed = SHA1(result, Encoding.Default); 

                if (hashed == hash) 
                { 
                 found = result; 
                 loopstate.Break(); 
                } 
               }); 

       if (found != null) 
       { 
        return found; 
       } 

      return "Not found."; 
     } 

Teraz moim prawdziwym problemem jest to, że szybko rozwiązać prostych haseł („aaaaaa” jest natychmiastowy), ale oczywiście trwa dłużej dalszy hasło jest z dala od „aaaaaa”.

Mam nadzieję, że ktoś mógłby dostarczyć wskazówek, jak zwiększyć wydajność.

+1

Zredukuj obciążenie, to tylko o to chodzi. Mógłbyś zaprojektować implementację SHA1, która używała 6 znaków. Możesz spróbować zmniejszyć narzut GC, np. Dlaczego używasz Enumerable.Range? Dlaczego nie: 'from c1 in Characters'? Możesz także przyjrzeć się próbie: 'select (" "+ c0 + c1 + c 2) + (" "+ c3 + c4 + c5)' zamiast twoich konstruktorów opartych na tablicach. Jednak to się pokazuje, brutalna siła jest powolna. –

+2

Czy "działa na naprawdę dużym polu z dużą ilością rdzeni"? Heck, uruchom go na lazurowym gromadzie ... –

+0

@marc: LOL! :) .... –

Odpowiedz

2

Jeśli jesteś dość zadowolony z implementacji, to uruchomiłbym kod z profilerem wydajności, takim jak YourKit lub DotTrace, możesz obejrzeć gorący punkt w kodzie i sprawdzić strojenie. Czasem miło to zrobić, gdy używasz syntaktycznie słodzonego kodu, takiego jak LINQ, w ten sposób możesz poczuć to, co naprawdę dzieje się pod maską ...