Получение случайных элементов с помощью php

Содержание

Usage

Generating integers and natural numbers

Random::intBetween(300, 999);
// => e.g. int(510)

// or

Random::intBelow(5);
// => e.g. int(1)

// or

Random::intValue();
// => e.g. int(935477113)

Generating floating-point numbers (floats, doubles or reals)

Random::floatBetween(1, 9);
// => e.g. float(7.6388446512546)

// or

Random::floatBelow(499);
// => e.g. float(281.51015805504)

// or

Random::floatValue();
// => e.g. float(0.05532844200834)

Generating hexadecimal strings

Random::hexLowercaseString(2);
// => e.g. string(2) "5f"

// or

Random::hexUppercaseString(7);
// => e.g. string(7) "B0F4B0C"

Generating strings consisting of letters

Random::alphaString(32);
// => e.g. string(32) "GvogcpNdwaxsmOAzKGYwDwqfMOUkZvAn"

// or

Random::alphaHumanString(7);
// => e.g. string(7) "KykrbXb"

// or

Random::alphaLowercaseString(2);
// => e.g. string(2) "ce"

// or

Random::alphaLowercaseHumanString(32);
// => e.g. string(32) "kqbgcmkttvmxjthwpgbhkgdfqhxqmmxh"

// or

Random::alphaUppercaseString(2);
// => e.g. string(2) "IJ"

// or

Random::alphaUppercaseHumanString(7);
// => e.g. string(7) "LJWLLHJ"

Generating strings consisting of letters and numbers

Random::alphanumericString(2);
// => e.g. string(2) "h9"

// or

Random::alphanumericHumanString(7);
// => e.g. string(7) "NF34gd4"

// or

Random::alphanumericLowercaseString(2);
// => e.g. string(2) "4g"

// or

Random::alphanumericLowercaseHumanString(32);
// => e.g. string(32) "wbdt3fdtg9c33dnxxtphp3qd9tgdvhbn"

// or

Random::alphanumericUppercaseString(2);
// => e.g. string(2) "O7"

// or

Random::alphanumericUppercaseHumanString(32);
// => e.g. string(32) "TWFHNNWLNKMPJMYKXHX3TXRCRFTFMYYW"

// or

Random::base32String(7);
// => e.g. string(7) "AZUELC4"

// or

Random::base58String(32);
// => e.g. string(32) "jut9s2LdWHT1EGJeBug3F58oYsaoU85s"

Generating strings consisting of letters, numbers and punctuation

Random::alphanumericAndPunctuationHumanString(32);
// => e.g. string(32) "x%jJ7pWTFwc94ctX3phyy^KT~??H4+JY"

// or

Random::asciiPrintableString(32);
// => e.g. string(32) "N~5_ kP5muxf,HeDY2(W_Bwy^qOkgOXa"

// or

Random::asciiPrintableHumanString(7);
// => e.g. string(7) "_r=kb?v"

// or

Random::base64String(19);
// => e.g. string(19) "I7A/H8D2R54uAo6jCQ3"

// or

Random::base64UrlString(4);
// => e.g. string(4) "_6GS"

// or

Random::base85String(7);
// => e.g. string(7) "j8o6sp:"

Using hyphens as dividers

\Delight\Random\Util::hyphenate('aaaaaaaaaa');
// => string(12) "aaaa-aaaa-aa"

// or

\Delight\Random\Util::hyphenate('bbbbbbbbbb', 3);
// => string(13) "bbb-bbb-bbb-b"

Using spaces as dividers

\Delight\Random\Util::spaceOut('cccccccccc');
// => string(12) "cccc cccc cc"


// or

\Delight\Random\Util::spaceOut('dddddddddd', 3);
// => string(13) "ddd ddd ddd d"

Using arbitrary dividers

\Delight\Random\Util::segmentize('eeeeeeeeee', '/');
// => string(12) "eeee/eeee/ee"


// or

\Delight\Random\Util::segmentize('ffffffffff', '/', 3);
// => string(13) "fff/fff/fff/f"

Изменения, ломающие обратную совместимость

Предотвращение возврата отрицательного нуля из number_format()

Раньше функция number_format() возвращала -0. Хотя это совершенно правильно в соответствии со спецификацией чисел с плавающей точкой IEEE 754, эта странность нежелательна для отображения отформатированных чисел в удобочитаемой форме.

