暗号学的に安全な乱数生成方法
前の暗号による数列から、次の数列の予測が困難であること。
統計的に偏りがないこと。
暗号学的に安全な乱数でなくてもよいならば、逆にこちらを使うべきではない。
エントロピー枯渇問題があるので無闇に使うのは望ましくない。
シード値を合わせてあえて同じ乱数列を作るということができないので、そういう目的には合わない。
最も確実なのは現実世界のランダム性を利用する方法
ガイガーカウンターなど
Unix
/dev/random が暗号学的に安全な乱数のストリームとされる。
/dev/random はエントロピーが枯渇することがあり、その時には十分なエントロピーが貯まるまでブロックされてしまうため、
高頻度で使う場合には /dev/urandom を使うべきとされている。
POSIX 準拠で特定バイト幅で取り出すには、dd コマンドを使うのが簡単。バイナリ値の整形は od コマンドなどを使う。
JavaScript
PHP
通常、オクテット列(0x00~0xffの列)として取得されるが、これを期待する整数範囲にする方法はいくつか考えられる。
偏りがないようにする場合
偏りがあっても構わない場合
オクテット値が期待する範囲から外れる場合は捨てて、次のオクテット値を取得する。
最初に取得するデータ列長さの見込みが難しい。
捨ててしまうエントロピーが多く、無駄が多い
偏りはない。
除算して小数点以下を切り捨てる。
簡単。
わずかに捨ててしまうエントロピーがある。
少し偏りが発生する。
全体のビット幅を除算して余りを使う。
エントロピーの利用効率は最良
処理がとても複雑
最初に取得するデータ列長さの見込みがやや難しい。(理論的には$ log_2(範囲)\cdot文字数のビット数で良いはず)
参考