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
и тогда вы снова во власти ОС!