Преобразование числовых ключей при приведении объектов и массивов

Теперь числовые ключи лучше обрабатываются при приведении массивов к объектам и объектов к массивам (через явное приведение, либо используя settype()).

Это означает, что числовые (или числа в виде строк) ключи из массивов, конвертированные в объекты теперь будут доступны:

И теперь числовые (или числа в виде строк) ключи объектов доступны при конвертации в массивы:

Запрещена передача в get_class()

Раньше передача в функцию get_class() возвращала имя класса, из которого был сделан вызов. Это поведение было удалено и теперь вместо этого будет будет вызвана ошибка уровня . Для достижения того же поведения, что и раньше, следует просто опустить аргумент.

Предупреждение при подсчёте неисчисляемых типов

Теперь при использовании count() с параметром, который нельзя посчитать будет возникать ошибка уровня (это также касается sizeof() как псевдонима этой функции).

Переход от ресурсов к объектам в модуле Hash

В рамках долгосрочной миграции отказа от ресурсов, модуль Hash был обновлен для использования объектов вместо ресурсов. Это изменение должно быть плавным для PHP-разработчиков, за исключением случаев, когда используются проверки is_resource() (которые нужно заменить на использование is_object()).

Улучшены значения по умолчанию в SSL/TLS

Были сделаны следующие изменения в значения по умолчанию:

  • tls:// теперь по умолчанию используется TLSv1.0 или TLSv1.1 или TLSv1.2
  • ssl:// псевдоним tls://
  • Константы STREAM_CRYPTO_METHOD_TLS_* по умолчанию равны TLSv1.0 или TLSv1.1 + TLSv1.2, вместо TLSv1.0

Возвращаемое значение gettype() для закрытых ресурсов

Раньше использование gettype() на закрытом ресурсе возвращало строку «unknown type». Теперь будет возвращена строка «resource (closed)».

Повышены уровни ошибок неопределенных констант

Не полностью определенные ссылки на неопределенные константы теперь будут генерировать (вместо ). В следующей основной версии PHP они будут генерировать исключения Error.

object для имен классов

Имя object ранее было мягко зарезервировано с PHP 7.0. Теперь оно полноценное зарезервированное слово, запрещающее использовать его в качестве имени класса, трейта или интерфейса.

array_unique() with

Если равен , ранее массив копировался, а не уникальные элементы удалялись (сохраняя значения цифровых индексов), но теперь создается новый массив путем добавления уникальных элементов. Это может привести к различным числовым индексам.

Изменения bcmod() с числами с плавающей точкой

Функция bcmod() больше не обрезает числа с плавающей точкой до целых. Таким образом, её поведение теперь соответствует fmod(), а не оператору %. Например, bcmod(‘4’, ‘3.5’) теперь возвращает 0.5 вместо 1.

Функции хеширования и некриптографические хеши

Функции hash_hmac(), hash_hmac_file(), hash_pbkdf2() и hash_init() (с ) больше не принимают некриптографические хеши.

Опции функции json_decode()

Опция функции json_decode(), , теперь используется, если второй параметр (assoc) равен . Ранее всегда игнорировался.

Вывод rand() и mt_rand()

Числа, генерируемые rand() и mt_rand() для определённого параметра переинициализации (seed), могут отличаться от PHP 7.1 на 64-битных машинах (из-за исправления ошибки модульного смещения в реализации).

Изменения в date_parse() и date_parse_from_format()

Элемент массива zone, возвращаемого функциями date_parse_from_format() и date_parse() теперь отображает секунды вместо минут, а его знак инвертируется. Например, -120 теперь будет 7200.

Introduction

Current predictable PRNG, i.e. mt_rand() and rand(), produces very weak random values even produces non random values.

Non random value

// We need the same random numbers here
srand(1234); 
for ($i=; $i < 10; $i++) {
   // Use my PRNG state
   $my_rand = rand(); 
}
 
// Somewhere later in code AND/OR even other requests
 
// We need somewhat random numbers for non CS purpose
for ($i=; $i < 10; $i++) {
   // following mt_rand() is NOT RANDOM at all
   $my_other_rand = mt_rand(); 
}

Above code worked as it should. PHP 7.1 broke this code. Similarly, shuffle()/etc are broken by PHP 7.1.

