你如何生成一个非常大的随机数?我正在思考2 ^ 10 ^ 9(十亿位)的顺序。任何编程语言 - 我认为该解决方案将转换为其他语言。
我想在[1,N]上进行统一分配。
我最初的想法:
- 您可以随机生成每个数字并连接。问题:即使非常好的伪随机生成器也可能开发出数百万个数字的模式,对吗?
您可以通过将随机数提高到随机指数来帮助创建大型随机数。问题:你必须使数学工作,以便得到的数字仍然是随机的,你应该能够在合理的时间内(比如一小时)计算它。
如果有帮助,您可以尝试在可能更小的范围(例如,使用实数)和变换上生成可能不均匀的分布。问题:这可能同样困难。
有什么想法吗?
答案 0 :(得分:4)
生成log2(N)
个随机位以获得数字M
,
其中M
可能是N
的两倍。
重复,直到M
在[1;N]
范围内。
现在要生成随机位,您可以使用真正的随机源,这很昂贵。
或者您可以使用一些加密安全的随机数生成器,例如带有随机密钥的AES,为后续的比特块加密计数器。加密安全意味着没有明显的模式。
答案 1 :(得分:2)
NTL: A Library for doing Number Theory
这是我的编码理论和密码学教师所推荐的...所以我猜它能正常工作,并且它非常易于使用。
RandomBnd,RandomBits,RandomLen - 用于生成伪随机数的例程
ZZ RandomLen_ZZ(long l);
// ZZ = psuedo-random number with precisely l bits,
// or 0 of l <= 0.
答案 2 :(得分:2)
这取决于您需要的数据。在大多数情况下,PRNG快速而简单。但它们并不完美。例如,我记得听说蒙特卡洛斯对混沌系统的模拟非常善于揭示PRNG中的基本模式。
如果那是你正在做的事情,那么我在研究生院学到了一个简单的技巧,可以产生大量的随机数据。拿一个大的(最好是快速变化的)文件。 (来自运行内核的一些大数据结构很好。)压缩它以增加熵。丢掉标题。然后为了更好的衡量,加密结果。如果您计划将其用于加密目的(并且您没有完整的熵数据集可用),则将其反转并再次加密。
基础理论很简单。信息理论告诉我们,没有冗余的信号和纯随机数据之间没有区别。因此,如果我们选择一个大文件(即大量信号),通过压缩删除冗余,并剥离标题,我们有一个非常好的随机信号。加密在删除工件方面做得非常好。然而,加密算法倾向于以块为前提。因此,如果有人能够,尽管一切都能猜到文件开头发生了什么,那么这些数据就更容易猜到了。但是,然后反转文件并再次加密意味着他们需要知道整个文件和我们的加密,以找到数据中的任何模式。
选择快速变化的数据的原因是,如果数据耗尽并想要生成更多数据,则可以再次返回相同的源。在此过程之后,即使很小的变化也会变成一个基本上不相关的随机数据集。
答案 3 :(得分:0)
如果您有一个随机数生成器,它会生成X位的随机数。并且[X1,X2,... Xn]的连接位创建了你想要的N位数,只要每个X是随机的,我不明白为什么你的大数字对于所有意图都不是随机的和目的。如果标准的C rand()方法不够安全,我肯定还有很多其他库(比如这个线程中提到的那些),其伪随机数是“更随机的”。
答案 4 :(得分:0)
即使非常好的伪随机生成器也可能开发出数百万位数的模式,对吗?
来自the wikipedia on pseudo-random number generation:
可以使用种子状态从任意开始状态开始PRNG。当用该状态初始化时,它将始终产生相同的序列。序列开始重复之前的最大长度由状态的大小决定,以位为单位。但是,由于最大周期的长度可能会随着每个“状态”位的增加而翻倍,因此很容易构建PRNG,其周期足以满足许多实际应用。
您可以通过将随机数提高到随机指数来帮助创建大型随机数
我假设你建议用随机值填充科学记数法的值?
例如:1.58901231 x 10^5819203489
这个问题是你的分布是对数的(或者是指数?:) - 相同的差异,它甚至不是)。你永远不会得到一个设置了第一百万位数的值,但在一列中包含一个数字。
您可以尝试在可能更小的范围内生成可能不均匀的分布(例如,使用实数)并转换
不确定我明白这一点。听起来像指数解决方案一样,有同样的问题。如果你在谈论乘以常数,那么你将得到一个块状分布而不是对数(指数?)。
建议的解决方案
如果您只需要具有良好分布的非常大的伪随机值,请使用具有更大状态的PRNG算法。 PRNG的周期性通常是比特数的平方,因此即使非常大的数字也不需要 许多比特。
从那里,您可以使用您的第一个解决方案:
您可以随机生成每个数字并连接
虽然我建议您使用PRNG返回的全部值(可能是2 ^ 31或2 ^ 32),并使用这些值填充字节数组,然后根据需要将其拆分。否则你可能会丢掉很多随机性。此外,将您的值缩放到某个范围(或使用模数)可能会轻易搞砸您的分布,因此还有另一个原因可以尝试保留PRNG可以返回的最大位数。但是要小心打包你的字节数组中的所有返回的数据,否则你将再次为你的发行版带来笨拙。
但是,这些解决方案的问题在于如何使用随机足够的值填充(大于正常)种子状态。您可以使用标准大小的种子(通过时间或GUID样式填充),并使用较小PRNG的值填充您的大PRNG状态。如果不是关键任务,那么这可能会有用,你的数字的分布情况如何。
如果您需要真正的加密安全随机值,唯一真正的方法是使用自然形式的随机性,例如http://www.random.org/处的随机性。自然随机性的缺点是可用性,以及许多自然随机设备需要一段时间来生成新熵的事实,因此生成大量数据可能会非常慢。
您也可以使用混合物并且是安全的 - 仅自然随机种子(以避免生成缓慢),以及PRNG用于其余部分。定期重新播种。