この記事では主にPHPの擬似乱数と真の乱数の詳細な説明を紹介します この記事ではまず、真の乱数と擬似の関連する概念について説明します。 -乱数、および mt_rand() 関数を使用するよりも優れた疑似乱数を生成するコード例を示します。必要な方は参照してください。
最初に述べておく必要があるのは、コンピュータは完全な乱数を生成することはできず、「疑似乱数」しか生成できないということです。実際、絶対乱数は理想的な乱数にすぎません。コンピュータがどのように発達しても、完全に乱数の列は生成されません。コンピューターは比較的ランダムな数、つまり擬似乱数しか生成できません。擬似乱数は擬似乱数ではない、ここで言う「擬似」とは規則的という意味で、コンピューターが生成する擬似乱数はランダムであり規則的であるという意味です。生成された擬似乱数は、特定のルールに従う場合もあれば、まったく従わない場合もあります。また、一部の疑似乱数は、ルールに従わない場合もあります。例えば、「世界に同じ形の葉は二つとない」ということは、物事の性質、つまりランダム性を指しますが、どの木の葉も同じような形をしている、つまり物事の共通性を指します。 、規則性。この観点から見ると、コンピュータは疑似乱数しか生成できず、完全な乱数を生成することはできないという事実をおそらく受け入れるでしょう。
まず、真の乱数と擬似乱数の概念を理解しましょう。
真性乱数発生器: 英語: true Random Number Generator、略称: TRNG は、予測不可能な物理的方法によって生成される乱数です。
擬似乱数発生器: 英語: pseudo-random number generateder、略称: PRNG は、コンピューターによって特定のアルゴリズムを使用して生成されます。
2つの方法で生成された乱数の写真を比較してください。
Random.org によって生成されたランダム ビットマップ (大気中の雷雨によって生成される大気ノイズを使用して乱数を生成します):
PHP の rand ランダム関数を使用してこの画像を生成するコードは次のとおりです:
コードは以下の通りです:
//gdライブラリを開く必要があります
header("Content-type: image/png");
$im = imagecreatetruecolor(512, 512)
または die("新しい GD イメージ ストリームを初期化できません");
$white = imagecolorallocate($im, 255, 255, 255);
for ($y=0; $y for ($x=0; $x if (rand(0,1) === 1) {
imagesetpixel($im, $x, $y, $white);
}
}
}
imagepng($im);
imagedestroy($im);
実際には、すべての擬似乱数生成器 (PRNG) がそれほど悪いわけではなく、Windows 上の PHP の rand() 関数がたまたまこのようになっただけです。同じコードを Linux でテストすると、結果の画像には明らかな縞模様が表示されません。 Windows では、rand() 関数の代わりに mt_rand() 関数を使用すると、効果が大幅に向上します。これは、mt_rand() がメルセンヌ ツイスター アルゴリズムを使用して乱数を生成するためです。 PHP のドキュメントには、「mt_rand() は、libc が提供する rand() よりも平均 4 倍の速さでランダムな値を生成できる」とも記載されています。
さらに、Linux カーネル (1.3.30 以降) には、多くのセキュリティ目的に十分な乱数ジェネレーター /dev/random が含まれています。
以下は Linux 乱数ジェネレーターの原理の紹介です:
Linux オペレーティング システムは、本質的にランダム (または少なくとも強いランダム性を持つコンポーネント) のライブラリ データを提供します。通常、このデータはデバイス ドライバーから取得されます。たとえば、キーボード ドライバーは 2 つのキーを押す間の時間に関する情報を収集し、この周囲のノイズを乱数生成ライブラリに入力します。
ランダムデータはエントロピープールに保存されます(Linuxカーネルは、デバイスドライバーやその他のソースから環境ノイズを収集するためにエントロピープールを維持します。理論的には、エントロピープール内のデータは完全にランダムであり、真の乱数シーケンスを生成できます。追跡するには)エントロピー プール内のデータのランダム性。このプロセスは、エントロピー推定と呼ばれます。エントロピー推定は、値が大きいほど、データがプールに含まれる乱数を表します。 、データがよりランダムであるほど、プールはより良くなります。) 新しいデータが入ってくるたびに「撹拌」されます。この撹拌は、実際にはランダム性を改善するのに役立つ数学的変換です。データがエントロピー プールに追加されると、システムは取得した真にランダムなビットの数を推定します。
ランダム性の総量を測定することが重要です。問題は、一部の量が最初に考えたときよりもランダムではないことがよくあることです。たとえば、最後のキーストロークからの秒数を表す 32 ビットの数値を追加しても、ほとんどのキーストロークは互いに近接しているため、実際には新しい 32 ビットのランダム情報は提供されません。
/dev/random からバイトを読み取った後、エントロピー プールは MD5 アルゴリズムを使用してパスワードをハッシュし、ハッシュ内の個々のバイトが数値に変換されて返されます。
エントロピープールに利用可能なランダム性ビットがない場合、/dev/random はプールに十分なランダム性が得られるまで結果を返さずに待機します。つまり、/dev/random を使用して多数の乱数を生成すると、速度が遅すぎて実用的ではないことがわかります。 /dev/random が数十バイトのデータを生成した後、何秒も結果が得られないことがよくあります。
幸いなことに、この制限を回避できるエントロピー プールへの別のインターフェイス /dev/urandom があります。この代替デバイスは、エントロピー プールに乱数が利用できない場合でも、常に乱数を返します。エントロピー プールに補充するのに十分な時間を与えずに多くの数値を取り出すと、さまざまなソースからプールされたエントロピーの利点が得られなくなりますが、エントロピー プールの MD5 ハッシュから非常に優れた乱数を取得することはできます。このアプローチは、誰かが MD5 アルゴリズムを解読し、出力を見てハッシュ入力について何かを学んだ場合、数値がすぐに完全に予測可能になるというものです。ほとんどの専門家は、そのような分析は計算的に実行不可能であることに同意しています。ただし、/dev/urandom は依然として /dev/random よりも「安全性が低い」(そして一般に疑わしい) と考えられています。
Windows では /dev/random は利用できませんが、Microsoft の「capicom.dll」が提供する CAPICOM.Utilities オブジェクトを使用できます。
以下は、PHP を使用して mt_rand() 関数よりも優れた擬似乱数を生成するコード例です。
コードは次のとおりです:
// 16 バイトの文字列内の 128 個の擬似乱数ビットを取得します
$pr_bits = '';
// Unix/Linux プラットフォーム?
$fp = @fopen('/dev/urandom','rb');
if ($fp !== FALSE) {
$pr_bits .= @fread($fp,16);
@fclose($fp);
}
// MS-Windows プラットフォーム?
if (@class_exists('COM')) {
試してください {
$CAPI_Util = 新しい COM('CAPICOM.Utilities.1');
$pr_bits .= $CAPI_Util->GetRandom(16,0);
// バイナリデータを要求すると、PHP がそれを書き換えるので、
//base64の戻り値をリクエストします
。// ハッシュ化による冗長性と無駄 ==CRLF...
if ($pr_bits) { $pr_bits = md5($pr_bits,TRUE) }
} catch (例外 $ex) {
// echo 'Exception: ' . $ex->getMessage();
}
}
if (strlen($pr_bits)
// システム所有者に警告するために何かをする
// 擬似乱数生成器がありません
}
?>
したがって、PHP が真の乱数を生成したい場合は、それをサポートするために外部要素を呼び出す必要があります。
注< >: さらにエキサイティングなチュートリアルについては、Bangke Homeプログラミング
に注目してください。