PHP: всегда ли псевдогенерируемые числа rand() всегда одинаковы для заданного начального числа?

Я генерирую последовательность псевдослучайных чисел с помощью этого кода:

$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 работает на разных операционных системах?

1 ответ

Решение

Если я запускаю этот код в Windows, я получаю последовательность 99, 38, 79, 21, 75, 91, 42, 36, 47, 67. Он совместим со всеми версиями, 32-разрядными или 64-разрядными на моем компьютере с Windows,

Принимая во внимание, что если я запускаю его на компьютере с Linux, я последовательно получаю последовательность 84, 39, 79, 80, 92, 19, 33, 77, 28, 55 независимо от того, какая версия PHP

Так что это не согласуется между операционными системами


Однако, если я использую mt_srand() а также mt_rand() вместо srand() а также rand() тогда я получаю согласованность между Windows/Linux и различными версиями PHP от 5.2 до 7.0

$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

Нет никакой гарантии, что случайные числа будут одинаковыми для разных версий ОС или 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 и тогда вы снова во власти ОС!

Другие вопросы по тегам