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

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

我已经很久没这么做了,我已经没有密码了。任何人都有这样做的代码,或有一个更好的建议,生成一个唯一的 ID?

298752 次浏览

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

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()

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

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


var id = components.join("");

更好的办法是:

new Date().valueOf();

而不是

new Date().getUTCMilliseconds();

ValueOf () “最有可能”是一个唯一的数字。

通过在线调查,我想出了下面这个对象,它可以为每个会话创建一个唯一的 id:

        window.mwUnique ={
prevTimeId : 0,
prevUniqueId : 0,
getUniqueID : function(){
try {
var d=new Date();
var newUniqueId = d.getTime();
if (newUniqueId == mwUnique.prevTimeId)
mwUnique.prevUniqueId = mwUnique.prevUniqueId + 1;
else {
mwUnique.prevTimeId = newUniqueId;
mwUnique.prevUniqueId = 0;
}
newUniqueId = newUniqueId + '' + mwUnique.prevUniqueId;
return newUniqueId;
}
catch(e) {
mwTool.logError('mwUnique.getUniqueID error:' + e.message + '.');
}
}
}

也许对某些人有帮助。

干杯

安德鲁

这应该可以:

var uniqueNumber = new Date().getTime(); // milliseconds since 1st Jan. 1970

当我想要一些小于一堆数字变化基数的东西时,我会这么做。

var uid = (new Date().getTime()).toString(36)

这比创建 Date实例执行得更快,使用的代码更少,并且 一直都是将生成一个唯一的数字(本地) :

function uniqueNumber() {
var date = Date.now();


// If created at same millisecond as previous
if (date <= uniqueNumber.previous) {
date = ++uniqueNumber.previous;
} else {
uniqueNumber.previous = date;
}


return date;
}


uniqueNumber.previous = 0;

http://jsfiddle.net/j8aLocan/

我已经在 Bower 和 npm: https://github.com/stevenvachon/unique-number上发布了这个

您还可以使用更复杂的方法,如 Cuid纯洁矮子来生成非数字。

这也应该做到:

(function() {
var uniquePrevious = 0;
uniqueId = function() {
return uniquePrevious++;
};
}());

假设由 @ abarber提出的解决方案是一个很好的解决方案,因为使用 (new Date()).getTime(),所以它有一个毫秒的窗口,并且在这个时间间隔内碰撞的情况下总和一个 tick,我们可以考虑使用内置的 我们可以清楚地看到:

首先,我们可以在这里看到如何在1/1000的窗口框架中使用 (new Date()).getTime()进行碰撞:

console.log( (new Date()).getTime() ); console.log( (new Date()).getTime() )
VM1155:1 1469615396590
VM1155:1 1469615396591
console.log( (new Date()).getTime() ); console.log( (new Date()).getTime() )
VM1156:1 1469615398845
VM1156:1 1469615398846
console.log( (new Date()).getTime() ); console.log( (new Date()).getTime() )
VM1158:1 1469615403045
VM1158:1 1469615403045

其次,我们尝试提出的避免1/1000窗口冲突的解决方案:

console.log( window.mwUnique.getUniqueID() ); console.log( window.mwUnique.getUniqueID() );
VM1159:1 14696154132130
VM1159:1 14696154132131

也就是说,我们可以考虑使用在事件循环中调用的节点 process.nextTick这样的函数作为一个单独的 tick,这里已经很好地解释了 给你。 当然,在浏览器中没有 process.nextTick,所以我们必须弄清楚如何做到这一点。 这个 实现将在浏览器中使用最接近于浏览器中的 I/O 的函数(setTimeout(fnc,0)setImmediate(fnc)window.requestAnimationFrame)安装一个 nextTick函数。正如建议的 给你,我们可以添加的 window.postMessage,但我离开这个读者,因为它需要一个 addEventListener以及。我已经修改了最初的模块版本,使其更加简单:

getUniqueID = (c => {
if(typeof(nextTick)=='undefined')
nextTick = (function(window, prefixes, i, p, fnc) {
while (!fnc && i < prefixes.length) {
fnc = window[prefixes[i++] + 'equestAnimationFrame'];
}
return (fnc && fnc.bind(window)) || window.setImmediate || function(fnc) {window.setTimeout(fnc, 0);};
})(window, 'r webkitR mozR msR oR'.split(' '), 0);
nextTick(() => {
return c( (new Date()).getTime() )
})
})

