【发布时间】:2010-11-21 17:50:45
【问题描述】:
我需要替换 PHP 的 rand() 函数,该函数使用强加密随机数生成器。
openssl_random_pseudo_bytes() 函数可让您访问强随机数生成器,但它会将其数据输出为字节字符串。相反,我需要一个介于 0 和 X 之间的整数。
我想关键是将openssl_random_pseudo_bytes() 的输出转换为整数,然后您可以对其进行任何您需要的数学运算。我可以想到一些从字节字符串转换为整数的“蛮力”方法,但我希望得到一些……优雅的东西。
【问题讨论】:
-
mt_rand() 会提供比 rand() 质量更好的随机数,但它的密码强度也不高。
-
小心,这个答案是错误的。更具体地说,“% $range”部分不正确。采取以下场景:您想要生成 1(包括)和 4(不包括)之间的数字(因为您执行 max-min)。 $range = 3。现在 3 不会平均分为 2^8,这意味着 1 将比 3 更常见。要非常小心,你想制作一个安全的随机数生成器,但无意中让它变得不安全,这就是为什么建议使用现有的实现。
-
@chacham15:如果理解正确,在 8 位范围内,您会得到 85 组 [1,2,3] 加上一个 [1,] 剩余,大约 1.17% 为“1”比“2”或“3”更有可能出现,对吧?你将如何解决这个问题?显然,使用现有实现不是一种选择,否则我不会问这个问题。
-
$num = hexdec(bin2hex(openssl_random_pseudo_bytes($length,$s))); $max = pow(2, 8*length); //for clarity, you can replace with a faster bit shift $remainder = $max % $range; $max = $max - $remainder; if ($num > $max){ return crypto_rand($min,$max); } return $min + ($num % $range); -
换句话说,你基本上得到了平均划分到你的范围内的最高数字(这也在随机数生成器的范围内),如果该值高于你必须重新运行该函数。
标签: php random cryptography