测试 PHP 随机数函数的随机性

admin 2025-11-23 阅读:20 评论:0
随机数生成是指产生不可预测数字的过程,在许多依赖随机性的不确定性应用中发挥着关键作用。一个理想的随机数序列不应具备可预测性。 “真正”的随机数生成可以依赖多种方式,例如掷硬币、掷骰子,甚至基于自然现象的物理过程,如宇宙辐射、大气压力或熔岩...

随机数生成是指产生不可预测数字的过程,在许多依赖随机性的不确定性应用中发挥着关键作用。一个理想的随机数序列不应具备可预测性。

“真正”的随机数生成可以依赖多种方式,例如掷硬币、掷骰子,甚至基于自然现象的物理过程,如宇宙辐射、大气压力或熔岩灯的变化等,这些方法在计算机中极难被模拟或预测。

为此,大多数现代操作系统都尝试提供接近真实随机性的生成器,通常基于硬盘旋转延迟等系统层面的测量机制。为了提升安全性,系统会定期重置随机数生成器的种子,从而防止因休眠、内存访问等事件泄露内部状态或被绕过安全保护。

在实际应用中,操作系统与编程语言的运行时环境通常内置随机数生成器(RNG),通过特定算法结合物理熵源生成伪随机数。由于伪随机数生成器依赖一个初始“种子”,一旦种子值与算法被掌握,整个随机序列都可能被预测。因此,在安全或对随机性要求较高的场景中,选择合适的随机数生成器至关重要。

PHP 中的随机数生成器

PHP 提供了几种生成随机值的方法:rand、mt_rand、random_int、random_bytes、openssl_random_pseudo_bytes 等,其中一些是伪随机数生成器,但它们带有各种属性,使它们彼此不同,并且必须优先于另一个。

随机数生成器无处不在,从简单的电脑游戏到 PIN 码,再到使用随机生成的加密密钥加密的敏感信息。在大多数应用程序中,使用适当的随机数生成器至关重要,以确保恶意行为者无法确定系统内生成的随机数。

所有伪随机生成器本质上都依赖于一个 “种子” 值,该值确定使用给定算法生成的所有整个随机数序列。计算机游戏(如 Minecraft)基于单个种子值构建整个游戏世界。为了构建一个相同的游戏世界,只需要初始种子。

PHP 中可用的随机数生成器在实现方式以及它们在依赖生成器的随机性来确保安全性的应用程序中使用的安全性方面有很大差异。

从 PHP 8.2 开始,PHP 提供了以下随机数生成器:

函数/类可用性笔记

rand

PHP 4 及更高版本

不安全,不适合任何与安全相关的应用程序。自 PHP 7.1 起为 mt_rand 的别名

mt_rand

PHP 4 及更高版本

使用 Mersenne Twisterwhatsapp网页版,在 PHP 7.1 中有所改进,但本质上仍不安全

lcg_value

PHP 4 及更高版本

返回 0 到 1 之间的浮点数(包括 0 和 1),加密不安全

random_int

PHP 7.0 及更高版本

推荐使用,因为它在加密上是安全的

random_bytes

PHP 7.0 及更高版本

推荐使用,如果系统熵不足会失败,不会回退到不安全算法

openssl_random_pseudo_bytes

OpenSSL 和 PHP 5.3 及更高版本

可用于获取加密安全的随机数,但不能保证,因为该函数可能会回退到不安全的算法

Random\Engine\Mt19937

PHP 8.2 及更高版本

mt_rand 的面向对象接口

Random\Engine\PcgOneseq128XslRr64

PHP 8.2 及更高版本

置换同余生成器实现

Random\Engine\Xoshiro256StarStar

PHP 8.2 及更高版本

Xoshiro PRNG(伪随机数生成器)实现

测量 PHP PRNGs 中的随机性

测量随机数生成器随机性的最简单方法之一是可视化产生的值以观察模式。

使用 PHP 的 GD 扩展,可以通过在随机的 X 和 Y 坐标上放置单个像素来绘制图像。在预先确定的尝试次数上,像素分布大致均匀的图像表示随机数生成器接近“真实”RNG。如果种子保持不变,则纯粹基于种子值生成值的 RNG(例如 Mersenne Twister)应生成相同的输出。

// 将测试函数命名为输出图像文件的名称
$test_name = 'random_int';
$size = 250;
$random_function = static function(int $max) {
    return random_int(0, $max);
};
// 创建一个指定 $size 的空白正方形图像
$im = imagecreatetruecolor($size, $size);
$white = imagecolorallocate($im, 255, 255, 255);
$black = imagecolorallocate($im, 0, 0, 0);
// 将图像填充为白色
imagefill($im, 0, 0, $white);
$iterations = $size ** 2;
for ($i = 0; $i < $iterations; $i++) {
    $x = $random_function($size);
    $y = $random_function($size);
    imagesetpixel($im, $x, $y, $black);
}
imagepng($im, $test_name . '.png', 0);
imagedestroy($im);

