random_int

(PHP 7, PHP 8)

random_intGenera números enteros seudoaleatorios criptográficamente seguros

Descripción

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

Genera números enteros aleatorios criptográficos aptos para resultados imparciales críticos, tales como barajar una baraja de cartas de póquer.

Las fuentes de aleatoriedad empleadas por esta función son las siguientes:

  • En Windows, se utilizará siempre » CryptGenRandom(). A partir de PHP 7.2.0, se usará siempre » CNG-API.
  • En Linux, se utilizará la llamada al sistema » getrandom(2) si está disponible.
  • En otras plataformas, se utilizará /dev/urandom.
  • Si no están disponibles ninguna de las fuentes citadas anteriormente, se lanzará una Exception.

Nota: Aunque esta función se añadió a PHP en PHP 7.0, hay disponible una » implementación de espacio de usuario para PHP 5.2 hasta 5.6, inclusive.

Parámetros

min

El valor mínimo a devolver, el cual debe ser PHP_INT_MIN o mayor.

max

El valor máximo a devolver, el cual debe ser menor o igual que PHP_INT_MAX.

Valores devueltos

Devuelve un número entero aleatorio criptográficamente seguro en el rango min a max, inclusive.

Errores/Excepciones

  • Si no se puede encontrar una fuente de aleatoriedad apropiada, se lanzará una Exception.
  • Si se proporcionan parámetros inválidos, se lanzará un TypeError.
  • Si max es menor que min, se lanzará un Error.

Ejemplos

Ejemplo #1 Ejmplo de random_int()

<?php
var_dump
(random_int(100999));
var_dump(random_int(-10000));
?>

El resultado del ejemplo sería algo similar a:

int(248)
int(-898)

Ver también

  • random_bytes() - Genera bytes seudoaleatorios criptográficamente seguros
add a note add a note

User Contributed Notes 4 notes

up
12
s rotondo90 at gmail com
7 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
3
bens at effortlessis dot com
3 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
5
ccb_bc at hotmail dot com
4 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
-35
info at raymondrodgers dot com
8 years ago
This function is based on Andrew Moore's UUID generation function on the uniqid function; it has been updated to use random_int() on PHP 7.0 or later yet continue to function with earlier versions using mt_rand().

function generateUUIDv4()
{
    if(version_compare(PHP_VERSION,'7.0.0', '<') )
    {
        return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
       
        // 32 bits for "time_low"
        mt_rand(0, 0xffff), mt_rand(0, 0xffff),
       
        // 16 bits for "time_mid"
        mt_rand(0, 0xffff),
       
        // 16 bits for "time_hi_and_version",
        // four most significant bits holds version number 4
        mt_rand(0, 0x0fff) | 0x4000,
       
        // 16 bits, 8 bits for "clk_seq_hi_res",
        // 8 bits for "clk_seq_low",
        // two most significant bits holds zero and one for variant DCE1.1
        mt_rand(0, 0x3fff) | 0x8000,
       
        // 48 bits for "node"
        mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
        );
    }
    else
    {
        return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
       
        // 32 bits for "time_low"
        random_int(0, 0xffff), random_int(0, 0xffff),
       
        // 16 bits for "time_mid"
        random_int(0, 0xffff),
       
        // 16 bits for "time_hi_and_version",
        // four most significant bits holds version number 4
        random_int(0, 0x0fff) | 0x4000,
       
        // 16 bits, 8 bits for "clk_seq_hi_res",
        // 8 bits for "clk_seq_low",
        // two most significant bits holds zero and one for variant DCE1.1
        random_int(0, 0x3fff) | 0x8000,
       
        // 48 bits for "node"
        random_int(0, 0xffff), random_int(0, 0xffff), random_int(0, 0xffff)
        );
    }
}
To Top