PHP Conference Japan 2024

random_int

(PHP 7, PHP 8)

random_intПолучает криптографически безопасное равномерно выбранное целое число

Описание

random_int(int $min, int $max): int

Функция создаёт равномерно выбранное целое число между заданными минимумом и максимумом.

Случайная последовательность, которую генерирует функция, подходит для всех приложений, включая генерацию долгосрочных секретов вроде ключей шифрования.

Источники случайных величин в порядке приоритета:

  • Linux: » getrandom(), /dev/urandom

  • FreeBSD >= 12 (PHP >= 7.3): » getrandom(), /dev/urandom

  • Windows (PHP >= 7.2): » CNG-API

    Windows: » CryptGenRandom

  • macOS (PHP >= 8.2; >= 8.1.9; >= 8.0.22, если CCRandomGenerateBytes доступен во время компиляции): CCRandomGenerateBytes()

    macOS (PHP >= 8.1; >= 8.0.2): arc4random_buf(), /dev/urandom

  • NetBSD >= 7 (PHP >= 7.1; >= 7.0.1): arc4random_buf(), /dev/urandom

  • OpenBSD >= 5.5 (PHP >= 7.1; >= 7.0.1): arc4random_buf(), /dev/urandom

  • DragonflyBSD (PHP >= 8.1): » getrandom(), /dev/urandom

  • Solaris (PHP >= 8.1): » getrandom(), /dev/urandom

  • Любая комбинация операционной системы и версии PHP, не указанная раньше: /dev/urandom
  • Если ни один из источников не доступен или все они не генерируют случайную величину, то будет выброшено исключение Random\RandomException.

Замечание: Эта функция была добавлена в PHP 7.0, а для версий с 5.2 по 5.6 включительно доступна » пользовательская реализация.

Список параметров

min

Нижняя граница диапазона.

max

Верхняя граница диапазона.

Возвращаемые значения

Функция возвращает криптографически безопасное равномерно выбранное целое число из замкнутого интервала [min, max]. Функция возвращает как значение min так и значение max.

Ошибки

  • Если подходящие источники случайных величин отсутствуют, то выбрасывается исключение Random\RandomException.
  • Функция выбросит исключение ValueError, если задать значение max меньше, чем значение min.

Список изменений

Версия Описание
8.2.0 Теперь при сбое генератора CSPRNG функция будет выбрасывать исключение Random\RandomException. Раньше функция выбрасывала исключение Exception.

Примеры

Пример #1 Пример использования функции random_int()

<?php

var_dump
(random_int(100, 999));
var_dump(random_int(-1000, 0));

?>

Вывод приведённого примера будет похож на:

int(248)
int(-898)

Смотрите также

  • Random\Randomizer::getInt() - Получает равномерно выбранное целое число
  • random_bytes() - Получает криптографически безопасные случайные байты
Добавить

Примечания пользователей 4 notes

up
15
s rotondo90 at gmail com
8 years ago
Here is a simple backporting function, it works for PHP >= 5.1

<?php
if (!function_exists('random_int')) {
function
random_int($min, $max) {
if (!
function_exists('mcrypt_create_iv')) {
trigger_error(
'mcrypt must be loaded for random_int to work',
E_USER_WARNING
);
return
null;
}

if (!
is_int($min) || !is_int($max)) {
trigger_error('$min and $max must be integer values', E_USER_NOTICE);
$min = (int)$min;
$max = (int)$max;
}

if (
$min > $max) {
trigger_error('$max can\'t be lesser than $min', E_USER_WARNING);
return
null;
}

$range = $counter = $max - $min;
$bits = 1;

while (
$counter >>= 1) {
++
$bits;
}

$bytes = (int)max(ceil($bits/8), 1);
$bitmask = pow(2, $bits) - 1;

if (
$bitmask >= PHP_INT_MAX) {
$bitmask = PHP_INT_MAX;
}

do {
$result = hexdec(
bin2hex(
mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM)
)
) &
$bitmask;
} while (
$result > $range);

return
$result + $min;
}
}
?>

Randomness test

<?php
$max
= 100; // number of random values
$test = 1000000;

$array = array_fill(0, $max, 0);

for (
$i = 0; $i < $test; ++$i) {
++
$array[random_int(0, $max-1)];
}

function
arrayFormatResult(&$item) {
global
$test, $max; // try to avoid this nowdays ;)

$perc = ($item/($test/$max))-1;
$item .= ' '. number_format($perc, 4, '.', '') .'%';
}

array_walk($array, 'arrayFormatResult');

print_r($array);
?>
up
4
bens at effortlessis dot com
4 years ago
On my system (5th gen i7) random_int() takes about 14x longer to do the same number of calculations than rand().

for ($i=0; $i<10000000; $i++)
$x = rand(1, PHP_INT_MAX);

Takes 0.86 seconds for rand(), 12.29 seconds for random_int(). So use random_int() somewhat sparingly.

If it's not really important to be truly random, use rand() instead, especially in a tight loop.
up
0
ccb_bc at hotmail dot com
5 years ago
<?php
// PHP >= 7
function str_rand(int $length = 16){
$x = '';
for(
$i = 1; $i <= $length; $i++){
$x .= dechex(random_int(0,255));
}
return
substr($x, 0, $length);
}
var_dump(str_rand());
?>
up
-1
Hayley Watson
1 year ago
A small function for generating version 4 GUIDs.

<?php
function v4uuid()
{
$a = str_pad(dechex(random_int(0x0000_0000, 0xffff_ffff)), '0', STR_PAD_LEFT);
$b = str_pad(dechex(random_int(0x0000, 0xffff)), '0', STR_PAD_LEFT);
$c = dechex(random_int(0x4000, 0x4fff));
$d = dechex(random_int(0x8000, 0xbfff));
$e = str_pad(dechex(random_int(0x0000_0000_0000, 0xffff_ffff_ffff)), '0', STR_PAD_LEFT);
return
"$a-$b-$c-$d-$e";
}
?>
To Top