如何生成既“随机”又“唯一”的数字?

11

随机数是如何生成的?像Java等语言如何生成随机数,特别是GUIDs是如何生成的?我发现伪随机数生成器等算法使用初始值。

但我需要创建一个随机数程序,其中一旦出现的数字即使系统重新启动也不会重复。我认为我需要在任何地方存储这些值,以便我可以检查数字是否重复,但如果列表超过限制,这将变得太复杂了。


2
你需要一个GUID生成器吗?如果是这样,请告诉我们你所使用的编程语言和操作系统。我们会为你提供相应平台上如何使用GUID库的指导。 - S.Lott
手动生成随机数的方法: - Binary Worrier
@S.Lott:是的,我在Windows XP和C#中使用VS2005。 @Binary Worrier:抱歉,当我发布这个问题时,我没有找到那个stackoverflow的问题。 - SyncMaster
@pragadheesh:我说“几乎”是因为我不确定这个问题是否与您有关,或者那里的答案是否回答了您的问题。 - Binary Worrier
就我个人而言,我认为这是一个不同的(并且非常好的)问题,尽管答案可能会有重叠。 - annakata
一个关于随机数的问题,竟然没有人链接到xkcd吗?我的天啊,这个世界要怎么了!? - Ed James
6个回答

18

首先:如果一个数字保证永远不会重复,那么它并不是很随机。

其次:有很多 PRNG算法

更新:

第三:有一个IETF RFC关于UUID(MS称为GUID),但如果您担心安全性,请注意(U|G)UID不是加密安全的。

更新2:

如果您想在生产代码中实际使用这样的东西(而不仅仅是为了自己的启示),使用现成的库。如果您以前从未做过这样的事情(甚至如果您已经做过了),那么这种代码几乎肯定会出现微妙的错误。

更新3:

这里是.NET GUID文档


+1:我相信这已经涵盖了所有的基础知识,如果这不能回答问题,那就没有什么能回答了 :) - Binary Worrier
有趣的是,由于LCG(http://en.wikipedia.org/wiki/Linear_congruential_generator)仅由先前的值种子化,因此它将创建一个不重复的序列。也就是说,在整个序列重复之前,不会有任何重复。 - Sionide21
1
如果RNG不重复自己,那么它肯定可以是随机的。这仅需要它有一个相等的机会来选择到目前为止未被选择的任何数字。 - MSalters
1
强制执行该约束条件会减少每个生成的数字的熵,并使预测序列中下一个数字变得越来越容易,此时它不再是随机的。 - Hank Gay

3

有很多方法可以生成随机数。通常使用带有种子的伪随机数生成器进行系统/库调用来完成。

但是,还有其他获取随机数的方法,涉及使用专用硬件获取真正的随机数。我知道一些扑克网站使用这种硬件。阅读他们如何做到这一点非常有趣。


这大概是基于观察衰变粒子吧?该死,我的下半个小时就没了。 - annakata
1
可以在其膝部附近放置一些二极管(这个术语用英语怎么说呢?),利用它非常不稳定并且可以随机切换从流过电流到不流过电流的特性来完成。 - Nathan Fellman

0
大多数随机数生成器都有一种“随机”重新初始化种子值的方法(有时称为 randomize)。
如果不可能进行重新初始化,则还可以使用系统时钟来初始化种子。

1
系统时钟是一个不好的想法。如果你在运行一个扑克网站,我可以使用试错法并且非常容易地根据过去几张牌和猜测我们时钟之间的时间差来确定你的种子。 - SillyMonkey

0

0

关于Java编程语言的具体内容:

  • java.util.Random使用线性同余生成器,这种方法不太好
  • java.util.UUID#randomUUID()使用java.security.SecureRandom,这是一种接口,用于各种加密安全的随机数生成器 - 默认情况下基于SHA-1算法。
  • UUIDs/GUIDs不一定是随机的
  • 在网络上很容易找到比java.util.Random更好的随机数生成器实现,例如Mersenne Twistermultiply-with-carry

0

我了解您正在寻找使用C#生成随机数的方法。如果是的话,RNGCryptoServiceProvider就是您要找的。

[编辑]

如果您使用RNGCryptoServiceProvider生成足够长的字节数,它很可能是唯一的,但并不保证。理论上,真正的随机数并不意味着唯一。您掷两次骰子,可能两次都是正面,但它们仍然是随机的。真正的随机!

我想要应用唯一性检查,您只需要自己设计一个机制来记录先前生成的数字的历史记录即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接