本当にランダムで確実なのは"/dev/random"ですが、きわめて遅いです。
シードに使うために最初だけとかならいいですが、何回も呼び出すと
エントロピーが貯まるまでの待ちが発生し、プログラムがその間停止します。
環境依存になりますが、その場合は"/dev/urandom"を使った方がいいでしょう。
"/dev/urandom"は真のランダムではない疑似乱数ではありますが、
暗号論的疑似乱数生成器のようです(OSのマニュアルを読むべきかも知れませんが)。
次のSecureRandom
ですが、下記のような実装になっています。(Ruby 2.2.2で確認)
- OpenSSLが使用できるなら
OpenSSL::Random
を使う。
- 1.が使えず、かつ、Windowsなら、CryptGenRandomを使う。
- 1.も2.も使えないなら、/dev/urandomを使う。
- 上全部がつかえないなら、NotImplementedErrorで例外発生。
OpenSSL::Random
についても単に呼び出すだけでなく、
現在のナノセコンドレベルのクロック時間をエントロピーに追加するなどの
初期化も勝手にしてくれます。
OpenSSLが確実にあるとは限らない環境(たとえばWindows)も想定するのであれば、
この方法が一番いいかと思います。
最後のOpenSSL::Random
はSecureRandom
と違って
エントロピーを自分で細かく追加できます。
逆に言うと使用前にエントロピーを自分で追加しない場合は
OS上のOpenSSLのバージョン依存となり、十分なエントロピーを使わない場合もあるようです。
安全性を考慮するなら、OpenSSL::Random.random_add()
などで
エントロピーを追加をしておくべきでしょう。
以上ですが、仕様書などでエントロピーの長さや実装に言及がなければ、
SecureRandom
が使いやすく、安全性も十分だと思います。
ここぞという所でのみ/dev/randomを使う(ただし、何度も呼び出しは駄目)のが
いいのではないでしょうか?