caw*_*caw 17 php security random
PHP的rand()功能不能提供良好的随机数.所以我开始使用mt_rand(),据说可以提供更好的结果.但这些结果有多好?有没有什么方法可以再次改善它们?
我的想法:
function rand_best($min, $max) {
$generated = array();
for ($i = 0; $i < 100; $i++) {
$generated[] = mt_rand($min, $max);
}
shuffle($generated);
$position = mt_rand(0, 99);
return $generated[$position];
}
Run Code Online (Sandbox Code Playgroud)
这应该给你"完美"的随机数,不应该吗?
coo*_*ird 33
伪随机数发生器(PRNG)是非常复杂的野兽.
有没有真正的"完美"的随机数生成器 - 事实上,可以从数学函数来完成最好的是伪随机 - 他们似乎足够的随机对大多数的意图和目的.
实际上,从PRNG返回的数字执行任何其他操作并不会真正增加其随机性,事实上,该数字可能变得不那么随机.
所以,我最好的建议是,不要搞乱从PRNG返回的值.使用足以满足预期用途的PRNG,如果不是,则找到可以产生更好结果的PRNG,如有必要.
坦率地说,看起来这个mt_rand功能使用的是Mersenne twister,它是一个相当不错的PRNG,因此对于大多数休闲用途来说它可能已经足够好了.
但是,Mersenne Twister并非设计用于任何安全环境.有关在需要随机性以确保安全性时使用的解决方案,请参阅此答案.
编辑
评论中有一个问题,为什么对随机数执行操作可以减少随机性.例如,一些PRNG可以在比特的不同部分返回更一致,更少随机的数字 - 高端可以比低端更随机.
因此,在丢弃高端并且返回低端的操作中,该值可以变得比从PRNG返回的原始值更不随机.
我目前找不到一个好的解释,但是我从该Random.nextInt(int)方法的Java文档中找到了解释,该方法旨在在指定范围内创建一个相当随机的值.该方法考虑了值的各部分的随机性差异,因此与更天真的实现相比,它可以返回更好的随机数rand() % range.
Sal*_*ali 25
快速回答:
在新的PHP7中,最终支持加密安全的伪随机整数.
int random_int ( int $min , int $max )
Run Code Online (Sandbox Code Playgroud)
更长的答案
没有完美的随机数生成器,计算机使用伪随机数生成器来创建看起来随机的序列.序列看起来是随机的(并通过一些随机性测试),但由于有一些算法可以生成它,你可以用完全相同的状态重复算法并得到相同的结果.
与加密 "不发明自己的密码" 相同的建议可以转换为随机数生成器,这意味着你不能只是将大量随机数生成器组合在一起并期望得到更好的生成器.
随机数生成器的子集之一是加密安全随机数生成器:
普通PRNG的要求也由加密安全的PRNG满足,但反之则不然.CSPRNG要求分为两组:第一,他们通过统计随机性测试; 其次,他们在严重攻击下保持良好状态,即使他们的初始或运行状态的一部分可供攻击者使用
所以这非常接近你对" 完美 "的定义.在没有条件的情况下再次(除了学习如何进行加密)之外,您应该尝试实现其中一种算法并在系统中使用它.
但幸运的是PHP7实现了它,
int random_int ( int $min , int $max )
Run Code Online (Sandbox Code Playgroud)
生成适用于无偏结果至关重要的加密随机整数(即改组扑克牌组).
随机来源如下:
getrandom(2)系统调用(较新的Linux内核)这使得之前的所有答案都已过时(有些已弃用).
Pet*_*ter 17
我不确定你所做的"改善了"随机性.根据我的理解,您生成100个随机数,然后随机选择其中一个.
从我记忆中的概率过程来看,这可能不会增加随机性,就好像生成器函数中存在潜在的偏差(mt_rand()),然后它仍然会以某种方式反映在输出中.
tru*_*ppo 13
以什么方式mt_rand()"坏"?
例如:如果它有利于某个数字.让我们说mt_rand(1,10)有利于该范围内的低数字,即"1"和"2"平均每个超过10%.那么你的"改进"仍然会遇到同样的问题.
从故障序列中选择随机数仍然有问题.
man*_*oid 12
<?php
function random_number(){
return 4; // return generated number
// guaranteed to be random
}
?>
Run Code Online (Sandbox Code Playgroud)
除了开玩笑之外,你会陷入一个关于什么是"随机"或什么是"最佳"的哲学问题.理想情况下,您希望随机数在整个过程中几乎没有模式.通常系统时间用作种子,但我也使用先前的随机数作为种子,之前的随机数字作为种子.问题是,凭借足够强大的计算机以及对硬件运行和生成器功能的全面了解,您将能够预测生成的整个数字集.因此,如果你有足够强大的计算机(有些人将上帝置于这个类别中)知道宇宙的所有可能的变量和功能,那么你就能够预测发生或将要发生的每一个事件.多数随机数发生器是对自己很好,但如果你知道谁可以看到的图案,他们越有可能喜欢在美丽心灵的家伙,你应该让他们住进了一家诊所.
受欢迎的需求:D
小智 5
我写了一个cronjob,定期从random.org获取1000个数字(比如每小时一次)并将它们添加到PHP数组中.每当我想在我的脚本中使用随机数时,我会使用mt_rand(0,1000)从中调用一个数字.一些额外的微秒开销,但我得到了基于自然大气噪声的真正随机数.