使用单个随机数发生器(RNG)生成多个数字与每个发生器生成一个数字并丢弃它之间有区别吗?这两种实现都会产生同等随机的数字吗?普通RNG和安全RNG之间是否存在差异?
我有一个Web应用程序,应该代表客户生成一个随机数列表.也就是说,从每个客户的角度来看,数字应该是随机的.这是否意味着我需要为每个客户会话保留一个单独的随机RNG?或者我可以在所有会话中共享一个RNG吗?或者我可以根据请求创建和丢弃RNG吗?
更新:这个问题与随机序列的子集是否也是随机的有关?
随机数生成器具有状态 - 这实际上是必要的特征.下一个"随机"数字是前一个数字和种子/状态的函数.纯粹主义者称他们为伪随机数发生器.数字将通过随机性的统计测试,但实际上不是随机的.
随机值的序列是有限的并且重复.
可以把随机数生成器想象成一组数字,然后以随机顺序处理它们.种子用于"洗牌"数字.一旦种子被设定,数字序列是固定的并且很难预测.有些种子会比其他种子更早重复.
大多数发电机的周期足够长,没有人会注意到它重复.48位随机数发生器在重复之前将产生数千亿个随机数 - 使用(AFAIK)任何32位种子值.
当你给它一个种子并让它喷出值时,生成器只会生成类似随机的值.如果更改种子,那么与上一个种子生成的值相比,使用新种子值生成的数字可能不会显示为随机 - 当您更改种子时,所有投注都会关闭.所以不要.
一个合理的方法是拥有一台发电机并将数字"交易"给您的各种客户.不要乱用创建和丢弃生成器.不要乱用变种子.
最重要的是,永远不要尝试编写自己的随机数生成器.大多数语言库中的内置生成器都非常好.特别是使用超过32位的现代产品.
一些Linux发行版有一个/dev/random
和/dev/urandom
设备.您可以阅读这些一次,为您的应用程序的随机数生成器播种.它们具有或多或少的随机值,但它们通过随机系统事件"收集噪声"起作用.谨慎使用它们,以便在使用之间有很多随机事件.
我建议多次使用一台发电机.据我所知,所有发电机都有一个状态.种子生成器时,可以根据种子将其状态设置为某个值.如果你继续产生新的种子,你选择的种子可能不会像使用一个生成器生成的数字那样随机.
对于我使用过的大多数生成器来说尤其如此,它使用当前时间(以毫秒为单位)作为种子.
基于硬件的真实[1]随机数生成器是可能的,但非平凡且通常具有较低的平均速率.可用性也是一个问题[2].谷歌搜索"射击噪音"或"放射性衰变"与"随机数发生器"相结合应返回一些命中.
这些系统不需要维护状态.可能不是你想要的.
正如其他人所指出的,软件系统只是伪随机的,必须保持状态.
折衷方案是使用基于硬件的RNG来提供熵池(存储状态),该熵池可用于为PRNG播种.这在/ dev/random [3]和/ dev/urandom [4]的linux实现中非常明确地完成.
这些是关于/ dev/random熵池的默认输入实际上是多么随机的一些论点.
脚注:
以我们对物理学的理解来解决任何问题
因为你在等待随机过程
/ dev/random功能直接访问来自各种来源的熵池,这些来源被认为是真正的或几乎是随机的,当熵耗尽时会阻塞
/ dev/urandom就像/ dev/random,但当entopy耗尽时,会使用加密哈希,这使得熵池有效地成为有状态的PRNG
如果您创建RNG并从中生成单个随机数然后丢弃RNG,则生成的数量仅与用于启动RNG的种子一样随机.
创建一个RNG并从中抽取许多数字会好得多.