// We need the same random numbers here
mt_srand(1234); 
for ($i=; $i < 10; $i++) {
   // Use my PRNG state
   $my_rand = mt_rand(); 
}
 
// Somewhere later in code AND/OR even other requests
 
// We need to shuffle randomly
shuffle($my_random_array); // This is NOT RANDOM at all

These behaviors are not limited to specific request that calls mt_srand($some_value)/srand($some_value), but applies to consecutive requests.

PHP should have system and user PRNG state to resolve this behavior.

Weak seeding = Weak random

MT rand has 2^19937−1 cycle. This makes MT rand much stronger than older predictable PRNG. However, PHP initializes MT rand by 32 bit int value for both system and user seed, thus only 2^32 initial states. As a result, PHP’s MT rand cannot not use more than 99% of MT rand cycle. This behavior is extremely weaker than MT rand could be.

To resolve this issue, PHP should initialize MT rand with more seed value and have API allows large seed value.

Rack of Reseeding

Reseeding is important for PRNG to mitigate guessed random value. Since MT rand is predictable PRNG, using the same PRNG state allows to guess next random value easily. Current PHP only supports very weak initialization and keeps using the same PRNG state once it is initialized. This behavior makes trivial to guess MT rand generated random numbers.

To resolve this issue, PHP should reseed MT rand when state is used certain number of times.

Contributors

This project would not be anywhere near as excellent as it is today if it weren’t for the contributions of the following individuals:

  • @AndrewCarterUK (Andrew Carter)
  • @asgrim (James Titcumb)
  • @bcremer (Benjamin Cremer)
  • @chriscct7 (Chris Christoff)
  • @CodesInChaos (Christian Winnerlein)
  • @ConnorVG (Connor S. Parks)
  • @cs278 (Chris Smith)
  • @cweagans (Cameron Eagans)
  • @dd32 (Dion Hulse)
  • @geggleto (Glenn Eggleton)
  • @glensc (Elan Ruusamäe)
  • @GrahamCampbell (Graham Campbell)
  • @ircmaxell (Anthony Ferrara)
  • @jdevalk (Joost de Valk)
  • @jedisct1 (Frank Denis)
  • @juliangut (Julián Gutiérrez)
  • @kelunik (Niklas Keller)
  • @lt (Leigh)
  • @MasonM (Mason Malone)
  • @menkaff (Mehran NikNafs)
  • @mmeyer2k (Michael M)
  • @narfbg (Andrey Andreev)
  • @nicolas-grekas (Nicolas Grekas)
  • @ocean90 (Dominik Schilling)
  • @oittaa
  • @oucil (Kevin Farley)
  • @philios33 (Phil Nicholls)
  • @redragonx (Stephen Chavez)
  • @relaxnow (Boy Baukema)
  • @rchouinard (Ryan Chouinard)
  • @rugk
  • @SammyK (Sammy Kaye Powers)
  • @scottchiefbaker (Scott Baker)
  • @skyosev (Stoyan Kyosev)
  • @sthen (Stuart Henderseon)
  • @stof (Christophe Coevoet)
  • @teohhanhui (Teoh Han Hui)
  • @tom— (Tom Worster)
  • @tsyr2ko
  • @trowski (Aaron Piotrowski)
  • @twistor (Chris Lepannen)
  • @vinkla (Vincent Klaiber)
  • @voku (Lars Moelleken)
  • @xabbuh (Christian Flothmann)

Usage

Generate a string of random bytes

try {
    $string = random_bytes(32);
} catch (TypeError $e) {
    // Well, it's an integer, so this IS unexpected.
    die("An unexpected error has occurred"); 
} catch (Error $e) {
    // This is also unexpected because 32 is a reasonable integer.
    die("An unexpected error has occurred");
} catch (Exception $e) {
    // If you get this message, the CSPRNG failed hard.
    die("Could not generate a random string. Is our OS secure?");
}

var_dump(bin2hex($string));
// string(64) "5787c41ae124b3b9363b7825104f8bc8cf27c4c3036573e5f0d4a91ad2eeac6f"

Generate a random integer between two given integers (inclusive)

