目前,我们使用的是内置的随机数生成器,可以用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中可用的引擎列表.

\RANDOM\引擎\Mt19937

这个引擎实现了与当前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

\RANDOM\Engine\PcgOneseq128XslRr64

这个引擎实现了Permuted Congruential Generator (pcg_oneseq_128_xsl_rr_64).

PCG是一类简单、快速、空间效率高、统计性能好的随机数生成算法.与许多通用RNG不同,它们也很难预测.

它是伪随机数生成器(PRNG),因此不会生成加密安全的随机序列.

更多信息可在此处找到:https://www.pcg-random.org/

\Raname\Engine\Xoshiro256 StarStar

这是另一个伪随机数生成器,因此同样不会生成密码安全的随机序列.

它在PHP中被称为Xoshiro256StarStar,但通常该算法的名称拼写为‘Xoshiro256**’.这是因为PHP不支持类名称中的字符*

该算法的完整细节可在此处找到:https://prng.di.unimi.it/

\随机\引擎\安全

该引擎实现了加密安全的PRNG(CSPRNG).它不能是种子,因为它的目的是生成密码应用程序(例如密码重置链接)所需的最高质量、不可猜测的随机性.

使用什么引擎?

按优先顺序排列:

  1. 使用Secure.这是安全的 Select ,除非您知道您有特定的要求.这就是为什么在没有发动机的情况下,这是Randomizer的默认设置.

  2. 如果您的应用程序不需要CSPRNG并且您有严格的性能要求,或者如果您的应用程序要求随机数是可重复的,以获得重现性,则使用Xoshiro256StarStarPcgOneseq128XslRr64.

  3. 使用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发动机!

Php相关问答推荐

p a/a/p的x路径 Select ,但不是p somethext a链接/a或某些文本/p>

打印SQL表内容时在DIV内添加断点

Laravel:从匹配的数组数据中获取记录

显示WooCommerce当前产品类别或标签的短代码

在PHP中循环访问多维数组,并按组显示内容

Codeigniter 3中SMTP.office 365.com的截断问题

如何在laravel中添加延迟?

文件::Files()响应返回空对象数组

添加不存在的订单元数据以扩展WooCommerce针对特定产品的管理订单搜索

WooCommerce 以编程方式添加的费用不会持续存在

Filament PHP v3:在禁用的表单字段上,ID 不会写入数据库

如何在 Laravel 迁移中使用日期时间和天数?

在shopware 6.5上可以使用什么事件来判断刚刚支付的订单的状态

当所有对象都属于同一类型时,我可以省略 PHP in_array() 中的 strict 参数吗?

在PHP WordPress插件中使用变量连接路径时的问题解决方法

如何在WooCommerce管理产品列表中显示运输类别列

为什么在 phpunit 的开头测试 PHP_VERSION?

如何使用属性创建属性预设?

NetBeans 不显示中文内容

如何在字符串constant-string-NUMBER-*中获取 NUMBER?