目前,我们使用的是内置的随机数生成器,可以用mt_srand()作为种子,但这意味着我们的测试依赖于全局状态.
有没有使用内置的随机数生成器来避免依赖于全局状态,因此在重复性方面不会那么不可靠?
目前,我们使用的是内置的随机数生成器,可以用mt_srand()作为种子,但这意味着我们的测试依赖于全局状态.
有没有使用内置的随机数生成器来避免依赖于全局状态,因此在重复性方面不会那么不可靠?
在PHP8.2中,您可以使用new random extension.
此扩展旨在解决当前在PHP中使用随机数生成器时遇到的某些类型的问题.具体内容如下:
因为随机数生成器(称为"引擎")的状态存储在对象中,所以它们可以作为参数传递,并且不会相互干扰,因为它们不依赖于全局状态.
因此,您可以创建多个随机引擎来实现具有相同或不同种子的Xoshiro256**算法:
$engine_1 = new \Raname\Engine\Xoshiro256 StarStar(1234);
$engine_2 = new \Raname\Engine\Xoshiro256 StarStar(4321); // generates a different sequence than (1).
$engine_3 = new \Raname\Engine\Xoshiro256 StarStar(1234); // generates the same sequence as (1).
这些引擎中的每一个都将生成它们自己的可重现的随机数据序列,而不会干扰彼此的内部状态.
Mersenne Twister随机产生器是1997年最先进的,但mt_rand()
未能通过几个随机性统计测试,例如大挤压和挤压测试.
以下是上的PHP8.2中可用的引擎列表.
这个引擎实现了与当前mt_rand()
版本相同的Mersenne Twister.
Mt19937引擎仍然生成32位(4字节)字节串,因为根据定义,Mt19937是32位引擎.
然而,将其与随机发生器(用于与引擎交互的高级API)相结合,Mt19937引擎能够生成随机64位整数,方法是将引擎的随机性扩展为跨越所请求范围所需的随机度:
$randomizer = new \Random\Randomizer(new \RANDOM\引擎\Mt19937(1234));
$randomizer->getInt(0, 8_000_000_000); // 8 billion requires 64 bit integers
这个引擎实现了Permuted Congruential Generator (pcg_oneseq_128_xsl_rr_64).
PCG是一类简单、快速、空间效率高、统计性能好的随机数生成算法.与许多通用RNG不同,它们也很难预测.
它是伪随机数生成器(PRNG),因此不会生成加密安全的随机序列.
更多信息可在此处找到:https://www.pcg-random.org/
这是另一个伪随机数生成器,因此同样不会生成密码安全的随机序列.
它在PHP中被称为Xoshiro256StarStar
,但通常该算法的名称拼写为‘Xoshiro256**’.这是因为PHP不支持类名称中的字符*
该算法的完整细节可在此处找到:https://prng.di.unimi.it/
该引擎实现了加密安全的PRNG(CSPRNG).它不能是种子,因为它的目的是生成密码应用程序(例如密码重置链接)所需的最高质量、不可猜测的随机性.
按优先顺序排列:
使用Secure
.这是安全的 Select ,除非您知道您有特定的要求.这就是为什么在没有发动机的情况下,这是Randomizer
的默认设置.
如果您的应用程序不需要CSPRNG并且您有严格的性能要求,或者如果您的应用程序要求随机数是可重复的,以获得重现性,则使用Xoshiro256StarStar
或PcgOneseq128XslRr64
.
使用Mt19937
仅用于向后兼容.Xoshiro256**和PcgOneseq128XslRr64在所有可能的指标上都更好.
您还可以 Select 在开发和测试环境中使用可复制的随机数生成器,然后在生产环境中使用加密安全的生成器:
$rng = $is_production
? new \随机\引擎\安全()
: new \RANDOM\Engine\PcgOneseq128XslRr64(1234);
如果默认引擎不足以支持您的用例,您还可以在 用户领域的PHP.
以下是一个基于SHA-1的引擎的简单示例:
<?php
final class Sha1Engine implements \Random\Engine {
public function __construct(private string $state) { }
/**
* Return a random bytestring. The bytestring will be interpreted in little-endian order.
*/
public function generate(): string
{
$this->state = \sha1($this->state, true);
return \substr($this->state, 0, 8);
}
}
这个基于SHA-1的引擎生成的随机性应该相当好,但不能用于安全关键应用程序.必须使用Secure
发动机!