try {
    $int = random_int(, 255);
} catch (TypeError $e) {
    // Well, it's an integer, so this IS unexpected.
    die("An unexpected error has occurred"); 
} catch (Error $e) {
    // This is also unexpected because 0 and 255 are both reasonable integers.
    die("An unexpected error has occurred");
} catch (Exception $e) {
    // If you get this message, the CSPRNG failed hard.
    die("Could not generate a random int. Is our OS secure?");
}

var_dump($int);
// int(47)

Exception handling

When handling exceptions and errors you must account for differences between PHP 5 and PHP7.

The differences:


  • Catching works, so long as it is caught before .
  • Catching has different behavior, without previously catching .
  • There is no portable way to catch all errors/exceptions.

Example

try {
    return random_int(1, $userInput);
} catch (TypeError $e) {
    // This is okay, so long as `Error` is caught before `Exception`.
    throw new Exception('Please enter a number!');
} catch (Error $e) {
    // This is required, if you do not need to do anything just rethrow.
    throw $e;
} catch (Exception $e) {
    // This is optional and maybe omitted if you do not want to handle errors
    // during generation.
    throw new InternalServerErrorException(
        'Oops, our server is bust and cannot generate any random data.',
        500,
        $e
    );
}

Troubleshooting

Exception: «Could not gather sufficient random data»


If an Exception is thrown, then your operating system is not secure.

  1. If you’re on Windows, make sure you enable mcrypt.
  2. If you’re on any other OS, make sure is readable.
    • FreeBSD jails need to expose from the host OS
    • If you use , make sure is allowed

This library does not (and will not accept any patches to) fall back to an insecure random number generator.

Version Conflict with


If you’re using a project that has a line like this in its composer.json


Содержание

Usage

Generating integers and natural numbers

Random::intBetween(300, 999);
// => e.g. int(510)

// or

Random::intBelow(5);
// => e.g. int(1)

// or

Random::intValue();
// => e.g. int(935477113)

Generating floating-point numbers (floats, doubles or reals)

Random::floatBetween(1, 9);
// => e.g. float(7.6388446512546)

// or

Random::floatBelow(499);
// => e.g. float(281.51015805504)

// or

Random::floatValue();
// => e.g. float(0.05532844200834)

Generating hexadecimal strings

Random::hexLowercaseString(2);
// => e.g. string(2) "5f"

// or

Random::hexUppercaseString(7);
// => e.g. string(7) "B0F4B0C"

Generating strings consisting of letters

Random::alphaString(32);
// => e.g. string(32) "GvogcpNdwaxsmOAzKGYwDwqfMOUkZvAn"

// or

Random::alphaHumanString(7);
// => e.g. string(7) "KykrbXb"

// or

Random::alphaLowercaseString(2);
// => e.g. string(2) "ce"

// or

Random::alphaLowercaseHumanString(32);
// => e.g. string(32) "kqbgcmkttvmxjthwpgbhkgdfqhxqmmxh"

// or

Random::alphaUppercaseString(2);
// => e.g. string(2) "IJ"

// or

Random::alphaUppercaseHumanString(7);
// => e.g. string(7) "LJWLLHJ"

Generating strings consisting of letters and numbers

Random::alphanumericString(2);
// => e.g. string(2) "h9"

// or

Random::alphanumericHumanString(7);
// => e.g. string(7) "NF34gd4"

// or

Random::alphanumericLowercaseString(2);
// => e.g. string(2) "4g"

// or

Random::alphanumericLowercaseHumanString(32);
// => e.g. string(32) "wbdt3fdtg9c33dnxxtphp3qd9tgdvhbn"

// or

Random::alphanumericUppercaseString(2);
// => e.g. string(2) "O7"

// or

Random::alphanumericUppercaseHumanString(32);
// => e.g. string(32) "TWFHNNWLNKMPJMYKXHX3TXRCRFTFMYYW"

// or

Random::base32String(7);
// => e.g. string(7) "AZUELC4"

// or

Random::base58String(32);
// => e.g. string(32) "jut9s2LdWHT1EGJeBug3F58oYsaoU85s"

Generating strings consisting of letters, numbers and punctuation

Random::alphanumericAndPunctuationHumanString(32);
// => e.g. string(32) "x%jJ7pWTFwc94ctX3phyy^KT~??H4+JY"

// or

Random::asciiPrintableString(32);
// => e.g. string(32) "N~5_ kP5muxf,HeDY2(W_Bwy^qOkgOXa"

