即使是非常好的伪随机生成器也可能开发出数百万位数的模式,对吧?
来自关于伪随机数生成的维基百科:
PRNG 可以使用种子状态从任意起始状态开始。此后,当使用该状态初始化时,它将始终产生相同的序列。序列开始重复之前的最大长度由状态的大小决定,以比特为单位。但是,由于添加“状态”的每一位,最大周期的长度可能会加倍,因此很容易构建周期足够长的 PRNG,以用于许多实际应用。
您也许可以通过将随机数提高到随机指数来帮助创建大随机数
我假设您建议使用随机值填充科学计数法的值?
例如:1.58901231 x 10^5819203489
这样做的问题是您的分布将是对数的(或者是指数的?:) - 相同的差异,甚至不是)。您永远不会得到一个包含第百万位数字集的值,但在一个列中包含一个数字。
您可以尝试在可能较小的范围内生成可能不均匀的分布(例如,使用实数)并转换
不确定我是否理解这一点。听起来与指数解决方案相同,但问题相同。如果您正在谈论乘以常数,那么您将得到一个块状分布而不是对数(指数?)分布。
建议的解决方案
如果您只需要具有良好分布的非常大的伪随机值,请使用具有更大状态的 PRNG 算法。PRNG 的周期性通常是比特数的平方,因此即使是非常大的数字也不需要那么多比特。
从那里,您可以使用您的第一个解决方案:
您可以随机生成每个数字并连接
尽管我建议您使用 PRNG 返回的全部值(可能是 2^31 或 2^32),并用这些值填充字节数组,并根据需要将其拆分。否则你可能会丢掉很多随机性。此外,将您的值缩放到一个范围(或使用模数)很容易搞砸您的分布,因此尝试保持 PRNG 可以返回的最大位数还有另一个原因。但是,请小心将返回的位包含在您的字节数组中,否则您将再次在您的分发中引入块状。
但是,这些解决方案的问题是如何用足够随机的值填充(大于正常的)种子状态。您可能能够使用标准大小的种子(通过时间或 GUID 样式的人口填充),并使用来自较小 PRNG 的值填充您的大 PRNG 状态。如果您的数字分布的好坏不是关键任务,这可能会起作用。
如果您需要真正加密安全的随机值,唯一真正的方法是使用自然形式的随机性,例如http://www.random.org/中的随机值。自然随机性的缺点是可用性,而且许多自然随机设备需要一段时间才能生成新的熵,因此生成大量数据可能真的很慢。
您还可以使用混合种子并确保安全 - 仅使用自然随机种子(以避免生成缓慢),其余部分使用 PRNG。定期重新播种。