【问题标题】:What is a good, fast PRNG (non-cryptographically secure)什么是好的、快速的 PRNG(非加密安全)
【发布时间】:2009-08-12 13:47:01
【问题描述】:

我正在寻找一种快速的 PRNG,以便我可以快速为对象创建(半)唯一 ID。唯一性更多的是一个管理问题,ID 重复只是在极少数情况下才会出现的问题。

它必须尽可能快,因为性能至关重要,而且是非连续的(如果 ID 是连续的,则更有可能在管理方面发生错误)。另外,我想避免使用较低的数字,但只要重试直到检索到足够高的数字,就可以轻松缓解这种情况。

编辑 我还应该补充一点,我要求 ID 为 32 位,因此 GUID 不起作用并且需要独立于平台(目前正在 PC 上实现,但还需要在 Nintendo DS、PSP、PS3、Wii、Xbox 等上运行平台)。此外,它可能每秒调用数千次,因此基于输入的随机数生成是不可行的。

谢谢

【问题讨论】:

  • 您使用什么语言/系统?
  • @John:那应该对算法影响太大了吧?
  • 所以你想要一个 prng 算法,而不是快速实现。
  • 为什么是随机的?为什么不是顺序的?如果您想要不同,如果只有一个来源,则最后一个加一保证是唯一的。

标签: random


【解决方案1】:

GUIDs?许多环境都支持生成这些。

【讨论】:

    【解决方案2】:

    我不确定我的理解是否正确,但如果您使用的是 Linux 机器,则可以从 /dev/urandom 读取以获取高质量随机数流。这些数字可用于生成您需要的任何长度的字符串。 请记住,要使此解决方案起作用,机器应该接收来自用户(键盘/鼠标)的输入。

    【讨论】:

      【解决方案3】:

      最适合您的 PRNG 的算法是您的编程语言已经提供的任何库。它将有一个经过良好测试的算法,并且可能会很聪明地使用计算机中现有的随机源,例如 /dev/random。

      如果您想要“低数字”,请不要在得到一个之前重试;这将永远持续下去。只需取随机数并根据您的天花板对其进行修改。即:

      random() % 1000000
      

      返回一个介于 0 和 999,999 之间的随机数。

      【讨论】:

      • 但这些通常是一种放慢速度的方法,而且我不需要它是高质量的随机,只要足够随机即可。另外,我正在使用 c++,其中唯一的标准算法是 'rand()',它在许多平台上都被破坏并且可能非常慢。
      • “PRNG 的最佳算法是你的编程语言已经提供的任何库。” - 那个太错误了,甚至都不好笑。您基本上可以参考 PRNG 上的每一个来源来确定。
      【解决方案4】:

      如果你真的只需要非顺序部分,X[i] = (X[i-1] + a) mod b 有什么问题?如果 a 和 b 是互质数,这将与周期 b 重复。这使得 b=2^32 成为一个简单的选择,而 a 可以是任何大于 2 的素数。性能将以 MHz 为单位,而不是 KHz。

      避免使用较小的数字也很简单:使用序列 X[i] = offset + (X[i-1] - offset + a) mod b

      【讨论】:

      • 这不是基本上是顺序的,而是一个步骤吗?
      • 当然。但考虑到这个问题,这可能已经足够好了。重点是:不要过度设计。
      • +1 - 另外,谷歌 'fishman and moore' 为 a 和 b 找到一组好的值。
      【解决方案5】:

      这可能有效:

      自纪元以来的当前时间总和,线程 id 和序号。

      【讨论】:

      • 这是个好主意,并没有真正想到使用线程ID之类的东西。虽然这并非在所有平台上都可用,但我应该能够从分散在系统周围的变量中获取相当多的随机数据(例如当前的扫描行数和从简单的堆栈遍历中获取的值)。
      • 这是一个糟糕的答案,因为它主要是一个顺序流(时间不一定会改变,我不明白为什么线程 id 会改变)跨度>
      • @StevenLu,我同意。那是一个可怕的答案!我什至不记得写过那个......
      【解决方案6】:

      【讨论】:

        【解决方案7】:

        Fishman 和 Moore 写了一篇关于线性同余 PRNG 的论文 (A(x) = A(x-1)|m)。 This posting on Stackoverflow 讨论了这个算法。如果您的平台都可以支持用于中间结果的 64 位累加器(所有现代 C 编译器都应支持 64 位 long long 变量),那么这将简单快速,周期为 2^30,M = 2^31- 1.上面链接的帖子有一些来自 Fishman 和 Moore 论文的良好 A 值。

        【讨论】:

          【解决方案8】:

          试试this。由乔治·马萨利亚提供。

          无法与每秒 20 亿个随机数争论。

          【讨论】:

          • 是的,如果我只需要处理支持 SSE 的处理器,那就太好了。不幸的是,我处理的是 x86(其中许多相当精简到最低限度的功能)、PowerPC、Arm、MIPS 和 Cell 处理器(有时还有其他一些)。
          • 那么,只需使用优化程度较低的 Marsaglia RNG 之一即可。
          【解决方案9】:

          如果问题是某些对象或线程生成的 ID 与其他对象或线程相同,请考虑使用 10k 保留子 ID 填充这些 ID。

          如果您从前一个 id 生成随机 id,这将是同样的问题,因为 prngs 是确定性的。即 id 25653 将始终生成 id 7567832 下一个。总是。

          您可能会考虑仅将 prng 用于非标准 id 生成,例如生成 id 的对象。比如观察这些冲突在什么条件下发生并用prng修复这些情况。其余的可能是安全的。

          【讨论】:

            猜你喜欢
            • 2013-03-03
            • 1970-01-01
            • 2010-11-05
            • 2015-09-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多