所以我们在1/1000窗口中有:

getUniqueID(function(c) { console.log(c); });getUniqueID(function(c) { console.log(c); });
undefined
VM1160:1 1469615416965
VM1160:1 1469615416966

2021年更新的数字和 id 不一定是唯一的,但应该是足够令人满意的唯一:

(哦,谁知道 something.toString(36)竟然是个东西)

// a pseudo-random floating number based on Date.now()
const generateRandomNumber = () =>
Math.log2(Date.now()) + Math.random();


console.log("a pseudo-random floating number based on Date.now():");
console.log(generateRandomNumber());


// a locally unique-ish HTML id
const generateUniqueId = () => `_${Date.now().toString(36)}${Math.floor(Number.MAX_SAFE_INTEGER * Math.random()).toString(36)}`;


console.log("a locally unique-ish HTML id:");
console.log(generateUniqueId())


// a pseudo-random BigInt
const generateRandomBigInt = () =>
BigInt(Date.now()) * BigInt(Number.MAX_SAFE_INTEGER) +
BigInt(Math.floor(Number.MAX_SAFE_INTEGER * Math.random()));


console.log("a pseudo-random BigInt:");
console.log(generateRandomBigInt().toString());


// same but base32-encoded (each char is 5 bits)


console.log("same but base32-encoded (each char is 5 bits):");
console.log(generateRandomBigInt().toString(32));


// extracting the "Date.now" timestamp of when it was generated:


console.log('extracting the "Date.now" timestamp of when it was generated:');
console.log(Number(generateRandomBigInt() / BigInt(Number.MAX_SAFE_INTEGER)))


// generate a run of random BigInt in ascending order


function generateRandomBigIntFactory() {
let count = 0, prev = 0;
return () => {
const now = Date.now();
if (now === prev) { ++count; }
else { count = 0; prev = now; }
return (BigInt(now) * BigInt(16384) + BigInt(count)) * BigInt(Number.MAX_SAFE_INTEGER) +
BigInt(Math.floor(Math.random() * Number.MAX_SAFE_INTEGER));
}
}


// verify the order is ascending
const generate = generateRandomBigIntFactory();
let prev = 0;
for (let i = 0; i < 65536; i++) {
const num = generate();
if (num <= prev) console.log(`error: ${prev}, ${num}`);
prev = num;
}


console.log("the last random BigInt:");
console.log(prev.toString());

这将创建一个几乎保证唯一的32个字符的关键客户端,如果您只想要数字更改“ chars”var。

var d = new Date().valueOf();
var n = d.toString();
var result = '';
var length = 32;
var p = 0;
var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';


for (var i = length; i > 0; --i){
result += ((i & 1) && n.charAt(p) ? '<b>' + n.charAt(p) + '</b>' : chars[Math.floor(Math.random() * chars.length)]);
if(i & 1) p++;
};

Https://jsfiddle.net/j0evrdf1/1/

    function UniqueValue(d){
var dat_e = new Date();
var uniqu_e = ((Math.random() *1000) +"").slice(-4)


dat_e = dat_e.toISOString().replace(/[^0-9]/g, "").replace(dat_e.getFullYear(),uniqu_e);
if(d==dat_e)
dat_e = UniqueValue(dat_e);
return dat_e;
}

调用1: UniqueValue (’0’)
调用2: UniqueValue (UniqueValue (’0’))//将是复杂的 < br/>

输出样本:
For (var i = 0; i < 10; i + +){ console.log (UniqueValue (UniqueValue (’0’))) ; }
60950116113248802
26780116113248803
53920116113248803
35840116113248803
47430116113248803
41680116113248803
42980116113248804
34750116113248804
20950116113248804
03730116113248804

我吸毒

Math.floor(new Date().valueOf() * Math.random())

因此,如果有任何机会,代码是在同一时间发射,也有一个很小的机会,随机数将是相同的。

创建一个数字的最短方法是,您可以非常肯定,它将在您能想到的尽可能多的单独实例中是唯一的

Date.now() + Math.random()

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

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

用这个: 在 javascript 中创建唯一的数字

var uniqueNumber=(new Date().getTime()).toString(36);

真的有用。 :)

在 ES6:

