明日も楽をするために

めんどくさがりなITエンジニアが書くメモ帳

PHP5.2でより良い乱数生成

PHPの乱数生成で偏りを感じるので、異なる方法での乱数生成を調べてみました。

乱数の取得にはrand()とmt_rand()があり、mt_rand()がより良い乱数を取得とドキュメントに書いてあるのですがイマイチです。

mt_rand()はmt_srand()によりシードを生成できますが、指定がない場合は自動でやってくれるみたいです。ここに問題があると思われるので、ここを別の方法でシードを生成します。


PHP5.3だとopenssl_random_pseudo_bytes()を使用して乱数を初期化する方法があるようです。

<?php
mt_srand(hexdec(bin2hex(openssl_random_pseudo_bytes(4))));

しかし私の職場環境だとPHP5.2なので、この方法は使えません(ノД`)・゜・。

そこでLinuxの疑似乱数生成器/dev/urandomを利用することにします

<?php
$file = file_get_contents('/dev/urandom', false, null, 0, 1000);
$file = base64_encode($file);
exec("echo {$file} | tr -dc 0-9 | head -c 8", $output);
mt_srand($output[0]);

これで8桁の乱数を取得できます。