适当的 PRNG(伪随机数生成器)算法将有一个循环时间,在此期间它永远不会处于相同状态。如果您在从中检索到的数字中公开 PRNG 的整个状态,您将获得一个保证在生成器期间唯一的数字。
执行此操作的简单 PRNG 称为“线性同余” PRNG,它迭代一个公式:
X(i) = AX(i-1)|M
使用正确的因子对,您可以从带有 32 位累加器的简单 PRNG 中获得 2^30(约 10 亿)的周期。请注意,您将需要一个 64 位长的临时变量来保存计算的中间“AX”部分。大多数(如果不是全部)C 编译器都支持这种数据类型。您还应该能够在大多数 SQL 方言中使用数字数据类型来执行此操作。
使用正确的 A 和 M 值,我们可以获得具有良好统计和几何特性的随机数生成器。有一篇由 Fishman 和 Moore 撰写的著名论文。
对于 M = 2^31 - 1,我们可以使用下面的 A 的值来获得一个具有很长周期(2^30 IIRC)的 PRNG。
A的良好价值:
742,938,285
950,706,376
1,226,874,159
62,089,911
1,343,714,438
请注意,这种类型的生成器(根据定义)在密码学上是不安全的。如果你知道它生成的最后一个数字,你就可以预测它接下来会做什么。不幸的是,我认为您不能同时获得加密安全性和保证不可重复性。对于要加密安全的 PRNG(例如Blum Blum Shub),它不能在生成的数字中暴露足够的状态以允许预测序列中的下一个数字。因此内部状态比生成的数量更宽,并且(为了具有良好的安全性)周期将比可以生成的可能值的数量长。这意味着暴露的数字在该期间内不会是唯一的。
出于类似的原因,长周期发电机如Mersenne Twister 也是如此。