const ID_LENGTH = 36
const START_LETTERS_ASCII = 97 // Use 64 for uppercase
const ALPHABET_LENGTH = 26


const uniqueID = () => [...new Array(ID_LENGTH)]
.map(() => String.fromCharCode(START_LETTERS_ASCII + Math.random() * ALPHABET_LENGTH))
.join('')

例如:

 > uniqueID()
> "bxppcnanpuxzpyewttifptbklkurvvetigra"

也许更好的方法是使用 getTime ()或 valueOf () ,但这种方法返回惟一的加上人类可理解的数字(表示日期和时间) :

window.getUniqNr = function() {
var now = new Date();
if (typeof window.uniqCounter === 'undefined') window.uniqCounter = 0;
window.uniqCounter++;
var m = now.getMonth(); var d = now.getDay();
var h = now.getHours(); var i = now.getMinutes();
var s = now.getSeconds(); var ms = now.getMilliseconds();
timestamp = now.getFullYear().toString()
+ (m <= 9 ? '0' : '') + m.toString()
+( d <= 9 ? '0' : '') + d.toString()
+ (h <= 9 ? '0' : '') + h.toString()
+ (i <= 9 ? '0' : '') + i.toString()
+ (s <= 9 ? '0' : '') + s.toString()
+ (ms <= 9 ? '00' : (ms <= 99 ? '0' : '')) + ms.toString()
+ window.uniqCounter;


return timestamp;
};
window.getUniqNr();
let now = new Date();
let timestamp = now.getFullYear().toString();
let month = now.getMonth() + 1;
timestamp += (month < 10 ? '0' : '') + month.toString();
timestamp += (now.getDate() < 10 ? '0' : '') + now.getDate().toString();
timestamp += (now.getHours() < 10 ? '0' : '') + now.getHours().toString();
timestamp += (now.getMinutes() < 10 ? '0' : '') + now.getMinutes().toString();
timestamp += (now.getSeconds() < 10 ? '0' : '') + now.getSeconds().toString();
timestamp += (now.getMilliseconds() < 100 ? '0' : '') + now.getMilliseconds().toString();

由于节点中的毫秒不会每毫秒更新一次,因此下面是一个答案。这将生成一个唯一的人类可读票号。我对编程和 Nodejs 都是新手。如果我说错了,请纠正我。

function get2Digit(value) {
if (value.length == 1) return "0" + "" + value;
else return value;

}

function get3Digit(value) {
if (value.length == 1) return "00" + "" + value;
else return value;

}

function generateID() {
var d = new Date();
var year = d.getFullYear();
var month = get2Digit(d.getMonth() + 1);
var date = get2Digit(d.getDate());
var hours = get2Digit(d.getHours());
var minutes = get2Digit(d.getMinutes());
var seconds = get2Digit(d.getSeconds());
var millSeconds = get2Digit(d.getMilliseconds());
var dateValue = year + "" + month + "" + date;
var uniqueID = hours + "" + minutes + "" + seconds + "" + millSeconds;


if (lastUniqueID == "false" || lastUniqueID < uniqueID) lastUniqueID = uniqueID;
else lastUniqueID = Number(lastUniqueID) + 1;
return dateValue + "" + lastUniqueID;
}

容易并且总是得到独特的价值:

const uniqueValue = (new Date()).getTime() + Math.trunc(365 * Math.random());
**OUTPUT LIKE THIS** : 1556782842762

如果你想在几毫秒后得到一个唯一的数字,那么使用 Date.now(),如果你想在 for loop中使用它,那么一起使用 Date.now() and Math.random()

For 循环中唯一的数字

function getUniqueID(){
for(var i = 0; i< 5; i++)
console.log(Date.now() + ( (Math.random()*100000).toFixed()))
}
getUniqueID()

所有数字都是唯一的

15598251485988384 155982514859810330 155982514859860737 155982514859882244 155982514859883316

没有 Math.random()的唯一数字

function getUniqueID(){
for(var i = 0; i< 5; i++)
console.log(Date.now())
}
getUniqueID()

输出: : 数字重复

1559825328327 1559825328327 1559825328327 1559825328328 1559825328328

我已经这样做了

