Bruteforcowy generator wyrazów w PHP :)
Nudziłem się i machnąłem sobie taki skrypt co to za pomocą łopatologicznej metody generuje sobie wszelkie możliwe kombinacje z zakresu [a-zA-Z0-9]. Jakie efekty? Po pół godziny pracy (każde słowo wrzucałem do bazy danych) otrzymałem jakieś 30 mln rekordów. Całość zajmuje mi na dysku ponad 500Mb, a średni czas wykonania jakiegokolwiek zapytania 15 sekund wzwyż
Co ciekawe wszystkie wyrazy zaczynają się tylko od literki ‘a’, czyli przez ten czas nie wygenerowano ani jednej kombinacji typu ‘bxxxxx‘, gdzie x jest dowolnym znakiem alfanumerycznym.
Czy warto? Raczej nie, chociaż kiedyś dobry słownik był podstawą
. Ogólnie gdybym chciał wygenerować całość (o ile się nie mylę to liczba kombinacji to 62! * n, gdzie n to maksymalna długość) w jakiś sensowny sposób to musiałbym posiadać armię komputerów zombie i jakoś dane między nimi synchronizować.
Ogólnie całość traktuję jako ciekawostkę, kod wrzucam poniżej.
PS. proszę na to nie patrzeć pod kątem jakości kodu. Gdybym chciał mógłbym to jakoś ładniej zrobić. {geshi lang=”php”} mysql_connect('localhost', 'root', '') or die('brak polaczenia'); $znaki = "abcdefghijklmnoprstuwxyzq"; function InsertWord($pWord) { mysql_query($sql); function MkWord($pMaxDepth, $pCurrentDepth = 1, $pText = '') { for($i = 0; $i < $count; $i++) { $str = $pText.$znaki[$i]; if($pMaxDepth != $pCurrentDepth) { } } echo "Start: ".date(DATE_RFC822)."\n"; ?>
set_time_limit(0);
mysql_select_db('words');
mysql_query('TRUNCATE words');
$znaki .= "ABCDEFGHIJKLMNOPRSTUWZYXQ";
$znaki .= "1234567890";
$sql = "
INSERT INTO
words
SET
word = '{$pWord}'
";
}
global $znaki;
$count = strlen($znaki);
InsertWord($str);
MkWord($pMaxDepth,($pCurrentDepth+1), $str);
}
// no to lecimy z koksem - generujemy wszelkie mozliwe wyrazy - maks. dlugosc - 6 znakow
MkWord(6);
echo "End: ".date(DATE_RFC822)."\n";
[/sourcecode]
Kolejny PS. W ramach moich ‘testów’ generowałem wyrazy o długości 6 znaków. Oczywiście można tą długość skrócić, chociaż i tak pewnie nie ma to jako takiego znaczenia
Mylisz się (a propos liczby „kombinacji”).
Ugh, warto by to przerobić
– primo, przy każdym generowaniu masz zapytanie do mysql – zuo – secundo, algorytm brzydki – [tertio?] po co za każdym razem generować $count = strlen($znaki); ? Zapisz sobie gdzieś! Tego typu optymalizacje to podstawa
– http://dl-client.getdropbox.com/u/28596/Stuff/pinky.7z – może się przyda
tam jest wygodniejszy algorytm – Można się pokusić o „loop unrolling” tutaj, czyli zamiast pętli po długości znaków zrobić wielkiego switcha – choć nie wiem czy to przyspieszy.
hcz: to popraw mnie
groszek: wiem, że te zapytania są głupie. W sumie potem mnie olśniło, że o wiele lepszy byłby zapis do pliku
A co jest złęgo w algorytmie? Szczerze mówiąc, to było robione ciut na pałę (metodą prób i błędów). Najlepszym rozwiązaniem zdawała się właśnie rekursja.
PS, wiem że to można zoptymalizować (i wiem jak
). Zdaje się, że nawet napisałem, aby nie patrzeć na „jakość” kodu
62^n. Wariacja z powtórzeniami
Co do ilości słów to Pyetras ma rację.
A powiedz mi jeszcze, po co to gdziekolwiek zapisywać? Gdyby to był słownik (czyli coś co zawiera poprawne słowa kodowe) to ok, ale tak? Szybciej na bieżąco generować wszystkie potrzebne w danym momencie kombinacje.
@kosa: liczba słów, nie ilość
@radmen: Jeśli chcesz policzyć liczbę słów o długości nie większej niż n to będzie:
62^1 + 62^2 + 62^3 + … + 62^n
BTW: w twoich znakach brakuje „v”
Oczywiście, liczba.
Pyetrek, hcz:dziękuję za wyjaśnienia
Faktycznie brakuje ‘v’. Kosa: masz rację. Ja to bardziej robiłem jako taki eksperyment. Z resztą teoretycznie raz wygenerowany słownik, mógłby być dalej używany (choć pewnie w tej sytuacji niewiele przyspieszy).