Take the State of PHP 2026 Survey →

RNG fixes and changes View as Markdown

Implemented (PHP 7.1)
Authors
Leigh T leigh@php.net
Date
2016-05-03
Version
1.0
Source
wiki.php.net/rfc/rng_fixes

Votes

Fix mt_rand() implementation closed
Yes
19
No
5
24 voters
bishop Yes 2016-07-07 19:53
cmb Yes 2016-07-09 09:13
colinodell Yes 2016-07-10 14:46
derick No 2016-07-07 12:34
eliw Yes 2016-07-09 14:10
galvao Yes 2016-07-09 09:36
guilhermeblanco Yes 2016-07-13 14:39
hywan Yes 2016-07-07 13:40
jhdxr Yes 2016-07-10 14:24
kguest Yes 2016-07-11 10:39
kinncj Yes 2016-07-13 14:28
leigh Yes 2016-07-07 10:32
mariano Yes 2016-07-07 13:11
mbeccati No 2016-07-09 07:52
mike Yes 2016-07-13 13:33
nikic Yes 2016-07-09 08:48
ocramius Yes 2016-07-07 14:53
pajoye No 2016-07-09 07:45
peehaa Yes 2016-07-07 11:01
svpernova09 Yes 2016-07-08 20:29
trowski Yes 2016-07-07 15:09
tularis Yes 2016-07-10 20:24
tyrael No 2016-07-09 14:43
zimt No 2016-07-07 15:06
Alias rand() to mt_rand() closed
Yes
21
No
4
25 voters
bishop Yes 2016-07-07 19:53
cmb No 2016-07-09 09:13
colinodell No 2016-07-10 14:47
derick Yes 2016-07-07 12:35
eliw Yes 2016-07-09 14:10
galvao Yes 2016-07-09 09:36
guilhermeblanco Yes 2016-07-13 14:40
hywan Yes 2016-07-07 13:40
jhdxr Yes 2016-07-10 14:25
kguest Yes 2016-07-11 10:39
kinncj No 2016-07-13 14:28
leigh Yes 2016-07-07 10:32
mariano Yes 2016-07-07 13:10
mbeccati Yes 2016-07-09 07:52
mike No 2016-07-13 13:32
nikic Yes 2016-07-09 08:48
ocramius Yes 2016-07-07 14:54
pajoye Yes 2016-07-09 07:45
peehaa Yes 2016-07-07 11:02
stas Yes 2016-07-10 05:25
svpernova09 Yes 2016-07-08 20:30
trowski Yes 2016-07-07 15:09
tularis Yes 2016-07-10 20:24
tyrael Yes 2016-07-09 14:43
zimt Yes 2016-07-07 15:06
Fix RAND_RANGE() closed
Yes
25
No
0
25 voters
bishop Yes 2016-07-07 19:53
cmb Yes 2016-07-09 09:13
colinodell Yes 2016-07-10 14:44
derick Yes 2016-07-07 12:35
eliw Yes 2016-07-09 14:10
galvao Yes 2016-07-09 09:37
guilhermeblanco Yes 2016-07-13 14:41
hywan Yes 2016-07-07 13:40
jhdxr Yes 2016-07-10 14:25
kguest Yes 2016-07-11 10:39
kinncj Yes 2016-07-13 14:28
leigh Yes 2016-07-07 10:32
mariano Yes 2016-07-07 13:10
mbeccati Yes 2016-07-09 07:52
mike Yes 2016-07-13 13:33
nikic Yes 2016-07-09 08:48
ocramius Yes 2016-07-07 14:54
pajoye Yes 2016-07-09 07:46
peehaa Yes 2016-07-07 11:02
stas Yes 2016-07-10 05:26
svpernova09 Yes 2016-07-08 20:30
trowski Yes 2016-07-07 15:09
tularis Yes 2016-07-10 20:24
tyrael Yes 2016-07-09 14:44
zimt Yes 2016-07-07 15:07
Replace insecure uses of php_rand() with php_random_bytes() closed
Yes
23
No
0
23 voters
bishop Yes 2016-07-07 19:54
cmb Yes 2016-07-09 09:13
colinodell Yes 2016-07-10 14:44
eliw Yes 2016-07-09 14:10
galvao Yes 2016-07-09 09:37
guilhermeblanco Yes 2016-07-13 14:41
hywan Yes 2016-07-07 13:40
jhdxr Yes 2016-07-15 18:04
kguest Yes 2016-07-11 10:39
kinncj Yes 2016-07-13 14:28
leigh Yes 2016-07-07 10:33
mariano Yes 2016-07-07 13:10
mbeccati Yes 2016-07-09 07:52
mike Yes 2016-07-13 13:33
nikic Yes 2016-07-09 08:48
ocramius Yes 2016-07-07 14:54
peehaa Yes 2016-07-07 11:02
stas Yes 2016-07-10 05:26
svpernova09 Yes 2016-07-08 20:30
trowski Yes 2016-07-07 15:10
tularis Yes 2016-07-10 20:24
tyrael Yes 2016-07-09 14:44
zimt Yes 2016-07-07 15:08
Make array_rand() more efficient closed
Yes
24
No
0
24 voters
bishop Yes 2016-07-07 19:54
cmb Yes 2016-07-09 09:13
colinodell Yes 2016-07-10 14:46
eliw Yes 2016-07-09 14:10
galvao Yes 2016-07-09 09:38
guilhermeblanco Yes 2016-07-13 14:41
hywan Yes 2016-07-07 13:40
jhdxr Yes 2016-07-15 18:04
kguest Yes 2016-07-11 10:40
kinncj Yes 2016-07-13 14:29
leigh Yes 2016-07-07 10:33
mariano Yes 2016-07-07 13:10
mbeccati Yes 2016-07-09 07:53
mike Yes 2016-07-13 13:33
nikic Yes 2016-07-09 08:48
ocramius Yes 2016-07-07 14:55
pajoye Yes 2016-07-09 07:46
peehaa Yes 2016-07-07 11:02
stas Yes 2016-07-10 05:26
svpernova09 Yes 2016-07-08 20:30
trowski Yes 2016-07-07 15:10
tularis Yes 2016-07-10 20:25
tyrael Yes 2016-07-09 14:47
zimt Yes 2016-07-07 15:08

