SHA512在PHP中生成随机数

时间:2013-04-03 17:40:25

标签: php random generator sha

我正在使用$blockhash[$i] = rand().time().rand()

填充一个包含随机数的数组

然后,对于该数组中的每个随机数,我计算对应的SHA512

$SecretKey = "60674ccb549f1988439774adb82ff187e63a2dfd403a0dee852e4e4eab75a0b3";
$sha = hash_hmac('sha512', $value, $SecretKey);
拆分它:

$pool  = str_split($sha, 2);

然后我从$ pool数组中获取第一个数字,将hex转换为dec并将其限制在1和50之内:

$dec = hexdec($pool[0]) % 50 + 1;

问题是数字不是随机的,我不知道为什么。我正在计算从1到50的每个数字的频率,但1,2,3,4,5和6的数字经常比其他数字上升。见图

enter image description here

为什么会发生这种情况以及如何解决?谢谢!

3 个答案:

答案 0 :(得分:4)

您要转换为十进制的2个十六进制字符将在0-255范围内。你修改了50并且添加1使得1-6(范围(0-5)+1)在1-256上发生6次而其他每个数字仅发生5次。这将导致这些数字增加约20%。

答案 1 :(得分:1)

rand()mt_rand()都不会生成真正的随机值。

正如手册所述:

  

此函数不会生成加密安全值,也不应用于加密目的。如果您需要加密安全值,请考虑改为使用openssl_random_pseudo_bytes()

请参阅Better Random Generating PHP,了解指出同一问题且有一些好答案的StackOverflow问题。

答案 2 :(得分:1)

由于您从哈希中获取两个十六进制数字,因此您经常会获得1-6个数字。这是一个字节,因此它可以存储从0255的值。然后你使用modulo 50。结果,您获得了范围0-4950-99100-149150-199200-249和... 250-255。最后一个是造成结果中1-6的额外流行的原因。

解决方案:只需使用mt_rand(1,50);

即可

[编辑]

如果你真的需要将0-255范围内的数字转换为1-50范围,那么解决方案就是缩放和舍入。

$number = round(($byteValue)/(255/49))+1;