我需要在更长的叙述中为多个句子生成唯一的id(多个用户可以在不同的机器上同时执行相同的操作).
我考虑过new Date().getTime()(也许连接一个username)但是因为id是在一个循环中生成而迭代句子,我发现重复创建(因为生成可以在相同的毫秒发生).
所以我现在正在玩:
var random1 = Math.floor((Math.random() * 10000) + 1).toString(36);
var random2 = Math.floor((Math.random() * 10000) + 1);
var random3 = Math.floor((Math.random() * 10000) + 1);
var id = random1 + random2 + random3;
// generates things like:
// 1h754278042
// 58o83798349
// 3ls28055962
Run Code Online (Sandbox Code Playgroud)
但是我想到了(不可否认,作为一个没有考虑过独特/随机/加密问题的人),或许加入三个随机数并不是随机数一个随机数?
生成和连接3个Math.random()值比1 个值更随机Math.random()吗?
这个答案(https://security.stackexchange.com/a/124003)说明:
如果随机生成器确实产生随机数据,那么无关紧要.
但我不确定这是如何适用于Math.random().
编辑:
场景是Web上的客户端而不是安全性,只是为了确保每个句子在数据库中都有唯一的id.
编辑:
我最终实施了:
function guid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
var id = guid();
Run Code Online (Sandbox Code Playgroud)
来自:https://stackoverflow.com/a/105074/1063287
另请参阅对该答案的评论:
实际上,RFC允许从随机数创建的UUID.你只需要旋转几个比特来识别它.见4.4节.从真正随机或伪随机数创建UUID的算法:rfc-archive.org/getrfc.php?rfc = 4122
情况很复杂。
由于您使用随机数生成器的特定方式,第一个字符串可能相同,而第二个或第三个字符串不同。这意味着您生成的唯一字符串比仅调用一次Math.random(). 更独特的字符串意味着更少的碰撞,这正是您的目标。
要确认这一点,只需将大量这些字符串转储到文件中,然后对它们进行排序,看看第二个和第三个值是否始终随第一个值变化,或者它们是否可以独立变化(您需要在输出中添加分隔符看到那个)。
这是 PRNG 状态隐藏方式的产物;在添加了一些内容后,它将停止工作。它应该(不能保证!)经过多次迭代,以至于您无法轻松测试它,所以不要尝试凭经验来解决它。
如果你有一个非常原始的生成器算法,那么你可能会发现只要random1等于 X,那么random2就总是等于 Y,并且random3总是等于 Z;所以如果你在 X 处发生碰撞,那么隐含地 Y 和 Z 也会发生碰撞,所以它们不会有帮助。
但大多数 PRNG(以及代码的结构,因为每次调用只获取 10000 个不同的值)的状态比它们在单个调用中显示的状态大得多。这意味着即使random1是 X,random2并且random3仍然是完全不可预测的,并且它们的存在使得碰撞的可能性较小。
然而,当您到达时,您random100应该开始看到您可以根据所有其他 s 的值猜测它将是什么,randomX并且它不会使字符串变得更加唯一。
然后整个问题就陷入了种子质量和州规模的兔子洞。基本上,随机数生成器可能非常弱,以至于它只能产生多达 40 亿个唯一的字符串,并且在实际情况下可能要少得多。该random()函数并不是为了解决 GUID 问题,因此存在可能会严重失败的风险。