javascript - 在 JavaScript 和 AS3 中生成真正唯一的 UUID - PRNG 和底层算法

标签 javascript algorithm actionscript-3 random cryptography

我正在开发一个每天生成大约 20 亿 个唯一 UUID 的系统。 UUID 是在客户端使用 JavaScript\Flash (AS3) 生成的。

我们最近注意到我们的 UUID 几乎是唯一的。我们有大约 20% (!) 的日常重复,其中大部分(相对于流量)来自 chrome。

我做了some reading and learned that the pseudo-random大多数浏览器(尤其是 Chrome)上的 PRNG 算法实现存在缺陷。 Chromium 和 Node.js 使用 V8 javaScript 引擎,该引擎实现了一种称为 MWC1616 的算法。

理论上,使用良好的 PRNG 生成的 UUID 应该具有 2132 probability对于碰撞,但对于 MWC1616,在一些非常现实的场景下,这个概率约为 1:30000。

为了解决这个问题,我考虑了以下选项:

  1. 在服务器上生成 ID(使用 Go)
  2. 通过使用 UUID 散列 IP、UA、时间戳等信息,在客户端生成更强的 ID。
  3. 用更好的随机生成器替换 Math.random()。

因为我更喜欢把东西放在客户端上,我不想重新发明轮子和修改 UUID 创建逻辑,所以我想坚持使用选项 3。

好消息是在较新的浏览器上,有 getRandomValues接口(interface)。不幸的是,我需要支持旧版浏览器。

所以我的问题是:

  1. 什么是好的和可靠的 JavaScript polyfill

crypto.getRandomValues()

(内部不使用 Math.random)?

  1. AS3 Math.random() 是否使用浏览器的 Math.random()?它本身实现了相同的算法吗?

  2. flash.crypto.generateRandomBytes() 是否使用 Math.random()?它使用 crypto.getRandomValues() 吗?如果不是,它实现了哪种算法?对于 AS3 中的同一问题,它会是一个很好的解决方案吗?如果没有,您会推荐哪个 AS3 加密库?

附言我强烈推荐我提到的文章-1- -2- -3- .多年来我一直意识到 Math.random() 的问题,但这篇文章真正让我明白了。

最佳答案

在花了一个多星期的时间对此进行研究之后 - 我的结论是:永远不要在客户端上生成 UUID。只是不要。特别是如果您打算扩展。

多年来,我知道浏览器的 Math.random 实现很糟糕,但直到我们达到每天数十亿事件的规模,我才明白它有多糟糕。

我决定采用最简单的技术解决方案并将 UUID 生成移至服务器。重复 ID 的百分比从每天 ~25% 下降到 ~0.0008%

附言我们的服务器是用 Go 实现的。 Node.js 使用 JavaScript V8 引擎并且可能有同样的问题。虽然看起来如果您使用的是最新的 Node.js,您应该没问题。

关于javascript - 在 JavaScript 和 AS3 中生成真正唯一的 UUID - PRNG 和底层算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42809128/

相关文章:

javascript - Lodash 是否与 _.keys 相反?

algorithm - 通过平铺三角形分割任意多边形

c++ - 这段代码的运行时复杂度是多少?

apache-flex - FLEX, ActionScript : how can I invoke a CustomEvent?

actionscript-3 - 全屏 Flash as3 中的字体模糊

javascript - 防止 History.replaceState 附加到 url

javascript - 函数中的增量值

actionscript-3 - 面向对象 : Bestish Practices: Getting two classes talking each other

javascript - react useState() 数组不更新

algorithm - 必须研究哪些算法才能做出更好的算法