我有一个非常大的范围/数字集,(1..1236401668096),我基本上想要’洗牌’,即随机遍历而不重新访问相同的数字.我将运行一个Web服务,每次请求进入时它都会递增一个计数器并从该范围中拉出下一个“洗牌”号码.该算法必须适应服务器脱机,能够使用计数器的持久值重新启动遍历(类似于如何为伪随机数生成器播种,并获得相同的伪随机数给定种子和你在哪个迭代).
我想知道这样的算法是否存在或是否可行.我已经看过了Fisher-Yates Shuffle,但第一步是“记下从1到N的数字”,这将占用整个范围的TB级存储空间.为每个请求生成一个伪随机数可能会有一段时间,但随着数据库/树变满,碰撞将变得更加普遍并且可能降低性能(根据我的计算,在10亿次点击后已经有0.08%的碰撞几率).对于我的场景,是否有更理想的解决方案,或者这只是一个梦想?
改组的原因是,能够正确猜测序列中的下一个数字可能会导致我的应用程序中出现轻微的DOS漏洞,但也因为表示层看起来更好,数量分布更广(我宁愿不详细了解应用程序的功能.此时我正在考虑使用PRNG并处理冲突或混洗范围切片(从(1..10000000).to_a.shuffle开始,然后,(10000001,20000000).to_a.shuffle等作为每个范围的数字开始耗尽).
任何数学家都有更好的想法/建议吗?
最佳答案 使用/ dev / random位连接PRNG或LFSR序列
有几种算法可以生成具有任意大且已知周期的伪随机数.两个明显的候选者是LCPRNG(LCG)和LFSR,但有更多的算法,如Mersenne Twister.
这些发电机的周期可以很容易地构建,以满足您的要求,然后您就不会发生碰撞.
您可以通过从/ dev / random这样的接口添加10,20或30位加密散列熵来处理PRNG和LFSR的可预测行为.因为已知数字的确定性部分是唯一的,所以如果你重复它的实际随机部分就没有区别.