【问题标题】:Erlang - Random Number GeneratorErlang - 随机数生成器
【发布时间】:2011-02-11 21:57:00
【问题描述】:

我正在使用以下方法来生成一个近似随机数。

3> erlang:ref_to_list(make_ref()).

"#Ref<0.0.0.36>"

我想要的是00036

嗯,这是我在之前的帖子中被告知我可以做的事情。我突然想到,从 make ref 中提取数字并不容易。

任何人都可以展示它是如何轻松完成的,或者可能推荐其他解决方案。

请记住,在相同的几纳秒内调用时,使用 random:seed() 不是随机的。

问候

【问题讨论】:

  • 不要在每次调用随机数生成器时重新播种。播种一次,然后使用它。 random 模块非常适合这个。
  • 你能澄清一下你想要随机数还是唯一数?它们是非常不同的生物,“make_ref”不可能产生随机数。
  • 是的,然后添加您想要使用的随机数,是游戏、模拟还是安全。因为为了安全起见,您需要完全不同的随机数。

标签: random erlang integer


【解决方案1】:

注意:来自 OTP 18 erlang:now/0 random 模块已弃用,OTP 20 将删除 random module。请参阅Time and Time Correction in Erlang 了解更多详情。此外,如果您使用 rand:uniform/0,则不再需要按进程播种。以下内容留作参考。


问题是您错误地使用了randomrandom:seed/0 将始终使用相同的种子为随机数生成器播种。这不适合你想要的。相反,您可以使用random:seed(erlang:now()) 为其添加另一个数字,即当前时间。

“如果两个电话非常接近会发生什么?”你可能会问。嗯,Erlang 的人考虑到了这一点,所以now/0 保证总是返回递增的数字:

返回元组 {MegaSecs, Secs, MicroSecs} 这是 自 1970 年 1 月 1 日(零时)格林威治标准时间 00:00 起经过的时间 假设底层操作系统支持这一点。否则,有些 选择其他时间点。 还可以保证 subse- 对该 BIF 的 quent 调用会返回不断增加的值。 因此,now() 的返回值可用于生成 独特的时间戳,如果它在一个紧密的循环中被调用 快速机器节点的时间可能会出现偏差。

(强调我的)

还请注意,random PRNG 是每个进程的,因此您应该始终使用播种器调用来启动您的进程:

init([..]) ->
  random:seed(erlang:now()),
  [..]
  {ok, #state { [..] }}.

为此使用引用也许是可能的,但我认为它不可行。解决方案超过erlang:ref_to_list/1,它并不漂亮。

【讨论】:

  • 感谢关于 now() 的有趣观点。我正在为我的应用程序计时并获得 1 微秒,你所说的这意味着我的时间可以更快!无论哪种方式,您都可以按照自己的方式编写编辑吗?
  • 你还没有说你想要一个唯一的值(没有其他人有这个值)还是随机的(没有人可以轻易猜到这个值)。此外,您还没有说明在多大程度上需要随机性。您可能需要详细说明这些事情 - 否则人们无法帮助您。
  • +1 表示“PRNG 是每个进程”。这实际上是我正在寻找的信息。
  • 要获得更多随机和安全的种子,您应该使用crypto:strong_rand_bytes/1
  • 对于 OTP 18 及更高版本,只需使用 rand:uniform/0。它自动播种,不仅使用时间相关值,还使用所有其他单调递增的数字生成器。请记住 erlang:now/0 已被弃用。有关详细信息,请参阅erlang.org/doc/apps/erts/time_correction.html
猜你喜欢
  • 2011-06-25
  • 2023-01-03
  • 1970-01-01
  • 2015-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-05
相关资源
最近更新 更多