微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

什么是PHP的mt_rand最小值以及如何计算32位Linux机器上的32位整数

mt_rand()允许的最小值是多less? 对于32位和64位机器,它是一样的吗? 我怎么能生成一个32位整数使用mt_rand() (注意,它不需要是高度随机的)?

背景我为什么要问:我有一个64位的开发物理服务器和一个32位的生产VPS。 刚刚意识到生产服务器并没有生成全系列的PKs。 为了弄清楚发生了什么,我运行了下面的脚本。 64位机器从来没有(或者至less我从来没有目睹过)匹配,但32位匹配约50%的时间。

<?PHP date_default_timezone_set('America/Los_Angeles'); ini_set('display_errors',1); error_reporting(E_ALL); $count=0; for ($i = 0; $i <= 10000; $i++) { $rand=2147483648+mt_rand(-2147483647,2147483647); //Spans 1 to 4294967295 where 0 is reserved if($rand==2147483649){$count++;} } echo('mt_getrandmax()='.mt_getrandmax().' count='.$count);

产量

mt_getrandmax()=2147483647 count=5034

是否需要调用每个线程或每个进程的srand()C函数来播种随机数?

Windows'rand_s线程安全吗?

我该如何使用/ dev / urandom进行testing?

Java将行添加到文本文件的特定部分

在保持公平分配的同时从/ dev / urandom范围内获取字节

测量dev / urandom效率

机器学习algorithm可以检测数字序列的随机性吗?

boost :: random_device的非Linux实现

在Windows上模拟/ dev / random

Python的SystemRandom / os.urandom总是有足够的熵来encryption

TL; DR:要在整个可能的整数范围内得到一个随机整数,使用:

function random_integer() { $min = defined('PHP_INT_MIN') ? PHP_INT_MIN : (-PHP_INT_MAX-1); return mt_rand($min,-1) + mt_rand(0,PHP_INT_MAX); }

对于PHP 7,你可以使用random_int() 。

在引擎盖下( 1,2 ),PHP是这样做的:

$number = random_number_between_0_and_0x7FFFFFFF_using_Mersenne_Twister; $number = $min + (($max - $min + 1.0) * ($number / (0x7FFFFFFF + 1.0)));

注意$max - $min 。 当max被设置到最高端并且min是任何负值时,发生溢出。 因此,最大范围是PHP_INT_MAX 。 如果你的最大值是PHP_INT_MAX ,那么你的最小值必然是0 。

现在的后面的故事。 PHP实现了32位Mersenne Twister算法。 这给了我们在[0,和2 ^ 31-1)之间的随机整数。 如果你问任何其他的范围,PHP使用简单的合并函数来缩放这个数字。 该分箱功能包括可能导致溢出的减法,以及这个问题。

因此,如果你想得到一个大于PHP中整数的范围,你必须添加间隔,如下所示:

mt_rand(PHP_INT_MIN,PHP_INT_MAX);

请注意, PHP_INT_MIN自PHP 7起可用,因此您需要在此之前为您的环境计算合适的最小值。

另外,请注意,2 ^ 31-1是getrandmax()返回的值。 人们误以为在64位机器上getrandmax()会返回2 ^ 63-1。 这不是真的。 getrandmax()返回算法返回的最大整数,总是2 ^ 31-1。

你可以像这样产生一个32位的整数:

$rand = unpack("l",openssl_random_pseudo_bytes(4));

这是在这里PHP文档中注意到的问题

这在64位Linux上正常工作:

<?PHP printf ("%08xn",mt_rand (0,0xFFFFFFFF)); ?>

但在我们的32位Linux开发服务器上,总是产生00000000 。

在同一台机器上,这个:

<?PHP printf ("%08xn",0xFFFFFFF0)); ?>

似乎总是产生00000000或fffffff2到ffffffff范围内的fffffff2 。 这个:

<?PHP printf ("%08xn",0xFFFFFF00)); ?>

给出最后两位数字变化的数字,依此类推,至少为0xF0000000.

但是,这个:

<?PHP printf ("%08xn",0x7FFFFFFF)); ?>

工作正常

这里添加一个错误报告。

PHP是否正在解决这个问题一直没有任何说法。

在此期间,你可以使用max_rand和你之间​​的mt_rand函数,你应该没问题

用法示例

$rand=mt_rand(1,2147483647)+mt_rand(0,2147483647);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