function uniqeId() {
var ranDom = Math.floor(new Date().valueOf() * Math.random())
return _.uniqueId(ranDom);
}
function getUniqueNumber() {


function shuffle(str) {
var a = str.split("");
var n = a.length;
for(var i = n - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
return a.join("");
}
var str = new Date().getTime() + (Math.random()*999 +1000).toFixed() //string
return Number.parseInt(shuffle(str));
}

关于上述 # 马塞洛 · 拉扎罗尼的解决方案

Date.now() + Math.random()

返回一个类似于这样的数字1567507511939.4558(限制为4个小数) ,并且每0.1% 给出一个非唯一数(或冲突)。

Add toString ()修复了这个问题

Date.now() + Math.random().toString()

返回’15675096840820.04510962122198503’(字符串) ,以及 进一步是如此的“慢”,以至于你永远不会得到相同的毫秒。

let uuid = ((new Date().getTime()).toString(36))+'_'+(Date.now() + Math.random().toString()).split('.').join("_")

样本结果“ k3jobnvt _ 15750033412250 _ 18299601769317408”

使用 javascript time V2.0生成唯一数字

JavaScript 时间值: 日期为毫秒,始于1970-01-01
100% 保证产生一个不同的数字..。

let Q = {};
Q.in = document.querySelector('#in');
Q.info = document.querySelector('#butStart');
Q.copy = document.querySelector('#butCopy');
Q.demo = document.querySelector('#demo');


function genUniqueNum() {
let kol = Q.in.value,
data, tmp, out = '';
let i = 0;


while (i < kol) {
data = new Date().getTime();
if (data != tmp) {
out += `${data}\n`;
tmp = data;
i++;
}
}
Q.demo.value += out;
}


function elemTarget(e) {
e = e || window.event;
e.preventDefault();
return e.target;
}


document.addEventListener('click', (e) => {
let elem = elemTarget(e);


if (elem.id === 'butStart') {
genUniqueNum();
}
if (elem.id === 'butCopy' && Q.demo.value) {
Q.demo.select();
Q.demo.setSelectionRange(0, 99999);
document.execCommand("copy");
}
if (elem.id === 'butClear') {
Q.demo.value = '';
}
});
#in{
width: 91px;
}


#butStart,
#butCopy,
#butClear {
width: 100px;
margin: 3px 2px 0px 0;
height: 25px;
}


#butCopy {
margin: 0 5px;
}


#demo {
width: 200px;
height: 100px;
margin: 5px 0 0;
}
  <input type="number" id="in" maxlength="1000000" minlength="1" value="5">
<label> - Amount</label><br>
<button id="butStart">Start</button><br>
<textarea id="demo"></textarea><br>
<button id="butClear">Clear</button><button id="butCopy">Copy</button>

叉子,代码,我

在2022年,可以使用浏览器内的 加密 API生成加密强随机值。

function getRandomNumbers() {
const typedArray = new Uint8Array(10);
const randomValues = window.crypto.getRandomValues(typedArray);
return randomValues.join('');
}


console.log(getRandomNumbers());
// 1857488137147725264738


function getRandomNumbers() {
const typedArray = new Uint8Array(10);
const randomValues = window.crypto.getRandomValues(typedArray);
return randomValues.join('');
}


console.log(getRandomNumbers());

所有主流浏览器(包括 IE11)都支持 Uint8Array构造函数和

在 JS 中始终获得唯一的 ID

function getUniqueId(){
return (new Date().getTime()).toString(36) + new Date().getUTCMilliseconds();
}


getUniqueId()    // Call the function


------------results like


//"ka2high4264"


//"ka2hj115905"


//"ka2hj1my690"


//"ka2hj23j287"


//"ka2hj2jp869"

使用 toString(36),稍微慢一点,这里有一个更快更独特的解决方案:

new Date().getUTCMilliseconds().toString() +
"-" +
Date.now() +
"-" +
filename.replace(/\s+/g, "-").toLowerCase()

得到一个唯一的数字:

function getUnique(){
return new Date().getTime().toString() + window.crypto.getRandomValues(new Uint32Array(1))[0];
}
// or
function getUniqueNumber(){
const now = new Date();
return Number([
now.getFullYear(),
now.getMonth(),
now.getDate(),
now.getHours(),
now.getMinutes(),
now.getUTCMilliseconds(),
window.crypto.getRandomValues(new Uint8Array(1))[0]
].join(""));
}

