自然とランダム
2007.05.16
今回は「ランダム」についての話でもしましょうか。
デジタル技術というものは決定論的です。デジタル技術がその根底に置くアナログ変量自体は、細かく見ていけば本質的にランダムな揺らぎを持つものなのでしょうが、そういうランダムな揺らぎを封じ込めて、たとえば「+3V以上は 1」という具合に、「決めて」しまうことでデジタル技術というものが成立しているわけです。
ですからそういう「決めて」しまうような、「抽象化」の上に成立するデジタル技術というものは、本質的に決定論的でないことはありえません。一般によく使われる線形合同法による乱数アルゴリズム(rand() で実装されるタイプのもの)は、「一見乱数みたいに」見えることだけを目的にしています。ですから、たとえばモンテカルロ法のような「乱数の品質によって値が異なる」アルゴリズムですと、足を掬われる結果が出る可能性もありますし、セキュリティが重要なケースでは「今出た乱数の値から次に出る乱数の値を推測する」ことが、アルゴリズムがバレている場合に不可能である、とは言えません。要するに rand() は本当の乱数を生成するのではなくて、「一見乱数に見える」数、「擬似乱数」を生成するのです。
私はそういえば心理学科の出ですから、学校時代「乱数表の使い方」とか手ほどきを受けてたりします(昔話ですね)。探すと今でもネット上に一様乱数表があったりします。勿論こういう乱数表の元はJISで決まっている乱数表の一部を載せているだけなのですから、より大きい乱数表をネタにして乱数を生成する...というのも「擬似乱数ではない」本当の乱数を得る手の一つです。
とはいえ、こういう乱数表に頼るのは現状ではあまり一般的な手段ではないでしょう。たとえば Tomcat でセッションキーを得るのに使う、Java の java.secure.SecurityRandom クラスでは、別なやり方をしていたりします。
これは Linux などの UNIX 系での JVM のやり方ですが、もし、 /dev/random(など) があれば、そこからランダムシードを得て乱数を生成します。このデバイスファイルとして実装された /dev/random と /dev/urandom です。
この2つは、ランダムジェネレータの仮想デバイスです。両者の違いは読み込み時にブロックするかどうかで、Java1.4まではブロックする /dev/random がデフォルトで $JAVA_HOME/jre/lib/security/java.security で securerandom.source プロパティに書かれていましたが、Java5からはブロックしない /dev/urandom に変更されています。
このランダムジェネレータは結構面白いものなのです。セキュリティツールをインストールする際など、「キーボードを叩き続けなさい」という指示が出て、適当にキーボードを叩く、ということをしますが、これは /dev/random を使うやり方なのですね。
というのは、「コンピュータの内部ではなくて、コンピュータの外側」にランダムの源を得る、というのがこの「キーボードを叩く」という儀式なのです。言い換えると、「人間がすること」であるキーボード入力の間隔から、こういうランダムの種を仕入れてくるわけです。
人間の行為は観念ではなくてアナログな自然現象です。だからこそ「ランダムの種」になりうるわけなのです。とはいえ、コンピュータの内部にだって、本当は自然現象があるのです。今の /dev/random は条件が合えばそういうコンピュータ内部の「自然」をランダムネスの供給源できる場合があったりします。
それはCPUの熱雑音だったりするわけです。CPU によってはそういう熱雑音を利用するハードウェア乱数生成器を持っていたりします。で、こういうハードウェア乱数生成器に対するドライバがもうすでに Linux などは備えているわけです(まあ、そういうCPUを使っていれば...ですが)。
何か「コンピュータと自然」というような深いテーマですね。面白くなって調べてしまいました!
投稿者 : 杉浦 こずえ | 投稿日時 : 2007.05.16 15:52
あすなろBLOGのトラックバック・コメントは承認制になっています。
すぐにブログに反映されませんので、ご了承ください。





