数字6桁パスワードのハッシュ値の総当たり、Perlでも約0.25秒で終わるよ
タイトルウソです。もっとかかりましたすみません。
徳丸浩の雑記帳: 数字6桁パスワードのハッシュ値の総当たり、PHPなら約0.25秒で終わるよ
を読んで、Perlでも実装してみた。
まあPHPとほとんど変わらないんですけれども。
今回はマルチプロセスの復習がてら実装。
環境
# OS FreeBSD 9.1-RELEASE-p9 amd64 # CPU Intel Xeon E312xx (Sandy Bridge) # Perl 5.8.9
さくらのスタンダードプランです。はい。
コード
#!/usr/bin/perl use common::sense; use Getopt::Long; use Digest::MD5 qw/md5_hex/; use Parallel::ForkManager; use Time::HiRes qw/time/; GetOptions( 's|salt=s' => \my $salt, 'hs|hash=s' => \my $hash, 'p|process=i' => \my $process, 'verbose' => \my $verbose, ); my $max_num = 1000000; $process ||= 2; my $start_time = time; main(); my $exec_time = time - $start_time; print 'TOTAL_EXEC_TIME: ' . $exec_time . "\n"; exit; sub main { my $current = 0; my $pm = Parallel::ForkManager->new( $process ); do { warn sprintf("parallel: %s process\n", $process); $pm->run_on_start( sub { my ($pid, $ident) = @_; warn sprintf("%s starts\n", $ident); } ); $pm->run_on_finish( sub { my ($pid, $exit_code, $ident, $exit_signal, $core_dump, $data) = @_; $current++; warn sprintf("%s completes.(%d/%d)\n", $ident, $current, $process); warn sprintf(" sec : %s\n", $$data) if defined $data;# must Parallel::ForkManager over v0.7.6 } ); } if $verbose; for (my $start = 0; $start < $process; $start++) { $pm->start($start) and next;# parent go next my $child_start_time = time; _search_hash($start, $process); my $child_exec_time = time - $child_start_time; $pm->finish(0, \$child_exec_time); } $pm->wait_all_children; return undef; } sub _search_hash { my ($start, $step) = @_; for ( my $i = $start; $i < $max_num; $i += $step) { my $pass = sprintf("%06d", $i); next if md5_hex($salt . '$' . $pass) ne $hash; # match my $time = time - $start_time; print sprintf("Solved: %s %s\n", $pass, $time); } return undef; } 1;
Parallel::ForkManager 使って並行ダウンローダ作った - 理系学生日記
のコードを丸コピ…。
実行
[sv] $ perl ./jal.pl -p 4 -s hoge -hs 4b364677946ccf79f841114e73ccaf4f -v parallel: 4 process 0 starts 1 starts 2 starts 3 starts Solved: 567890 0.186630010604858 2 completes.(1/4) sec : 0.386913061141968 1 completes.(2/4) sec : 0.523470878601074 3 completes.(3/4) sec : 0.457498073577881 0 completes.(4/4) sec : 0.597269058227539 TOTAL_EXEC_TIME: 0.604266166687012
ぐはっ、思ったよりかかるな…共用サーバだから仕方ないか。
同じサーバで徳丸先生のコードを実行してみる。
おんなじぐらいか、Perlのがちょい遅いぐらいか。
同じようなコードの書き方でやったら同じぐらいになるかな?
という感じでした。
6桁の数字なら
パスワード忘れたよ!>キューに入れる>ワーカーが総当り>メールでパスワードを送信(この間わずか1秒)
が可能ですね!