例如:

getUnique()
"15951973277543340653840"


for (let i=0; i<5; i++){
console.log( getUnique() );
}
15951974746301197061197
15951974746301600673248
15951974746302690320798
15951974746313778184640
1595197474631922766030


getUniqueNumber()
20206201121832230


for (let i=0; i<5; i++){
console.log( getUniqueNumber() );
}
2020620112149367
2020620112149336
20206201121493240
20206201121493150
20206201121494200

你可以用以下方法改变长度:

new Uint8Array(1)[0]
// or
new Uint16Array(1)[0]
// or
new Uint32Array(1)[0]

我找到了一个简单的解决办法

Var today = new Date () . valueOf () ;

Log (今天) ;

即使在快速循环中,这也会返回唯一的值。

当然这可以改进得更多

const getUniqueValue = (strength = 2, int=false) => {
    

const u = () => (Math.random() * 10000).toString().replace('.','');
    

let r = '';
    

for (let i=0; i < strength; i++) {
r += u();
}
    

return (int) ? parseInt(r) : r;
}


[1,2,3,5,6,7,8,9,10].map(item => console.log(getUniqueValue()));

我在试图找到一种也可以排序的简单 UID 生成技术时遇到了这个问题(这样我就可以按照 UID 排序,并且条目将按照创建/UID 生成的顺序出现)。大多数(所有?)的主要问题这里的解决方案是,它们要么依赖于毫秒精度(最好) = = 冲突(!)或者一个伪随机数 = = 冲突(!)不可分类(!).

下面的技术在可用的地方使用微秒级精度(例如,不使用抗指纹识别技术,例如 firefox) ,并结合一个增量的有状态后缀。虽然不是完美的,对于大量的 ID 也不是特别有效(参见下面的100万个示例) ,但是它可以工作并且是可逆的。

// return a uid, sortable by creation order
let increment;
let tuidPrev;


const uid = (uidPrev) => {
// get current time to microsecond precision (if available) and remove decimals
const tuid = ((performance.timing.navigationStart + performance.now()) * 1000)
// convert timestamp to base36 string
.toString(36);


// previous uid has been provided (stateful)
if (uidPrev) {
tuidPrev = uidPrev.slice(0, 10);
increment = uidPrev.length > 10 ? parseInt(uidPrev.slice(10), 36) : 0;
}


// if tuid is changed reset the increment
if (tuid !== tuidPrev) {
tuidPrev = tuid;
increment = 0;
}


// return timed uid + suffix (4^36 values) === very unique id!
return tuid + ('000' + (increment++).toString(36)).slice(-4);
}




// EXAMPLE (check the console!)
const iterations = 1000000;
const uids = [];
const uidMap = {};
const timeMap = {}
const microMap = {};
let time = performance.now();
for (let i = 0; i < iterations; i++) {
const id = uid();
uids.push(id);
uidMap[id] = i;
timeMap[Date.now()] = i;
microMap[performance.now()] = i;
}


console.log(`Time taken: ${performance.now() - time}ms`);
console.log('Unique IDs:', Object.keys(uidMap).length.toLocaleString());
console.log('Clashing timestamps:', (iterations - Object.keys(timeMap).length).toLocaleString());
console.log('Clashing microseconds:', (iterations - Object.keys(microMap).length).toLocaleString());
console.log('Sortable:', !uids.slice().sort().find((id, i) => uids[i] !== id))

生成惟一 ID 的通常方法是使用 Date.now();

const ID = Date.now();
console.log(ID);

另一种方法是使用可以使用 npm 安装的库作为 idgp

链接: https://www.npmjs.com/package/idgp

只要写使用自增量

i=1;
getUnique(){
return i++
}

我之所以这样做是因为我想要一个解决方案,其中的 UID 应该是:

  • 可能是独一无二的
  • 清晰(可以在 URL 中使用)
  • 可分类(按创建日期)
const uid = new Date().toISOString().replaceAll(/[-:TZ]/g, '.') + Math.random().toString().substring(2,7)
// '2022.04.15.03.56.36.197.50167'

注意: 您可以调整子字符串第二个参数,以增加唯一性的机会,但您将使 uid更长。取决于你的用例。

试试这个

    function generateId() {
return +new Date();
}

然后赋值给变量

const uniqueId = generateId();