PHP随机字符串生成奇迹般地生成了相同的字符串
因此,我在PHP中有一个相当简单的函数,用于呈现10个字符的长顺序ID:PHP随机字符串生成奇迹般地生成了相同的字符串,php,random,Php,Random,因此,我在PHP中有一个相当简单的函数,用于呈现10个字符的长顺序ID: 函数createReference($length=10) { $characters='ABCDEFGHIJKLMNPQRSTUVWXYZ123456789'; $string=''; 对于($i=0;$i
函数createReference($length=10)
{
$characters='ABCDEFGHIJKLMNPQRSTUVWXYZ123456789';
$string='';
对于($i=0;$i<$length;$i++){
$string.=$characters[rand(0,strlen($characters)-1)];
}
返回$string;
}
但是,今天在第154020条表记录上,它生成了与前一个订单ID相同的10个字符的ID(这是表中的第144258条记录),并尝试插入它。由于我对该列有唯一的限制,因此我收到了一个错误,并收到了来自该列的通知
根据我的计算,上面的脚本创建了不同的可能性
我读过一些关于rand()
和mt_rand()
做不同事情的文章,但这不应该是PHP7.1+的问题。该脚本正在PHP7.3
上运行
那么,我应该现在就买彩票,还是这里使用的伪随机性有什么可预测的?如果是这样的话,什么是更好的分布解决方案?假设rand()
是一个真正的RNG,那么在达到略高于所有可能性的平方根后,生成重复的预期几率达到50%(有关更精确的陈述和公式,请参见“”)。34^10的平方根是45435424,因此远远超过144258,但当然,rand()
远不是一个完美或“真实”的RNG
无论如何,使用rand
或mt\u rand
(而不是像random\u int
这样的加密RNG)生成唯一的随机标识符是个坏主意。根据ID是否必须难以猜测,或者仅ID是否足以授予对资源的访问权限,使用自动递增的记录数而不是随机数可能是更好的主意,也可能不是更好的主意。有关进一步的考虑,请参见我的章节“”
另请参见。假设rand()
是一个真正的RNG,则在达到略高于所有可能性的平方根后,生成副本的预期几率达到50%(有关更精确的语句和公式,请参见“”)。34^10的平方根是45435424,因此远远超过144258,但当然,rand()
远不是一个完美或“真实”的RNG
无论如何,使用rand
或mt\u rand
(而不是像random\u int
这样的加密RNG)生成唯一的随机标识符是个坏主意。根据ID是否必须难以猜测,或者仅ID是否足以授予对资源的访问权限,使用自动递增的记录数而不是随机数可能是更好的主意,也可能不是更好的主意。有关进一步的考虑,请参见我的章节“”
另请参见。偶尔会发生不太可能的事情。@Barmar这不是使用rand()
(非加密安全)和random\u int()
(加密安全)之间的区别吗?我一直在读一些关于加密安全RNG的资料,也许rand()
函数更有可能重新生成同一组数字。这当然是可能的。偶尔会发生一些不太可能的事情。@Barmar这不是使用rand()
(非加密安全)和random\u int()
(加密安全)?我一直在读一些关于加密安全RNG的东西,可能是rand()
函数更有可能重新生成相同的一组数字。这当然是可能的。谢谢,我已经预感到了random\u int
。我现在已经将该函数更改为使用random\u int
。我生成的唯一字符串只是用作用户可读的订单ID,而没有透露任何关于a的详细信息我会看看你们的资源,非常有趣的东西,还有PHP的array_rand()
使用了可能导致类似问题的非CSPRNG。谢谢,我已经预感到了random\u int
。我现在已将函数更改为使用random\u int
。我生成的唯一字符串仅用作用户可读的订单ID,而没有透露以前订单数量的任何详细信息我会看看你们的参考资料,非常有趣的东西,PHP的array\u rand()
如何使用非CSPRNG,这可能会导致类似的问题。