// or

Random::asciiPrintableHumanString(7);
// => e.g. string(7) "_r=kb?v"

// or

Random::base64String(19);
// => e.g. string(19) "I7A/H8D2R54uAo6jCQ3"

// or

Random::base64UrlString(4);
// => e.g. string(4) "_6GS"

// or

Random::base85String(7);
// => e.g. string(7) "j8o6sp:"

Using hyphens as dividers

\Delight\Random\Util::hyphenate('aaaaaaaaaa');
// => string(12) "aaaa-aaaa-aa"

// or

\Delight\Random\Util::hyphenate('bbbbbbbbbb', 3);
// => string(13) "bbb-bbb-bbb-b"

Using spaces as dividers

\Delight\Random\Util::spaceOut('cccccccccc');
// => string(12) "cccc cccc cc"


// or

\Delight\Random\Util::spaceOut('dddddddddd', 3);
// => string(13) "ddd ddd ddd d"

Using arbitrary dividers

\Delight\Random\Util::segmentize('eeeeeeeeee', '/');
// => string(12) "eeee/eeee/ee"


// or

\Delight\Random\Util::segmentize('ffffffffff', '/', 3);
// => string(13) "fff/fff/fff/f"

Изменения, ломающие обратную совместимость

Предотвращение возврата отрицательного нуля из number_format()

Раньше функция number_format() возвращала -0. Хотя это совершенно правильно в соответствии со спецификацией чисел с плавающей точкой IEEE 754, эта странность нежелательна для отображения отформатированных чисел в удобочитаемой форме.

Преобразование числовых ключей при приведении объектов и массивов

Теперь числовые ключи лучше обрабатываются при приведении массивов к объектам и объектов к массивам (через явное приведение, либо используя settype()).

Это означает, что числовые (или числа в виде строк) ключи из массивов, конвертированные в объекты теперь будут доступны:

И теперь числовые (или числа в виде строк) ключи объектов доступны при конвертации в массивы:

Запрещена передача в get_class()

Раньше передача в функцию get_class() возвращала имя класса, из которого был сделан вызов. Это поведение было удалено и теперь вместо этого будет будет вызвана ошибка уровня . Для достижения того же поведения, что и раньше, следует просто опустить аргумент.

Предупреждение при подсчёте неисчисляемых типов

Теперь при использовании count() с параметром, который нельзя посчитать будет возникать ошибка уровня (это также касается sizeof() как псевдонима этой функции).

Переход от ресурсов к объектам в модуле Hash

В рамках долгосрочной миграции отказа от ресурсов, модуль Hash был обновлен для использования объектов вместо ресурсов. Это изменение должно быть плавным для PHP-разработчиков, за исключением случаев, когда используются проверки is_resource() (которые нужно заменить на использование is_object()).

Улучшены значения по умолчанию в SSL/TLS

Были сделаны следующие изменения в значения по умолчанию:

  • tls:// теперь по умолчанию используется TLSv1.0 или TLSv1.1 или TLSv1.2
  • ssl:// псевдоним tls://
  • Константы STREAM_CRYPTO_METHOD_TLS_* по умолчанию равны TLSv1.0 или TLSv1.1 + TLSv1.2, вместо TLSv1.0

Возвращаемое значение gettype() для закрытых ресурсов

Раньше использование gettype() на закрытом ресурсе возвращало строку «unknown type». Теперь будет возвращена строка «resource (closed)».

Повышены уровни ошибок неопределенных констант

Не полностью определенные ссылки на неопределенные константы теперь будут генерировать (вместо ). В следующей основной версии PHP они будут генерировать исключения Error.

object для имен классов

Имя object ранее было мягко зарезервировано с PHP 7.0. Теперь оно полноценное зарезервированное слово, запрещающее использовать его в качестве имени класса, трейта или интерфейса.

array_unique() with

Если равен , ранее массив копировался, а не уникальные элементы удалялись (сохраняя значения цифровых индексов), но теперь создается новый массив путем добавления уникальных элементов. Это может привести к различным числовым индексам.

Изменения bcmod() с числами с плавающей точкой

Функция bcmod() больше не обрезает числа с плавающей точкой до целых. Таким образом, её поведение теперь соответствует fmod(), а не оператору %. Например, bcmod(‘4’, ‘3.5’) теперь возвращает 0.5 вместо 1.