random_int 函数是 CSPRNG(加密安全伪随机数生成器),自 PHP 7.0 起可用。如果它无法产生具有足够随机性的数字的衰老,则会引发 Exception,并且不会回退到任何不安全的 RNG 源。

此外,无法更改此 RNG 的种子值,这是在 PHP 中获取随机数和字节的推荐方法,即使对于加密作也是如此。

random_int / random_bytes

$random_function = static function(int $max) {
    return random_int(0, $max);
};

使用上面的代码段来可视化随机性,random_int 函数会生成类似于以下内容的图像:

“random_int”函数随机性的可视化,显示从 RNG 返回的均匀分布值

PHP 8.2 的新功能: 在 PHP 8.2 中,还可以使用 Random\Engine\Secure 引擎将 random_int 和 random_bytes PRNG 与 scoped 和 OOP API 一起使用。PHP 8.2 中有更详细的示例:新的随机扩展 - 使用示例mt_rand 函数和 Random\Engine\Mt19937 引擎

Mersenne Twister 是 PHP 中可用的伪随机数生成器。它的 seed 值是可配置的,但 PHP 在开始时会用足够随机的种子来设定它的种子。

$random_function = static function(int $max) {
    return mt_rand(0, $max);
};

“mt_rand”函数随机性的可视化,显示从 RNG 返回的均匀分布值

Mersenne Twister RNG 与混合/硬件方法之间的一个主要区别是随机数的整个序列都取决于种子。PHP 的 mt_srand 用于为 RNG 设定种子。Mersenne Twister 为同一种子生成相同的随机数序列。

当应用程序/游戏需要基于单个种子(例如 Minecraft)生成值时,这种确定性性质非常有用。但是telegram中文版,对于需要生成随机数以进行加密的应用程序来说,Mersenne Twister 是一个糟糕的选择,因为 RNG 的内部状态可以通过观察 RNG 产生的随机数序列来推导出来。

为了可视化这一点,使用 mt_rand() 函数生成以下三个。其中两个使用 $seed = 42,最后一个使用 $seed = 43:

mt_srand($seed);
$random_function = static function(int $max) {
    return mt_rand(0, $max);
};

为了更好地可视化相似之处和不同之处,使用 imagefilledrectangle() 函数生成了以下图像,以绘制填充矩形而不是单个像素。矩形的颜色也是随机选择的。

种子值示例说明图示

$seed = 42(第一次运行)

只要种子值相同,生成的随机数序列就保持不变。

$seed = 42(第二次运行)

只要种子值相同,生成的随机数序列就保持不变。

$seed = 43

即使更改种子值一个字节也会产生完全不同的随机数系列。

rand 功能

从 PHP 7.1 开始,PHP 的 rand 函数在后台使用 MT,结果与 mt_rand 函数相同。然而,在 PHP 7.0 之前,rand 函数产生了更可预测和重复的随机数流,这使得它与真正的随机数生成器相去甚远。

$random_function = static function(int $max) {
    return rand(0, $max);
};

可视化 'rand' 函数,具有可见的可预测模式

在 PHP 7.1 及更高版本中使用 rand 必然是坏的,因为它无论如何都会使用 mt_rand。但是,要确保静态分析器不会标记 rand 的使用,请考虑迁移到 random_int。

lcg_value 功能

lcg_value() 是一个组合线性同余生成器 ,它返回一个介于 0 和 1 之间的伪随机数。此函数也不被视为加密安全的伪随机数生成器。

$random_function = static function(int $max) {
    return abs((int) (lcg_value() * $max));
};

可视化“lcg_value”功能,具有看似随机的噪声且没有可见的模式

Random\Engine\PcgOneseq128XslRr64 和 Random\Engine\Xoshiro256StarStar

在 PHP 8.2 中,大多数 RNG 函数被移动到一个名为 random 的新扩展中。它引入了一个新的 \Random\Randomizer 类,以及四个作为 PHP 类的 RNG 引擎。

使用新的随机扩展添加的两个新 PRNG 是 PcgOneseq128XslRr64(置换同余生成器实现)和 Xoshiro256StarStar(Xoshiro PRNG 实现)。它们都类似于 Mersenne Twister,因为它们都只依赖于初始种子值,只要种子值保持不变,就可以用作确定性数字流。

PRNG 算法$seed = 42(第一次运行)$seed = 42(第二次运行)$seed = 43

可视化说明

只要种子值相同,生成的随机数序列就保持不变。

只要种子值相同,生成的随机数序列就保持不变。

即使更改种子值一个字节也会产生完全不同的随机数系列。

PcgOneseq128XslRr64

Xoshiro256StarStar

PHP 提供了几个随机数生成器,选择正确的随机数生成器很重要,尤其是当涉及到随机数流的不可预测性很重要的应用程序时。一些 RNG,比如 PHP 7.1 之前的 rand() 本质上是不安全和可预测的。

