22

rand()自分が何をしているのかを知っていて、サーバーにアクセスできる場合は、使用するだけで予測可能であることを私は知っています。

可能な限り予測不可能な乱数の選択に大きく依存するプロジェクトがあります。そこで、より良い乱数を生成できる他の組み込み関数またはユーザー関数の提案を探しています。

私はこれを使って小さなテストをしました:

$i = 0;

while($i < 10000){
    $rand = rand(0, 100);

    if(!isset($array[$rand])){
        $array[$rand] = 1;
    } else {
        $array[$rand]++;
    }

    sort($array);
    $i++;
}

結果が均等に分布していることがわかりました。各数値が生成される回数には奇妙なパターンがあります。

4

6 に答える 6

22

貧弱なランダム ソースを追加、乗算、または切り捨てると、貧弱なランダム結果が得られます。説明については、乱数と乱数の概要を参照してください。

PHP rand() 関数については正しいです。印象的な図については、統計分析の 2 番目の図を参照してください。(最初の図は印象的ですが、Rand() でプロットされたものではなく、Scott Adams によって描かれたものです)。

1 つの解決策は、 random.orgなどの真のランダム ジェネレーターを使用することです。もう 1 つは、Linux/BSD/etc を使用している場合です。/dev/randomを使用することです。ランダム性がミッション クリティカルな場合は、ハードウェア ランダム ジェネレーターを使用する必要があります。

于 2008-08-08T11:48:42.400 に答える
5

random.orgには、HTTP 経由でアクセスできる API があります。

RANDOM.ORG は、大気ノイズによってランダム性を生成する真の乱数サービスです。

于 2008-08-08T12:27:05.817 に答える
4

ランダム性の印象には注意が必要です。ランダム性の低い分布を選択する実験が数多く行われています。心は、ランダム性を生成したり推定したりするのがあまり得意ではないようです。

Fourmilabにはランダム性に関する優れた記事があり、別の真のランダム ジェネレーターも含まれています。たぶん、両方のサイトからランダムなデータを取得できるので、一方がダウンしてももう一方が残っています。

Fourmilab は、ランダム性をチェックするためのテスト プログラムも提供します。これを使用して、さまざまな myRand() プログラムをチェックできます。

前回のプログラムで、10000 個の値を生成した場合、10,000 個の中から最終的な値を選択してみませんか? 自分自身をサブセットに制限します。また、$min と $max が 10000 より大きい場合は機能しません。

とにかく、必要なランダム性はアプリケーションによって異なります。rand() はオンライン ゲームには問題ありませんが、暗号化には問題ありません (統計プログラムで十分にテストされていないものは、とにかく暗号化には適していません)。あなたは裁判官です!

于 2008-08-08T20:09:42.217 に答える
2

Rand のシードとして EPOCH からのミリ秒を使用した @KG のバリエーション?

于 2008-08-08T04:48:14.203 に答える
2

UUID を取得するのと概念が似ている乱数を取得する別の方法

PHP バージョン 5.3 以降

openssl_random_pseudo_bytes(...)

または、 RFC4122 を使用して次のライブラリを試すことができます

于 2013-09-18T08:59:40.600 に答える
1

新しいPHP7には、必要なことを正確に実行する関数があります。これは、暗号的に安全な疑似乱数整数を生成します。

int random_int ( int $min , int $max )

偏りのない結果が重要な場合 (ポーカー デッキのシャッフルなど) での使用に適した暗号乱数整数を生成します。

PRNG と CSPRNG (およびそれらの違い) に関する詳細な説明と、元のアプローチが実際に悪い考えである理由については、私の別の非常によく似た回答をお読みください。

于 2015-07-16T03:27:28.700 に答える