Srand: примеры (PHP)

Использование srand в PHP: примеры и альтернативы
Раздел: Математические функции
srand(int seed [, int mode]): void

Функция srand в PHP используется для инициализации генератора псевдослучайных чисел (ГПСЧ) путем установки его начального значения (seed).

Назначение и применение

Инициализация генератора одним и тем же числом приводит к генерации одной и той же последовательности "случайных" чисел. Это полезно для создания воспроизводимых сценариев, например, в тестах, демонстрациях или процедурной генерации контента.

Аргументы функции

До PHP 7.1 функция имела один необязательный аргумент:

  • $seed (int) - Целочисленное начальное значение для генератора. Если аргумент опущен или равен null, PHP, как правило, использовал текущую временную метку.

Начиная с PHP 7.1, функция стала устаревшей, а ее сигнатура изменилась: srand(int $seed = 0, int $mode = MT_RAND_MT19937): void. Добавился второй необязательный параметр:

  • $mode (int) - Константа, определяющая используемую реализацию алгоритма. Может быть MT_RAND_MT19937 (рекомендуется) или MT_RAND_PHP (устаревший, детерминированный алгоритм до PHP 7.1).
Инициализация с указанием seed
<?
srand(12345);
echo rand(1, 10) . "\n"; // 7 (например)
echo rand(1, 10) . "\n"; // 2
?>
7
2
Инициализация с параметром $mode (PHP 7.1+)
<?
srand(42, MT_RAND_MT19937);
$r1 = rand();
srand(42, MT_RAND_PHP);
$r2 = rand();
var_dump($r1 === $r2); // Разные алгоритмы - разные результаты
?>
bool(false)

В современном PHP рекомендуется использовать более новые и надежные функции.

mt_srand() и mt_rand()

Функция mt_srand() инициализирует генератор Mersenne Twister, который быстрее и производит более качественные псевдослучайные числа, чем rand()/srand().

<?
mt_srand(123);
echo mt_rand(1, 100);
?>
random_int()

Функция random_int() генерирует криптографически безопасные псевдослучайные целые числа. Она не требует явной инициализации и является предпочтительной для задач, связанных с безопасностью.

<?
echo random_int(1, 100); // Криптографически безопасное число
?>

Выбор функции: mt_rand() для общей небезопасной генерации, random_int() для безопасности. rand()/srand() считаются устаревшими.

Srand в Python

Модуль random. Функция random.seed() аналогична srand().

import random
random.seed(42)
print(random.randint(1, 10)) # 2
print(random.randint(1, 10)) # 1
2
1

Srand в Javascript

Стандартный JS не имеет прямой аналогии. Для детерминированной генерации используют внешние библиотеки или реализуют свой ГПСЧ (например, алгоритм xoroshiro128+).

// Использование простого линейного конгруэнтного генератора
let seed = 12345;
function seededRandom() {
    seed = (seed * 9301 + 49297) % 233280;
    return seed / 233280;
}
console.log(seededRandom()); // 0.211...

Srand в MySQL

Функция RAND(N). Если указан целочисленный аргумент N, он используется как начальное значение.

SELECT RAND(5), RAND(5); -- Оба вызова вернут одинаковое значение
0.406135, 0.406135
Использование устаревшей функции

В PHP 7.1+ вызов srand() без аргументов вызывает предупреждение о deprecated-статусе, а в PHP 8+ - уведомление об устаревании (E_DEPRECATED).

<?
srand(); // Deprecated: Функция srand() устарела с PHP 7.1
?>
Непонимание детерминированности

Ожидание разных последовательно чисел при одинаковом seed - ошибка.

<?
srand(100);
$a = rand();
srand(100); // Сброс к тому же seed
$b = rand();
var_dump($a === $b); // true, а не false
?>
bool(true)
Некорректная симуляция случайности

Использование srand(time()) для каждого запроса в веб-приложении может быть бесполезным, если запросы обрабатываются быстрее, чем меняется секунда.

В PHP 4.2.0 генератор rand() стал автоматически инициализироваться, и вызов srand() без параметров перестал быть обязательным.

Наиболее важное изменение произошло в PHP 7.1.0: функции srand() и rand() объявлены устаревшими (deprecated). Их замена - mt_srand() и mt_rand(). Для srand() был добавлен второй параметр $mode.

В PHP 8.0.0 и выше вызов устаревших функций вызывает ошибку уровня E_DEPRECATED, но они продолжают работать.

Создание воспроизводимой последовательности для тестов
Пример php
<?
function generateTestArray($seed, $length) {
    srand($seed);
    $arr = [];
    for ($i = 0; $i < $length; $i++) {
        $arr[] = rand(0, 1000);
    }
    return $arr;
}
// Массивы будут идентичны
$arr1 = generateTestArray(42, 5);
$arr2 = generateTestArray(42, 5);
print_r($arr1);
print_r($arr2);
?>
Array
(
    [0] => 124
    [1] => 724
    [2] => 223
    [3] => 251
    [4] => 53
)
Array
(
    [0] => 124
    [1] => 724
    [2] => 223
    [3] => 251
    [4] => 53
)
Генерация детерминированного "случайного" пароля на основе seed
Пример php
<?
function getSeededPassword($seed, $length = 8) {
    srand($seed);
    $chars = 'abcdefghijklmnopqrstuvwxyz';
    $password = '';
    for ($i = 0; $i < $length; $i++) {
        $password .= $chars[rand(0, strlen($chars) - 1)];
    }
    return $password;
}
echo getSeededPassword(555) . "\n"; // Например, "pxtkyqcp"
echo getSeededPassword(555) . "\n"; // Снова "pxtkyqcp"
?>
pxtkyqcp
pxtkyqcp
Симуляция броска костей с фиксированным начальным состоянием
Пример php
<?
function rollDice($seed, $rolls) {
    srand($seed);
    $results = [];
    for ($i = 0; $i < $rolls; $i++) {
        $results[] = rand(1, 6);
    }
    return $results;
}
$game1 = rollDice(999, 3);
$game2 = rollDice(999, 3);
// Симуляция даст одинаковую последовательность бросков
print_r($game1);
?>
Array
(
    [0] => 4
    [1] => 2
    [2] => 1
)
Использование с разными алгоритмами (PHP 7.1+)
Пример php
<?
// Сравнение последовательностей двух алгоритмов
srand(100, MT_RAND_MT19937);
$seq_mt = [rand(), rand(), rand()];

srand(100, MT_RAND_PHP);
$seq_php = [rand(), rand(), rand()];

echo "MT_RAND_MT19937: " . implode(', ', $seq_mt) . "\n";
echo "MT_RAND_PHP:      " . implode(', ', $seq_php) . "\n";
?>
MT_RAND_MT19937: 1194337952, 1843949759, 1595987920
MT_RAND_PHP:      128959393, 169346975, 59687338

PHP srand function comments

En
Srand Seeds the random number generator