rfc:rng_extension
Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
rfc:rng_extension [2021/06/25 22:25] zeriyoshi fix: tab -> space |
rfc:rng_extension [2022/08/01 16:52] (current) timwolla Errata |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== PHP RFC: Add Random Extension ====== | + | ====== PHP RFC: Random Extension |
- | * Version: | + | * Version: |
- | * Date: 2021-05-18 | + | * Date: 2022-02-24 |
- | * Author: Go Kudo < | + | * Author: Go Kudo < |
- | * Status: | + | * Status: |
- | * Implementation: | + | * Implementation: |
* First Published at: http:// | * First Published at: http:// | ||
===== Introduction ===== | ===== Introduction ===== | ||
- | PHP is currently having problems with RNG reproducibility. | ||
- | PHP' | + | There are several problems with the current implementation of PHP' |
- | But, these functions still store the state in the global state of PHP and are not easily reproducible. Look at the following example. | + | ==== Problems ==== |
- | <code php> | + | There are four main problems |
- | echo foo(1234, function (): void {}) . PHP_EOL; // Result: 1480009472 | + | |
- | echo foo(1234, function (): void { mt_rand(); }) . PHP_EOL; // Result: 1747253290 | + | |
- | function foo(int $seed, callable $bar): int { | + | * Global state |
- | | + | * Mersenne Twister |
- | | + | * Randomness |
- | | + | * Internals |
- | $result += mt_rand(); | + | |
- | return $result; | + | |
- | } | + | |
- | </ | + | |
- | As mentioned above, the reproducibility of random numbers can easily be lost if additional processing is added later. | + | === Global state === |
- | In addition, the fiber extension was introduced | + | Mersenne Twister state is implicitly stored |
- | There is also the problem of functions that implicitly use the state stored in PHP' | + | Let' |
<code php> | <code php> | ||
- | mt_srand(1234); | + | <?php |
- | echo mt_rand() . PHP_EOL; | + | |
+ | function foo(): void { | ||
+ | | ||
+ | } | ||
mt_srand(1234); | mt_srand(1234); | ||
- | str_shuffle(' | + | foo(); |
- | echo mt_rand() | + | mt_rand(1, 100); // result: 76 |
</ | </ | ||
- | ===== Proposal ===== | + | Then at some point in time the function was edited like below. |
- | Implement and bundled Random extension into PHP. | + | |
- | + | ||
- | The phpstub for the whole extension is as follows: | + | |
<code php> | <code php> | ||
<?php | <?php | ||
- | /** @generate-class-entries */ | + | function foo(): void { |
- | /** @generate-function-entries */ | + | str_shuffle(' |
+ | } | ||
- | namespace Random\NumberGenerator | + | mt_srand(1234); |
- | { | + | foo(); |
- | | + | mt_rand(1, 100); // result: 65 |
- | { | + | </ |
- | /** | + | |
- | * @tentative-return-type | + | |
- | * @internal | + | |
- | */ | + | |
- | public function generate(): int; | + | |
- | } | + | |
- | class XorShift128Plus implements RandomNumberGenerator | + | As you can see, the result of mt_rand has changed from 76 to 65 because str_shuffle() changed the state of Mersenne Twister internally. |
- | { | + | |
- | /** @tentative-return-type */ | + | |
- | public function __construct(?int $seed = null) {} | + | |
- | /** | + | Maintaining such code can be difficult when your code utilizes external packages. |
- | * @tentative-return-type | + | Also, by using Generator and Fiber introduced in PHP 8.1, the current state can be easily lost. |
- | * @internal | + | |
- | */ | + | |
- | public function generate(): int {} | + | |
- | /** @tentative-return-type */ | + | Given the above, mt_srand() and srand(), can not provide reproducible values in a consistent manner. |
- | public function __serialize(): array {} | + | |
- | /** @tentative-return-type */ | + | Another problem which may occur is when using extensions like Swoole, which copy global random state to child processes due to its structure, making random number-related operations unsafe unless they are reseeded. |
- | public function __unserialize(array $data): void {} | + | |
- | } | + | |
- | class MT19937 implements RandomNumberGenerator | + | https:// |
- | { | + | |
- | /** | + | |
- | * @implementation-alias Random\NumberGenerator\XorShift128Plus:: | + | |
- | * @tentative-return-type | + | |
- | */ | + | |
- | public function __construct(?int $seed = null) {} | + | |
- | /** | + | === Mersenne Twister === |
- | * @implementation-alias Random\NumberGenerator\XorShift128Plus:: | + | |
- | * @tentative-return-type | + | |
- | */ | + | |
- | public function generate(): int {} | + | |
- | /** | + | Mersenne Twister is an excellent pseudo random number generator. But, it is old and no longer suitable for the current needs. |
- | * @implementation-alias Random\NumberGenerator\XorShift128Plus:: | + | |
- | * @tentative-return-type | + | |
- | */ | + | |
- | public function __serialize(): | + | |
- | /** | + | It has a very long period of 2^19937 |
- | * @implementation-alias Random\NumberGenerator\XorShift128Plus:: | + | |
- | * @tentative-return-type | + | |
- | */ | + | |
- | public function __unserialize(array $data): void {} | + | |
- | } | + | |
- | class Secure implements RandomNumberGenerator | + | Also, the size that Mersenne Twister can generate is limited to 32-bit. This is not compatible with the current situation where many execution environments are 64-bit and zend_long has a length of 64-bit. |
- | { | + | |
- | /** @tentative-return-type */ | + | |
- | public function __construct() {} | + | |
- | /** | + | === Randomness === |
- | * @implementation-alias Random\NumberGenerator\XorShift128Plus:: | + | |
- | * @tentative-return-type | + | |
- | */ | + | |
- | public function generate(): int {} | + | |
- | } | + | |
- | } | + | |
- | namespace | + | PHP's built-in functions (< |
+ | |||
+ | === Internals === | ||
+ | |||
+ | The implementation of random numbers in PHP is scattered within the standard module for historical reasons. | ||
+ | |||
+ | The following are different header files, but some are interdependent, | ||
+ | |||
+ | | ^ extension ^ header | ||
+ | ^ Combined LCG | standard | ||
+ | ^ libc rand* | standard | ||
+ | ^ MT19937 | ||
+ | ^ CSPRNG | ||
+ | |||
+ | |||
+ | ==== Userland approach ==== | ||
+ | |||
+ | Think about how the above problems could be solved in userland. | ||
+ | |||
+ | Implement a random number generator in PHP. Here I will consider an already existing implementation (https:// | ||
+ | |||
+ | <code php> | ||
+ | class XorShift128Plus | ||
{ | { | ||
- | | + | |
+ | protected const MASK_S5 = 0x07ffffffffffffff; | ||
+ | protected const MASK_S18 = 0x00003fffffffffff; | ||
+ | protected const MASK_S27 = 0x0000001fffffffff; | ||
+ | protected const MASK_S30 = 0x00000003ffffffff; | ||
+ | protected const MASK_S31 = 0x00000001ffffffff; | ||
+ | protected const MASK_LO = 0x00000000ffffffff; | ||
+ | |||
+ | protected const ADD_HI = 0x9e3779b9; | ||
+ | protected const ADD_LO = 0x7f4a7c15; | ||
+ | protected const MUL1_HILO = 0x476d; | ||
+ | protected const MUL1_HIHI = 0xbf58; | ||
+ | protected const MUL1_LO = 0x1ce4e5b9; | ||
+ | protected const MUL2_HIHI = 0x94d0; | ||
+ | protected const MUL2_HILO = 0x49bb; | ||
+ | protected const MUL2_LO = 0x133111eb; | ||
+ | |||
+ | /* states */ | ||
+ | protected int $s0; | ||
+ | protected int $s1; | ||
+ | |||
+ | public function __construct(int $seed) | ||
{ | { | ||
- | | + | $s = $seed; |
- | public function nextInt(): int; | + | |
- | + | | |
- | /** @tentative-return-type */ | + | |
- | public function getInt(int | + | |
- | | + | |
- | /** @tentative-return-type */ | + | |
- | public function getBytes(int $length): string; | + | |
- | | + | |
- | /** @tentative-return-type */ | + | |
- | public function shuffleArray(array | + | |
- | + | ||
- | /** @tentative-return-type */ | + | |
- | public function shuffleString(string | + | |
} | } | ||
- | + | ||
- | | + | |
{ | { | ||
- | | + | |
- | | + | $s0 = $this-> |
- | | + | |
- | + | $s0h = ($s0 >> 32) & self:: | |
- | | + | $s0l = $s0 & self:: |
- | | + | $s1h = ($s1 >> 32) & self:: |
- | | + | $s1l = $s1 & self:: |
- | | + | |
- | | + | $zh = $s0h + $s1h + ($zl >> 32); |
- | | + | $z = ($zh << 32) | ($zl & self:: |
- | | + | |
- | | + | |
- | | + | $s1 ^= $s1 << 23; |
+ | $this-> | ||
+ | |||
+ | | ||
+ | } | ||
+ | |||
+ | protected | ||
+ | | ||
+ | | ||
+ | $zh = ($s >> 32) & self:: | ||
+ | | ||
+ | $z = $s = (($zh + self:: | ||
+ | |||
+ | | ||
+ | | ||
+ | $zh = ($z >> 32) & self::MASK_LO; | ||
+ | | ||
+ | $zll = $zl & 0xffff; | ||
+ | $zlh = $zl >> 16; | ||
+ | $mul1l = $zll * self:: | ||
+ | $mul1h = $zll * self:: | ||
+ | $mul1 = (($mul1h & 0xffff) << 16) | ($mul1l & 0xffff); | ||
+ | $mul2 = ((self::MUL1_LO * $zh) & self:: | ||
+ | | ||
+ | | ||
+ | $z = ($hi << 32) | ($lo & self:: | ||
+ | |||
+ | $z ^= ($z >> 27) & self:: | ||
+ | $zl = $z & self:: | ||
+ | $zh = ($z >> 32) & self:: | ||
+ | $lo = self:: | ||
+ | |||
+ | $zll = $zl & 0xffff; | ||
+ | $zlh = $zl >> 16; | ||
+ | $mul1l = $zll * self:: | ||
+ | $mul1h = $zll * self:: | ||
+ | $mul1 = (($mul1h & 0xffff) << 16) | ($mul1l & 0xffff); | ||
+ | |||
+ | $mul2 = (self:: | ||
+ | $carry = ($lo >> 32) & self:: | ||
+ | $hi = $mul1 + $mul2 + $carry; | ||
+ | $z = ($hi << 32) | ($lo & self:: | ||
+ | |||
+ | return $z ^ (($z >> 31) & self:: | ||
} | } | ||
+ | } | ||
+ | |||
+ | $xs128pp = new \XorShift128Plus(1234); | ||
+ | |||
+ | // Benchmarking | ||
+ | for ($i = 0; $i < 1000000000; $i++) { | ||
+ | $xs128pp-> | ||
} | } | ||
</ | </ | ||
- | Each RNG is implemented as a class in the Random\NumberGenerator namespace. They all implement | + | Compare |
- | The bundled RNGs are as follows: | + | | ^ PHP - XorShift128+ (iter:1000000000) ^ PHP - MtRand (savvot/ |
+ | ^ PHP 8.1 | 0m3.218s | ||
+ | ^ PHP 8.1 with JIT | 0m1.836s (64M buffer) | ||
- | * Random\NumberGenerator\XorShift128Plus: | + | Native implementation is much faster than userland ones, even with JIT enabled. |
- | * Random\NumberGenerator\MT19937: | + | |
- | * Random\NumberGenerator\Secure: | + | |
- | Random class use a XorShift128+ by default. It can generate 64-bit values, is used by major browsers, and is fast and reliable. | + | More about this can be read here: https:// |
- | However, when used XorShift128+ in a 32-bit environment, | + | |
- | Secure is practically equivalent to random_int() and random_bytes(), | + | ===== Proposal ===== |
- | This class also supports RNGs defined | + | Create a single Randomizer class which provides various randomization methods (like get int/bytes, shuffle string/ |
+ | |||
+ | I believe this proposal has the following benefits. | ||
+ | |||
+ | === Swapping RNG Based on Environment === | ||
+ | |||
+ | The appropriate RNG can be selected depending on the environment. | ||
+ | |||
+ | For example, say you want to use PRNG with a seed in development, | ||
<code php> | <code php> | ||
+ | $rng = $is_production | ||
+ | ? new Random\Engine\Secure() | ||
+ | : new Random\Engine\PCG64(1234); | ||
+ | |||
+ | $randomizer = new Random\Randomizer($rng); | ||
+ | $randomizer-> | ||
+ | </ | ||
- | class UserDefinedRNG implements | + | === Fixed Random |
- | { | + | |
- | | + | Processes that continue to generate random numbers until certain requirements are met may make it difficult to measure the processing load. |
- | + | ||
- | public function generate(): int | + | <code php> |
- | | + | $required_result |
- | return ++$this-> | + | while (($generated = mt_rand(1, 100)) !== $required_result) { |
- | | + | |
} | } | ||
- | function foobar(Random | + | echo " |
- | | + | </ |
- | | + | |
+ | Interface and dynamic injections, allowing for the fixed sequences at test time. | ||
+ | |||
+ | <code php> | ||
+ | $engine = new class () implements Random\Engine | ||
+ | | ||
+ | | ||
+ | | ||
+ | return pack(' | ||
} | } | ||
+ | }; | ||
+ | $randomizer = new Random\Randomizer($engine); | ||
+ | |||
+ | $required_result = $randomizer-> | ||
+ | while (($generated = $randomizer-> | ||
+ | echo " | ||
} | } | ||
- | foobar(new Random(new UserDefinedRNG())); // Results: 123456789 | + | echo " |
</ | </ | ||
- | Also, as with MT, various alternative APIs using Random | + | === Cryptographically Secure |
- | <code c> | + | Shuffling strings and arrays using CSPRNG |
- | /* similar php_mt_rand() */ | + | |
- | uint64_t php_random_next(php_random *php_random, | + | |
- | /* similar php_mt_rand_range() */ | + | <code php> |
- | zend_long php_random_range(php_random *php_random, | + | $engine = new Random\Engine\Secure(); |
+ | $randomizer = new Random\Randomizer($engine); | ||
- | /* similar php_array_data_shuffle() */ | + | $items = range(1, 10); |
- | void php_random_array_data_shuffle(php_random *php_random, zval *array); | + | $items = $randomizer-> |
- | + | ||
- | /* similar php_string_shuffle() */ | + | |
- | void php_random_string_shuffle(php_random *php_random, | + | |
</ | </ | ||
- | The Random | + | === State safe === |
+ | |||
+ | Since the scope is limited to the engine instance, unintentional state changes caused by things such as external packages and Fiber are completely prevented. | ||
+ | |||
+ | ==== Approach ==== | ||
+ | |||
+ | Implement the following new interfaces and classes. | ||
+ | |||
+ | === interface | ||
+ | |||
+ | Interface to provide random number generator engine. | ||
+ | |||
+ | It has a single < | ||
+ | |||
+ | If you implement a random number generator in PHP, the generated numbers must be converted to binary | ||
+ | |||
+ | Engine:: | ||
+ | |||
+ | However, if a string of 64-bit or greater is returned, it may be truncated for internal processing reasons. This currently applies only to user-defined classes. | ||
+ | |||
+ | === interface Random\CryptoSafeEngine === | ||
+ | |||
+ | A marker interface to indicate that the implemented random number generator is cryptographically secure. | ||
+ | |||
+ | === interface Random\SerializableEngine === | ||
+ | |||
+ | An interface indicating that the implemented random number generator | ||
+ | |||
+ | The following methods must be implemented: | ||
+ | |||
+ | * < | ||
+ | * < | ||
+ | |||
+ | === class Random\Engine\CombinedLCG === | ||
+ | |||
+ | Generate random numbers using the CombinedLCG algorithm. | ||
+ | |||
+ | By passing a value to the constructor, it can be seeded with any value. If omitted or null, the seed value is generated by CSPRNG. | ||
+ | |||
+ | The following interfaces are implemented: | ||
+ | |||
+ | * < | ||
+ | * < | ||
+ | |||
+ | The following methods are implemented: | ||
+ | |||
+ | * < | ||
+ | * < | ||
+ | * < | ||
+ | * < | ||
+ | |||
+ | The values generated by calling CombinedLCG:: | ||
<code php> | <code php> | ||
- | // serialize | + | $seed = 1234; |
- | $foo = new Random(new | + | |
- | for ($i = 0; $i < 10; $i++) { $foo->nextInt(); } | + | $engine |
- | var_dump(unserialize(serialize($foo))->nextInt() === $foo-> | + | var_dump(bin2hex($engine->generate())); // " |
+ | var_dump(bin2hex($engine->generate())); // " | ||
- | // can't serialize | + | // same seed results in same sequence of results. |
- | $foo = new Random(new | + | $engine |
- | for ($i = 0; $i < 10; $i++) { $foo->nextInt(); } | + | var_dump(bin2hex($engine->generate())); // " |
- | var_dump(unserialize(serialize($foo))->nextInt() === $foo-> | + | var_dump(bin2hex($engine->generate())); // " |
</ | </ | ||
- | It is not possible | + | === class Random\Engine\MersenneTwister == |
+ | |||
+ | Generate random numbers using the MT19937 (a.k.a Mersenne Twister) algorithm. | ||
+ | |||
+ | By passing a value to the constructor, | ||
+ | The second argument, passing MT_RAND_PHP, | ||
+ | |||
+ | The following interfaces are implemented: | ||
+ | |||
+ | * < | ||
+ | * < | ||
+ | |||
+ | The following methods are implemented: | ||
+ | |||
+ | * < | ||
+ | * < | ||
+ | * < | ||
+ | * < | ||
+ | |||
+ | The values generated by calling MersenneTwister:: | ||
<code php> | <code php> | ||
- | $foo = new Random(); | + | $seed = 1234; |
- | // can't direct clone | + | $engine = new \Random\Engine\MersenneTwister($seed); |
- | // $bar = clone $foo; | + | var_dump(bin2hex($engine-> |
+ | var_dump(bin2hex($engine-> | ||
- | // safe | + | // same seed results in same sequence of results. |
- | $bar = new Random(clone $foo->getNumberGenerator()); | + | $engine |
+ | var_dump(bin2hex($engine->generate())); // " | ||
+ | var_dump(bin2hex($engine-> | ||
</ | </ | ||
- | Using this feature, the first example | + | === class Random\Engine\PCG64 === |
+ | |||
+ | Generate random numbers using the PCG64 (Permuted Congruential Generator, pcg_oneseq_128) algorithm. | ||
+ | |||
+ | By passing a value to the constructor, | ||
+ | A string can also be passed | ||
+ | |||
+ | The following interfaces are implemented: | ||
+ | |||
+ | * < | ||
+ | * < | ||
+ | |||
+ | The following methods are implemented: | ||
+ | |||
+ | * < | ||
+ | * < | ||
+ | * < | ||
+ | * < | ||
+ | * < | ||
+ | |||
+ | PCG64:: | ||
+ | |||
+ | The values generated by calling PCG64:: | ||
<code php> | <code php> | ||
- | echo foo(1234, function (): void {}) . PHP_EOL; // Result: 1480009472 | + | $seed = 1234; |
- | echo foo(1234, function (): void { mt_rand(); }) . PHP_EOL; // Result: 1480009472 | + | |
- | function foo(int | + | $engine |
- | $random | + | var_dump(bin2hex($engine->generate())); // " |
- | $result = $random->nextInt(); | + | var_dump(bin2hex($engine-> |
- | $bar(); | + | |
- | $result += $random->nextInt(); | + | // same seed results in same sequence of results. |
- | | + | $engine |
- | } | + | var_dump(bin2hex($engine->generate())); // " |
+ | var_dump(bin2hex($engine-> | ||
</ | </ | ||
- | ===== Future Scope ===== | + | === class Random\Engine\Secure |
- | This RFC will be the basis for making PHP RNGs safe in the future. | + | Secure:: |
- | By first accepted this RFC, PHP gets a random | + | Random |
- | The Random class can also be used when new features | + | The following interfaces |
- | More in the future, | + | * < |
+ | * < | ||
+ | |||
+ | The following methods are implemented: | ||
+ | |||
+ | * < | ||
+ | * < | ||
+ | |||
+ | The sequence generated by Secure:: | ||
+ | |||
+ | === final class Random\Randomizer === | ||
+ | |||
+ | A single class for processing with random numbers using the engine. | ||
+ | |||
+ | The following methods are implemented: | ||
+ | |||
+ | * < | ||
+ | * < | ||
+ | * < | ||
+ | * < | ||
+ | * < | ||
+ | * < | ||
+ | * < | ||
+ | * < | ||
+ | |||
+ | The engine in the constructor is optional, and if it is omitted, Secure is automatically used. | ||
+ | |||
+ | This class is serializable, | ||
+ | |||
+ | The Randomizer calls the $this-> | ||
+ | |||
+ | Randomizer methods are fully reproducible in any environment as long as the result of Engine:: | ||
+ | |||
+ | However, if Randomizer:: | ||
+ | |||
+ | The engines implement a specific well-defined random number generator. | ||
+ | For a given seed it is guaranteed that they return the same sequence | ||
+ | For the Randomizer it is considered a breaking change if the observable behavior of the methods changes. | ||
+ | For a given seeded engine and identical method parameters the following must hold: | ||
+ | |||
+ | * The number of calls to the Engine:: | ||
+ | * The return value remains the same for a given result retrieved from Engine:: | ||
+ | |||
+ | Any changes to the Randomizer that violate these guarantees require a separate RFC. | ||
+ | |||
+ | ===== PRNG shootout ===== | ||
+ | |||
+ | Since MT19937 has the aforementioned problems, an alternative algorithm must be chosen. | ||
+ | |||
+ | When introducing a new RNG algorithm, the selection of the algorithm is very important. The following table shows the RNG algorithms that I considered | ||
+ | |||
+ | | ^ Generate size ^ State size ^ Performance | ||
+ | ^ MT19937 | ||
+ | ^ XorShift128+ | ||
+ | ^ Xoshiro256++ | ||
+ | ^ Xoshiro256* * | 64-bit | ||
+ | ^ PCG64 (XSL-RR) | ||
+ | |||
+ | MT19937 and XorShift128+ are already widely used, but they have failed several statistical tests and are not recommended for new use. | ||
+ | So I adopted a more modern PRNG called PCG64 which does not have any statistical test problems. | ||
+ | |||
+ | PCG64 is the only implementation of a reproducible RNG, except for MT19937 for compatibility and the special uses User and Secure. | ||
+ | |||
+ | PCG64 (pcg_state_oneseq_128 XSL-RR) looked like a good fit since it uses 64-bit wide values. | ||
+ | PCG64 uses 128-bit integers, which cannot be used natively in 32-bit environments and needs to be emulated, | ||
+ | but I think this is not a problem since most environments are now using 64-bit architectures. | ||
+ | |||
+ | I also considered Xoshiro256** but chose PCG because all of the issues raised against PCG64 appeared to have been resolved appropriately. | ||
+ | The issues raised and the inventor' | ||
+ | |||
+ | * https:// | ||
+ | * https:// | ||
+ | |||
+ | It is interesting to note that these algorithms have been heavily criticized by each other. | ||
+ | Both opinions were respectable, | ||
+ | |||
+ | I considered implementing both but adding unnecessary choices would have caused confusion for the users so the idea was dropped. If anyone thinks one is needed it can be added through PHP extensions. | ||
+ | |||
+ | ===== Internal Changes ===== | ||
+ | |||
+ | As a side effect of this RFC, the following PHP functions have been moved to the new ext/random extension. | ||
+ | |||
+ | * lcg_value() | ||
+ | * srand() | ||
+ | * rand() | ||
+ | * mt_srand() | ||
+ | * mt_rand() | ||
+ | * random_int() | ||
+ | * random_bytes() | ||
+ | |||
+ | The following internal APIs will also be moved to the ext/random extension: | ||
+ | |||
+ | * php_random_int_throw() | ||
+ | * php_random_int_silent() | ||
+ | * php_combined_lcg() | ||
+ | * php_mt_srand() | ||
+ | * php_mt_rand() | ||
+ | * php_mt_rand_range() | ||
+ | * php_mt_rand_common() | ||
+ | * php_srand() | ||
+ | * php_rand() | ||
+ | * php_random_bytes() | ||
+ | * php_random_int() | ||
+ | |||
+ | This is because ext/ | ||
+ | |||
+ | The following header files are left in for extension compatibility. | ||
+ | |||
+ | * ext/ | ||
+ | * ext/ | ||
+ | * ext/ | ||
+ | * ext/ | ||
+ | |||
+ | The contents all include ext/ | ||
+ | |||
+ | <code c> | ||
+ | #include " | ||
+ | </ | ||
+ | |||
+ | ===== Future Scope ===== | ||
+ | |||
+ | These are not within the scope of this RFC, but are worth considering in the future: | ||
+ | |||
+ | * Remove old header files for compatibility (php_lcg.h, php_rand.h, php_mt_rand.h, | ||
+ | * Deprecate lcg_value(), | ||
===== Backward Incompatible Changes ===== | ===== Backward Incompatible Changes ===== | ||
- | The following class name will no longer be available: | ||
- | - " | + | The following names have been reserved and will no longer be available |
- | | + | |
- | | + | |
- | | + | |
- | | + | * Random\CryptoSafeEngine |
- | | + | |
+ | * Random\Engine\CombinedLCG | ||
+ | | ||
+ | | ||
+ | * Random\Engine\Secure | ||
+ | * Random\Randomizer | ||
===== Proposed PHP Version(s) ===== | ===== Proposed PHP Version(s) ===== | ||
- | 8.1 | + | 8.2 |
- | + | ||
- | ===== FAQ ===== | + | |
- | ==== ==== | + | |
===== RFC Impact ===== | ===== RFC Impact ===== | ||
Line 285: | Line 563: | ||
==== To Existing Extensions ==== | ==== To Existing Extensions ==== | ||
- | none | + | In the future, it may be necessary to change the included header files to point to ext/ |
==== To Opcache ==== | ==== To Opcache ==== | ||
Line 300: | Line 578: | ||
===== Vote ===== | ===== Vote ===== | ||
- | Voting opens 2021-MM-DD and 2021-MM-DD at 00: | + | Voting opens 2022-06-14 and 2022-06-28 at 00: |
- | <doodle title=" | + | <doodle title=" |
* Yes | * Yes | ||
* No | * No | ||
Line 308: | Line 586: | ||
===== Patches and Tests ===== | ===== Patches and Tests ===== | ||
- | * https:// | + | * https:// |
+ | |||
+ | ===== Errata ===== | ||
+ | |||
+ | ==== Follow Up RFC: Random Extension Improvement ==== | ||
+ | |||
+ | The [[rfc: | ||
+ | |||
+ | ==== Split of Randomizer:: | ||
+ | |||
+ | The parameter-less variant of < |
rfc/rng_extension.1624659911.txt.gz · Last modified: 2021/06/25 22:25 by zeriyoshi