Discussions on the mailing list

[RFC] RNG fixes
by Leigh · 74 messages
[RFC][VOTE] RNG fixes
by Leigh · 16 messages

RFC text

Copied from wiki.php.net, last synchronized Oct 13, 2026 11:51 UTC

Introduction

There are several long standing issues with random number generation that should be addressed:

  • Incorrect implementations
  • Platform-specific outputs
  • Poor scaling of bounded outputs
  • Insecure usage

Some of these fixes alter the output of the RNG or change the behaviour of functions that depend on them, so it makes sense to perform all of the changes at the same time.

Proposal

There are several proposals up for discussion.

  • Fix the current mt_rand() implementation, with the legacy implementation still available.
  • Alias rand() to mt_rand().
  • Fix RAND_RANGE for large ranges.
  • Replace insecure uses of php_rand() with php_random_bytes()
  • Make array_rand() more efficient
Fix mt_rand() implementation

The implementation of mt_rand() in PHP contains a typo that makes it generate a different sequence of numbers to the original mt19937 implementation. See bug #71152

Statistical analysis suggests that the quality of the output is unaffected.

As mt_rand() can be seeded for repeatable sequences the current implementation makes it incompatible with other systems that do use correct implementations. However fixing it also means that the sequence generated for a given seed in PHP will also now be different.

The legacy implementation will be preserved and be selectable with a new `mt_srand(int $seed [, int $mode])` parameter, along with new constants representing the two modes. The default will be the fixed algorithm.

Vote: Fix mt_rand() implementation — Yes: 19 · No: 5 (closed)

Alias rand() to mt_rand()

rand() uses the system random number generator. The output of this RNG is system dependant and on many systems produces weak random numbers. (See bug #45301)

Aliasing it to mt_rand() improves the quality of the output and means the same output can be expected for a given seed regardless of platform.

Vote: Alias rand() to mt_rand() — Yes: 21 · No: 4 (closed)

Fix RAND_RANGE()

The macro used to scale the output of an RNG between two bounds is insufficient for large ranges. (See bug #45184)

The proposed fix is to concatenate multiple outputs for ranges exceeding 32 bits, and use rejection sampling (the same as used in random_bytes()) to produce unbiased outputs.

Vote: Fix RAND_RANGE() — Yes: 25 · No: 0 (closed)

Replace insecure uses of php_rand() with php_random_bytes()

There are several instances where rand() is used internally in a security sensetive context

  • crypt() salt generation
  • SOAP HTTP auth nonce generation

These instances should all be fixed to use the secure random number generator (even mcrypt which is deprecated)

Vote: Replace insecure uses of php_rand() with php_random_bytes() — Yes: 23 · No: 0 (closed)

Make array_rand() more efficient

It has been noted that (array_rand() produces weird and very uneven random distribution). As the above proposals change the output of array_rand() anyway, we can fix this at the same time.

Vote: Make array_rand() more efficient — Yes: 24 · No: 0 (closed)

Backward Incompatible Changes

A call to srand() or mt_srand() with a given seed will produce a different output in the following functions:

  • mt_rand()
  • rand()
  • array_rand()
  • shuffle()
  • str_shuffle()
  • crypt()

Proposed PHP Version(s)

7.1

RFC Impact

To SAPIs

None

To Existing Extensions

This is covered in the Backward Incompatible Changes section

To Opcache

None, this is a functional change, no changes to opcodes or code generation are required.

New Constants

MT_RAND_MT19937 (correct implementation mode) MT_RAND_PHP (unofficial implementation mode)

Open Issues

None

Proposed Voting Choices

Individual votes will be held for the remaining proposals, and since minor BC breaks are introduced they will require a 2/3 majority to pass.

Patches and Tests

https://github.com/php/php-src/pull/1986

Implementation

https://github.com/php/php-src/commit/ab834f4

References

Rejected Features

None