Функции хеширования и некриптографические хеши

Функции hash_hmac(), hash_hmac_file(), hash_pbkdf2() и hash_init() (с ) больше не принимают некриптографические хеши.

Опции функции json_decode()

Опция функции json_decode(), , теперь используется, если второй параметр (assoc) равен . Ранее всегда игнорировался.

Вывод rand() и mt_rand()

Числа, генерируемые rand() и mt_rand() для определённого параметра переинициализации (seed), могут отличаться от PHP 7.1 на 64-битных машинах (из-за исправления ошибки модульного смещения в реализации).

Изменения в date_parse() и date_parse_from_format()

Элемент массива zone, возвращаемого функциями date_parse_from_format() и date_parse() теперь отображает секунды вместо минут, а его знак инвертируется. Например, -120 теперь будет 7200.

Introduction

Current predictable PRNG, i.e. mt_rand() and rand(), produces very weak random values even produces non random values.

Non random value

// We need the same random numbers here
srand(1234); 
for ($i=; $i < 10; $i++) {
   // Use my PRNG state
   $my_rand = rand(); 
}
 
// Somewhere later in code AND/OR even other requests
 
// We need somewhat random numbers for non CS purpose
for ($i=; $i < 10; $i++) {
   // following mt_rand() is NOT RANDOM at all
   $my_other_rand = mt_rand(); 
}

Above code worked as it should. PHP 7.1 broke this code. Similarly, shuffle()/etc are broken by PHP 7.1.

// We need the same random numbers here
mt_srand(1234); 
for ($i=; $i < 10; $i++) {
   // Use my PRNG state
   $my_rand = mt_rand(); 
}
 
// Somewhere later in code AND/OR even other requests
 
// We need to shuffle randomly
shuffle($my_random_array); // This is NOT RANDOM at all

These behaviors are not limited to specific request that calls mt_srand($some_value)/srand($some_value), but applies to consecutive requests.

PHP should have system and user PRNG state to resolve this behavior.

Weak seeding = Weak random

MT rand has 2^19937−1 cycle. This makes MT rand much stronger than older predictable PRNG. However, PHP initializes MT rand by 32 bit int value for both system and user seed, thus only 2^32 initial states. As a result, PHP’s MT rand cannot not use more than 99% of MT rand cycle. This behavior is extremely weaker than MT rand could be.

To resolve this issue, PHP should initialize MT rand with more seed value and have API allows large seed value.

Rack of Reseeding

Reseeding is important for PRNG to mitigate guessed random value. Since MT rand is predictable PRNG, using the same PRNG state allows to guess next random value easily. Current PHP only supports very weak initialization and keeps using the same PRNG state once it is initialized. This behavior makes trivial to guess MT rand generated random numbers.

To resolve this issue, PHP should reseed MT rand when state is used certain number of times.

Contributors

This project would not be anywhere near as excellent as it is today if it weren’t for the contributions of the following individuals:

  • @AndrewCarterUK (Andrew Carter)
  • @asgrim (James Titcumb)
  • @bcremer (Benjamin Cremer)
  • @chriscct7 (Chris Christoff)
  • @CodesInChaos (Christian Winnerlein)
  • @ConnorVG (Connor S. Parks)
  • @cs278 (Chris Smith)
  • @cweagans (Cameron Eagans)
  • @dd32 (Dion Hulse)
  • @geggleto (Glenn Eggleton)
  • @glensc (Elan Ruusamäe)
  • @GrahamCampbell (Graham Campbell)
  • @ircmaxell (Anthony Ferrara)
  • @jdevalk (Joost de Valk)
  • @jedisct1 (Frank Denis)
  • @juliangut (Julián Gutiérrez)
  • @kelunik (Niklas Keller)
  • @lt (Leigh)
  • @MasonM (Mason Malone)
  • @menkaff (Mehran NikNafs)
  • @mmeyer2k (Michael M)
  • @narfbg (Andrey Andreev)
  • @nicolas-grekas (Nicolas Grekas)
  • @ocean90 (Dominik Schilling)
  • @oittaa
  • @oucil (Kevin Farley)
  • @philios33 (Phil Nicholls)
  • @redragonx (Stephen Chavez)
  • @relaxnow (Boy Baukema)
  • @rchouinard (Ryan Chouinard)
  • @rugk
  • @SammyK (Sammy Kaye Powers)
  • @scottchiefbaker (Scott Baker)
  • @skyosev (Stoyan Kyosev)
  • @sthen (Stuart Henderseon)
  • @stof (Christophe Coevoet)
  • @teohhanhui (Teoh Han Hui)
  • @tom— (Tom Worster)
  • @tsyr2ko
  • @trowski (Aaron Piotrowski)
  • @twistor (Chris Lepannen)
  • @vinkla (Vincent Klaiber)
  • @voku (Lars Moelleken)
  • @xabbuh (Christian Flothmann)

