4

このコードを使用して一連の疑似乱数を生成しています。

$seed = 1;
srand( $seed );
for($i=0; $i<10; $i++)
{
    echo rand(0,100) . "\n";
}
exit(0);

次のコードは常に(私のマシン上で)出力します

84
39
79
[....]
77
28
55

上記のコードの出力が常に同じであるという事実を信頼できますか?

そうでない場合、何がそれを変えることができますか?

たとえば、PHP のバージョンが異なると結果が異なる可能性がありますか?

それとも、異なるオペレーティング システムで実行されている PHP ですか?

4

2 に答える 2

3

このコードを Windows で実行すると、99、38、79、21、75、91、42、36、47、67 のシーケンスが返されます。これは、Windows ボックスの 32 ビットまたは 64 ビットのすべてのバージョンに対して一貫しています。 .

一方、Linuxボックスで実行すると、PHPのバージョンに関係なく、一貫して84、39、79、80、92、19、33、77、28、55のシーケンスが得られます

したがって、オペレーティングシステム間で一貫性がありません


ただし、and の代わりに and を使用するmt_srand()mt_rand()srand()Windows rand()/Linux と 5.2 から 7.0 までの異なるバージョンの PHP の間で一貫性が得られます。

$seed = 1;
mt_srand( $seed );
for($i=0; $i<10; $i++)
{
    echo mt_rand(0,100) . "\n";
}
exit(0);

一貫して 58、0、72、94、100、87、70、100、86、76 を与える

于 2015-12-05T15:09:35.660 に答える
2

OS または PHP のバージョン間で乱数が同じであるという保証はありません。したがって、このブログ投稿で指摘されているように、独自の疑似乱数ジェネレーターを作成することをお勧めします。

コードは次のとおりです。

<?php

class Random {

    // random seed
    private static $RSeed = 0;

    // set seed
    public static function seed($s = 0) {
        self::$RSeed = abs(intval($s)) % 9999999 + 1;
        self::num();
    }

    // generate random number
    public static function num($min = 0, $max = 9999999) {
        if (self::$RSeed == 0) self::seed(mt_rand());
        self::$RSeed = (self::$RSeed * 125) % 2796203;
        return self::$RSeed % ($max - $min + 1) + $min;
    }

}

// set seed
Random::seed(42);

// echo 10 numbers between 1 and 100
for ($i = 0; $i < 10; $i++) {
    echo Random::num(1, 100) . ',';
}
echo "\n";

for ($i = 0; $i < 10; $i++) {
    echo Random::num() . ',';
}
echo "\n";

結果は次のとおりです。

76,86,14,79,73,2,87,43,62,7,
393758,1684299,822150,2105442,337168,202955,203548,277673,1154689,1729772,

そして明らかに、異なる PHP バージョン間で一貫した結果が得られます。シードを提供する必要があることに注意してください。そうしないと、この関数はフォールバックしmt_rand、再び OS に翻弄されます!

于 2019-11-17T00:22:58.857 に答える