用javascript时间创建一个唯一的数字

IT技术 javascript time numbers unique
2021-03-04 13:52:06

我需要使用 javascript 动态生成唯一的 ID 号。过去,我通过使用时间创建一个数字来做到这一点。该数字将由四位数的年份、两位数的月份、两位数的日、两位数的小时、两位数的分钟、两位数的秒和三位位数的毫秒组成。所以它看起来像这样: 20111104103912732 ...这将为我的目的提供足够的唯一数字的确定性。

我已经有一段时间没有这样做了,而且我没有代码了。任何人都有执行此操作的代码,或者有更好的建议来生成唯一 ID?

6个回答

更好的方法是:

new Date().valueOf();

代替

new Date().getUTCMilliseconds();

valueOf()是“最有可能”的唯一数字。 http://www.w3schools.com/jsref/jsref_valueof_date.asp

它不是一个唯一的数字。毫秒的粒度不足以被认为是唯一的。
2021-05-02 13:52:06
我刚刚运行了一个 for 循环,我得到了重复的结果valueOf()我只是用这个 - +performance.now().toString().replace('.', 7) developer.mozilla.org/en-US/docs/Web/API/Performance/now
2021-05-04 13:52:06
@ItzikBenHutta 获得了相同value的 3 倍。使用多核 CPU,可能是线程的竞争条件。
2021-05-08 13:52:06
或者干脆 +new Date()
2021-05-12 13:52:06

创建一个您可以确定的数字的最短方法在您能想到的尽可能多的独立实例中是唯一的

Date.now() + Math.random()

如果函数调用有 1 毫秒的差异,则100% 保证生成不同的数字对于同一毫秒内的函数调用,如果您在同一毫秒内创建超过几百万个数字,您应该开始担心,这不太可能。

有关在同一毫秒内获得重复数字的概率的更多信息,请参阅https://stackoverflow.com/a/28220928/4617597

这应该是公认的答案,因为在尝试其他更高投票的答案时,从异步函数调用时,我连续获得了 2 倍甚至 3 倍的相同值。这似乎为标准的 8 核 CPU 提供了足够的随机性,可以完全在同一时刻生成 8 个唯一的字符串,足够我使用。
2021-04-21 13:52:06
此外,如果您想保留随机数的所有位,您可以单独生成它们并合并为字符串: new Date().valueOf().toString(36) + Math.random().toString(36).substr (2) 这会给你一个 19 个字符的字母数字字符串,这是一个相当数量的熵。尽管其中一半是可以预测的。
2021-04-26 13:52:06
Date.now() 当这将在简单/快速循环中时,部分将无用
2021-05-07 13:52:06
最好的: Date.now() + '' + Math.random()
2021-05-08 13:52:06
恕我直言,最好的解决方案是使用Math.floor(Date.now() * Math.random()). 如果在循环中只使用 Date.now(),就会有重复项,但 Math.random() 使其独一无二。
2021-05-10 13:52:06

如果你只想要一个独特的数字,那么

var timestamp = new Date().getUTCMilliseconds();

会给你一个简单的数字。但是,如果您需要可读版本,则需要进行一些处理:

var now = new Date();

timestamp = now.getFullYear().toString(); // 2011
timestamp += (now.getMonth < 9 ? '0' : '') + now.getMonth().toString(); // JS months are 0-based, so +1 and pad with 0's
timestamp += ((now.getDate < 10) ? '0' : '') + now.getDate().toString(); // pad with a 0
... etc... with .getHours(), getMinutes(), getSeconds(), getMilliseconds()
@Áxel:我没有说它是独一无二的,我说它是“独一无二的”。当然,使用时间戳生成的客户端会生成欺骗。
2021-04-21 13:52:06
(Math.random().toString().replace('.',Math.random().toString().replace('.',''))) 即使在快速循环中,这也会给出唯一编号
2021-04-22 13:52:06
-1,因为问题是关于唯一编号的。第一个代码块应该完全省略。
2021-04-24 13:52:06
getUTCMilliseconds The value returned by getUTCMilliseconds() is an integer between 0 and 999.这是唯一 id 最糟糕的想法,应该删除第一段。
2021-04-29 13:52:06
时间戳应new Date().getTime();date.getUTCMilliseconds()返回0和999之间的数字date.getTime()返回毫秒因为1月1日1970年(正常时间戳)。w3schools.com/jsref/jsref_obj_date.asp
2021-05-11 13:52:06

这可以通过以下代码简单地实现:

var date = new Date();
var components = [
    date.getYear(),
    date.getMonth(),
    date.getDate(),
    date.getHours(),
    date.getMinutes(),
    date.getSeconds(),
    date.getMilliseconds()
];

var id = components.join("");
如果这在同一毫秒内被调用两次怎么办?
2021-04-21 13:52:06
确实,但对于 op 来说是可以的:“对于我的目的,这将为唯一编号提供足够的确定性。”
2021-05-05 13:52:06

当我想要比一堆数字更小的东西时,我会这样做 - 改变基数。

var uid = (new Date().getTime()).toString(36)
我喜欢这个!我已经对其进行(Date.now() + Math.random()).toString(36)调整以防止毫秒级冲突。它很短,会生成类似“k92g5pux.i36”的内容
2021-05-07 13:52:06
@blushrt 是的,它可能会导致罕见的冲突。您可以使用诸如code.google.com/p/crypto-js 之类的东西对时间戳进行 md5 ,但就我而言,它“足够独特”,更重要的是,速度更快。
2021-05-09 13:52:06
@frumbert,这取决于。MD5 也不抗碰撞。但是在你的情况下,我很快遇到了麻烦,因为 toString(36) 我认为它会将数值转换为它的 ascii 表示,虽然不确定,但我可以看到问题,如果你经常调用你的 uuid 生成器,只有最后 3字符正在发生变化,因此您发生碰撞的可能性很高。如果您坚持使用新的 Date.getTime() 调用,您将获得更好的机会。但是,嘿,如果它适用于您的目的,没问题,我只需要它用于我的客户端代码的一些唯一 ID,最终使用 uuid 节点库。
2021-05-09 13:52:06