Usage

Generate a string of random bytes

try {
    $string = random_bytes(32);
} catch (TypeError $e) {
    // Well, it's an integer, so this IS unexpected.
    die("An unexpected error has occurred"); 
} catch (Error $e) {
    // This is also unexpected because 32 is a reasonable integer.
    die("An unexpected error has occurred");
} catch (Exception $e) {
    // If you get this message, the CSPRNG failed hard.
    die("Could not generate a random string. Is our OS secure?");
}

var_dump(bin2hex($string));
// string(64) "5787c41ae124b3b9363b7825104f8bc8cf27c4c3036573e5f0d4a91ad2eeac6f"

Generate a random integer between two given integers (inclusive)

try {
    $int = random_int(, 255);
} catch (TypeError $e) {
    // Well, it's an integer, so this IS unexpected.
    die("An unexpected error has occurred"); 
} catch (Error $e) {
    // This is also unexpected because 0 and 255 are both reasonable integers.
    die("An unexpected error has occurred");
} catch (Exception $e) {
    // If you get this message, the CSPRNG failed hard.
    die("Could not generate a random int. Is our OS secure?");
}

var_dump($int);
// int(47)

Exception handling

When handling exceptions and errors you must account for differences between PHP 5 and PHP7.

The differences:

  • Catching works, so long as it is caught before .
  • Catching has different behavior, without previously catching .
  • There is no portable way to catch all errors/exceptions.

Example

try {
    return random_int(1, $userInput);
} catch (TypeError $e) {
    // This is okay, so long as `Error` is caught before `Exception`.
    throw new Exception('Please enter a number!');
} catch (Error $e) {
    // This is required, if you do not need to do anything just rethrow.
    throw $e;
} catch (Exception $e) {
    // This is optional and maybe omitted if you do not want to handle errors
    // during generation.
    throw new InternalServerErrorException(
        'Oops, our server is bust and cannot generate any random data.',
        500,
        $e
    );
}

Troubleshooting

Exception: «Could not gather sufficient random data»

If an Exception is thrown, then your operating system is not secure.

  1. If you’re on Windows, make sure you enable mcrypt.
  2. If you’re on any other OS, make sure is readable.
    • FreeBSD jails need to expose from the host OS
    • If you use , make sure is allowed

This library does not (and will not accept any patches to) fall back to an insecure random number generator.

Version Conflict with

If you’re using a project that has a line like this in its composer.json

…and then you try to add random_compat 2 (or another library that explicitly requires random_compat 2, such as this secure PHP encryption library), you will get a version conflict.

The solution is to get the project to update its requirement string to allow version 2 and above to be used instead of hard-locking users to version 1.

"require" {
    ...
-    "paragonie/random_compat": "~1.1",
+    "paragonie/random_compat": ">=1",
    ...
}

Version 9.99.99

Note: There is a special version called which makes this library do nothing, but is only installable on PHP 7.

If you’re writing software (e.g. a library) that supports PHP 5, but may be used by software that doesn’t, you’ll want to allow to be installed. The above diff is what you want.

Conversely, if you’re writing software that (in and of itself) supports PHP 5, you do not want 9.99.99 to be installed, so you’ll want to make this change instead:

"require" {
    ...
-    "paragonie/random_compat": "~1.1",
+    "paragonie/random_compat": ">=1 <9.99",
    ...
}

To avoid installing «empty» version you can add section in your root :

Manifest Read Length Error

If you’re using the PHP Archive (Phar) approach rather than Composer, and you are getting an error message to the effect of «manifest read length was should be «, the Phar extension may not be enabled.

See for specific guidance on how to fix this issue.


С этим читают