PHP 8.2 除了现有的 Mersenne Twister(带有带有 Mt19937 的 OOP API)之外,还提供 Xoshiro256StarStar 和 PcgOneseq128XslRr64 作为两个额外的 RNG。

并非所有 RNG 都适用于加密安全伪随机数生成器 (CSPRNG)。在 PHP 7.0 之前,OpenSSL 扩展的 openssl_random_pseudo_bytes 函数是更好的选择,但即使这样也不理想,因为如果不可能随机数具有足够的熵,它通常会返回 false。此问题后来在 PHP 7.4 中得到修复,在 RNG 失败时抛出异常。

Mersenne Twister、Xoshiro256StarStar 和 PcgOneseq128XslRr64 等 RNG 也有用例whatsapp网页版登录,但由于它们依赖于单个种子值,因此不建议将它们用于任何需要 CSPRNG 的应用程序。

对于所有随机数生成目的,建议使用 random_int 和 random_bytes 函数,因为它会失败并显示异常(而不是静默默认不安全的算法),并且自 PHP 7.0 以来的所有 PHP 版本都支持它。

不使用 RNG 进行加密使用的应用程序可以使用更快的实现,例如 Xoshiro256StarStar。

版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

分享:

扫一扫在手机阅读、分享本文

热门文章
  • 详细指南:WhatsApp国内使用方法全攻略-下载安装、注册登录及功能使用攻略

    详细指南:WhatsApp国内使用方法全攻略-下载安装、注册登录及功能使用攻略
    一、下载与安装WhatsApp WhatsApp是一款全球使用范围极广的即时通讯软件,不仅可以实现文本聊天,还能进行语音、视频通话WhatsApp中文版,发送文件等功能。由于众所周知的原因,国内用户想要下载和安装WhatsApp可能会遇到一些困难。不过,只要按照以下步骤操作,就能顺利完成WhatsApp的下载和安装。 首先,我们需要解决的是下载问题。由于WhatsApp在国内的应用商店无法直接下载,所以我们需要寻找其他的下载途径。Android用户可以选择到各大安卓市场搜索下...
  • 苹果IOS5.1.1机完美越狱

    苹果IOS5.1.1机完美越狱
    越狱工具下载:(需手动复制: http://bbs./read-htm-tid-4804612.html ) 详细的越狱教程: Absinthe 2.0.4的越狱方法与Absinthe 1.0的越狱方法完全一样,非常简单的“傻瓜一键式”。不过这里绿毒有说明,最好重新刷固件。支持越狱设备IOS5.1.1的固件下载地址请点击本站的IOS固件下载,看下图: 下载完固件之后,把设备连接iTunes,开始刷固件。你也可以选择不刷,但是在越狱的过程之中,新的系统在越狱时会比较的顺利,...
  • 电脑微信的聊天照片文件在哪里微信图片保存电脑哪个文件夹

    电脑微信的聊天照片文件在哪里微信图片保存电脑哪个文件夹
    1. 怎么找到微信聊天图片在哪个文件夹里 图片保存路径:/storage/emulated/tencent/MicroMsg/WeiXin/文件夹,这个是完整路径。而在文件夹中只需要找到/tencent/MicroMsg/WeiXinWhatsApp中文版,就可以了,前面两个文件夹是系统根目录。以下是保存及查找图片的方法步骤介绍。 第一步、找到桌面的微信APP,直接点击打开这个微信的APP。 2. 电脑微信图片保存在哪个文件夹 个人微信文件夹。 电脑版微信聊天的图片,都保存到...
  • Windows 11版WhatsApp将从UWP/Native切换回WebView2打包模式

    Windows 11版WhatsApp将从UWP/Native切换回WebView2打包模式
    Meta(最近更名为 Meta AI)悄然宣布,WhatsApp 将在 Windows 11 上放弃 UWP(WinUI)WhatsApp中文版,退回采用基于 Chromium 的容器。这意味着 WhatsApp 又回到了几年前的样子。由于 web.whatsapp.com 一直领先于 Windows 应用开发,它确实拥有一些新功能,但速度更慢,占用更多内存。 如果独立开发者因为无力维护所有平台的代码库而选择 Web 应用程序,那是一回事,但当像 Meta 这样价值万亿美元...
  • 小米下載WhatsApp的完整指南:安装与使用注意事项

    小米下載WhatsApp的完整指南:安装与使用注意事项
    综上所述,确保您的小米手机具备以上条件,将有助于您顺利下载和安装WhatsApp,享受便捷的通讯服务。在满足这些条件后,您就可以按照后续步骤进行WhatsApp的下载和安装。 2. 下载和安装WhatsApp的具体步骤 在小米手机上下载和安装WhatsApp的具体步骤相对简单,但需注意一些特殊情况。首先,确保你的手机系统已更新到最新版本,以保证最佳的兼容性。由于安卓手机商店内无法直接找到WhatsApp,你可以通过APKPure等第三方应用商店进行下载。打开APKPure应用...