我正在使用$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的数字经常比其他数字上升。见图
为什么会发生这种情况以及如何解决?谢谢!
答案 0 :(得分:4)
您要转换为十进制的2个十六进制字符将在0-255范围内。你修改了50并且添加1使得1-6(范围(0-5)+1)在1-256上发生6次而其他每个数字仅发生5次。这将导致这些数字增加约20%。
答案 1 :(得分:1)
正如手册所述:
此函数不会生成加密安全值,也不应用于加密目的。如果您需要加密安全值,请考虑改为使用
openssl_random_pseudo_bytes()
。
请参阅Better Random Generating PHP,了解指出同一问题且有一些好答案的StackOverflow问题。
答案 2 :(得分:1)
由于您从哈希中获取两个十六进制数字,因此您经常会获得1-6个数字。这是一个字节,因此它可以存储从0
到255
的值。然后你使用modulo 50
。结果,您获得了范围0-49
,50-99
,100-149
,150-199
,200-249
和... 250-255
。最后一个是造成结果中1-6的额外流行的原因。
解决方案:只需使用mt_rand(1,50);
[编辑]
如果你真的需要将0-255范围内的数字转换为1-50范围,那么解决方案就是缩放和舍入。
$number = round(($byteValue)/(255/49))+1;