当前位置:  开发笔记 > 运维 > 正文

是否存在无状态随机数生成器?

如何解决《是否存在无状态随机数生成器?》经验,为你挑选了4个好方法。

使用单个随机数发生器(RNG)生成多个数字与每个发生器生成一个数字并丢弃它之间有区别吗?这两种实现都会产生同等随机的数字吗?普通RNG和安全RNG之间是否存在差异?

我有一个Web应用程序,应该代表客户生成一个随机数列表.也就是说,从每个客户的角度来看,数字应该是随机的.这是否意味着我需要为每个客户会话保留一个单独的随机RNG?或者我可以在所有会话中共享一个RNG吗?或者我可以根据请求创建和丢弃RNG吗?

更新:这个问题与随机序列的子集是否也是随机的有关?



1> S.Lott..:

随机数生成器具有状态 - 这实际上是必要的特征.下一个"随机"数字是前一个数字和种子/状态的函数.纯粹主义者称他们为伪随机数发生器.数字将通过随机性的统计测试,但实际上不是随机的.

随机值的序列是有限的并且重复.

可以把随机数生成器想象成一组数字,然后以随机顺序处理它们.种子用于"洗牌"数字.一旦种子被设定,数字序列是固定的并且很难预测.有些种子会比其他种子更早重复.

大多数发电机的周期足够长,没有人会注意到它重复.48位随机数发生器在重复之前将产生数千亿个随机数 - 使用(AFAIK)任何32位种子值.

当你给它一个种子并让它喷出值时,生成器只会生成类似随机的值.如果更改种子,那么与上一个种子生成的值相比,使用新种子值生成的数字可能不会显示为随机 - 当您更改种子时,所有投注都会关闭.所以不要.

一个合理的方法是拥有一台发电机并将数字"交易"给您的各种客户.不要乱用创建和丢弃生成器.不要乱用变种子.

最重要的是,永远不要尝试编写自己的随机数生成器.大多数语言库中的内置生成器都非常好.特别是使用超过32位的现代产品.

一些Linux发行版有一个/dev/random/dev/urandom设备.您可以阅读这些一次,为您的应用程序的随机数生成器播种.它们具有或多或少的随机值,但它们通过随机系统事件"收集噪声"起作用.谨慎使用它们,以便在使用之间有很多随机事件.


我不同意大多数语言库都有很好的生成器.C的rand()的大多数实现只是线性同余生成器,只有int的状态值.有很好的库实现,但我不认为与您的编译器捆绑的是质量.除此之外,还有很好的答案.
@phresnel:您的实现不会删除随机数生成器的状态:它们只是以不同方式实现它.递归维护堆栈中的状态.将种子分配给客户端不会删除状态,它只是在其他地方实现它.任何具有种子价值的RNG都是有状态的; 所有算法都使用种子值.

2> Claudiu..:

我建议多次使用一台发电机.据我所知,所有发电机都有一个状态.种子生成器时,可以根据种子将其状态设置为某个值.如果你继续产生新的种子,你选择的种子可能不会像使用一个生成器生成的数字那样随机.

对于我使用过的大多数生成器来说尤其如此,它使用当前时间(以毫秒为单位)作为种子.



3> dmckee..:

基于硬件的真实[1]随机数生成器是可能的,但非平凡且通常具有较低的平均速率.可用性也是一个问题[2].谷歌搜索"射击噪音"或"放射性衰变"与"随机数发生器"相结合应返回一些命中.

这些系统不需要维护状态.可能不是你想要的.

正如其他人所指出的,软件系统只是伪随机的,必须保持状态.

折衷方案是使用基于硬件的RNG来提供熵池(存储状态),该熵池可用于为PRNG播种.这在/ dev/random [3]和/ dev/urandom [4]的linux实现中非常明确地完成.

这些是关于/ dev/random熵池的默认输入实际上是多么随机的一些论点.


脚注:

    以我们对物理学的理解来解决任何问题

    因为你在等待随机过程

    / dev/random功能直接访问来自各种来源的熵池,这些来源被认为是真正的或几乎是随机的,当熵耗尽时会阻塞

    / dev/urandom就像/ dev/random,但当entopy耗尽时,会使用加密哈希,这使得熵池有效地成为有状态的PRNG



4> BoltBait..:

如果您创建RNG并从中生成单个随机数然后丢弃RNG,则生成的数量仅与用于启动RNG的种子一样随机.

创建一个RNG并从中抽取许多数字会好得多.

推荐阅读
手机用户2402851155
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有