【发布时间】:2018-01-19 18:49:35
【问题描述】:
这是我之前提出的问题Is this JS Unique ID Generator Unreliable? (Getting collisions) 的后续问题。
在下面的脚本中,我使用 2 种方法生成 10000 个随机数。方法 1 是高达 10^6 的直接随机数,而方法 2 将高达 10^6 的随机数(与 [1] 中的想法相同)与当前的 JS Date().time() 时间戳连接。还有一种方法 [3],它只对 RNG 进行 Math.round,而不是整个连接结果。
我的问题是,如果您继续单击测试按钮,您会看到 [1] 总是产生 10000 个唯一数字,但 [2] 无论如何都会产生 ~9500 个。 [3] 产生 ~9900 但也不是最大值。这是为什么?从 [0..10^6] 中的前一个随机数获得 +/-1 并将其与时间戳连接的完全相反 +/-1 的时间戳混合的机会是不可能的。我们在一个循环中几乎在同一毫秒内生成。 10^6 是一个巨大的限制,比我原来的问题要大得多,我们知道这是真的,因为方法 [1] 非常有效。
是否存在某种截断,它会修剪字符串并使其更有可能出现重复?矛盾的是,较小的字符串比使用相同 RNG 的较大字符串效果更好。但如果没有截断,我希望结果是 100%,如 [1]。
function run() {
var nums1 = new Set(), nums2 = new Set(), nums3 = new Set();
for (var i = 0; i < 10000; i++) {
nums1.add(random10to6th());
}
for (var i = 0; i < 10000; i++) {
nums2.add(random10to6th_concatToTimestamp());
}
for (var i = 0; i < 10000; i++) {
nums3.add(random10to6th_concatToTimestamp_roundRNGOnly());
}
console.clear();
console.log('Random 10^6 Unique set: ' + nums1.size);
console.log('Random 10^6 and Concat to Date().time() Unique set: ' + nums2.size);
console.log('Random 10^6 and Concat to Date().time(), Round RNG Only Unique set: ' + nums3.size);
function random10to6th() {
return Math.random() * Math.pow(10, 6);
}
function random10to6th_concatToTimestamp() {
return Math.round(new Date().getTime() + '' + (Math.random() * Math.pow(10, 6)));
}
}
function random10to6th_concatToTimestamp_roundRNGOnly() {
return new Date().getTime() + '' + Math.round(Math.random() * Math.pow(10, 6));
}
<button onclick="run()">Run Algorithms</button>
<p>(Keep clicking this button)</p>
【问题讨论】:
-
您可以将数字作为字符串存储为数组的最大值
.length上的数千个(三个元素的组),请参阅How do I add 1 to a big integer represented as a string in JavaScript? -
random10to6th_concatToTimestamp_roundRNGOnly()返回不受精度问题影响的字符串而不是数字。 -
@le_m
Math.round(Math.random() * Math.pow(10, 6))不影响精度问题? -
Math.round(Math.random() * Math.pow(10, 6))比Math.random() * Math.pow(10, 6)更容易发生冲突,因为四舍五入将可能的值集限制为 10^6 个可能值。 -
如果担心随机值的冲突,您可以在结果字符串中包含字母字符;例如,您可以创建和撤销
Blob URLs N 次。另见How would one generate a MAC address in Javascript?
标签: javascript random