我需要使用JavaScript动态生成唯一的ID号。过去,我是通过使用时间创建数字来实现的。该数字由四位数的年份,两位数的月份,两位数的日期,两位数的小时,两位数的分钟,两位数的秒和三位数的毫秒组成。因此它看起来像这样:20111104103912732 ...对于我的目的,这将足够确定唯一的数字。
自从我这样做已经有一段时间了,我再也没有代码了。任何人都有执行此操作的代码,或者有更好的建议来生成唯一ID?
Answers:
如果您只想要一个唯一的数字,那么
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()
new Date().getTime();
的date.getUTCMilliseconds()
返回0和999之间的数字date.getTime()
返回毫秒因为1月1日1970年(正常时间戳)。w3schools.com/jsref/jsref_obj_date.asp
function foo1() {console.log(new Date().getUTCMilliseconds()); console.log(new Date().getUTCMilliseconds()); }
The value returned by getUTCMilliseconds() is an integer between 0 and 999.
。对于唯一ID,这是最糟糕的主意,应删除第一段。
更好的方法是:
new Date().valueOf();
代替
new Date().getUTCMilliseconds();
valueOf()是“最有可能”的唯一数字。 http://www.w3schools.com/jsref/jsref_valueof_date.asp。
+new Date()
valueOf()
。我只是用这个- +performance.now().toString().replace('.', 7)
developer.mozilla.org/en-US/docs/Web/API/Performance/now
您可以确定的最简单的数字创建方法是,在您想到的多个实例中,它是唯一的
Date.now() + Math.random()
如果函数调用之间存在1毫秒的差异,则保证100%生成不同的数字。对于同一毫秒内的函数调用,如果您在同一毫秒内创建了数百万个以上的数字(这不太可能),则应该开始担心。
有关在同一毫秒内获得重复数字的可能性的更多信息,请参见https://stackoverflow.com/a/28220928/4617597
只需使用以下代码即可实现:
var date = new Date();
var components = [
date.getYear(),
date.getMonth(),
date.getDate(),
date.getHours(),
date.getMinutes(),
date.getSeconds(),
date.getMilliseconds()
];
var id = components.join("");
当我想要一些比一堆数字小的东西时,这就是我要做的事情-改变基数。
var uid = (new Date().getTime()).toString(36)
(Date.now() + Math.random()).toString(36)
了调整,以防止毫秒级的冲突。它很短,会生成类似“ k92g5pux.i36”的内容
这比创建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;
jsfiddle:http : //jsfiddle.net/j8aLocan/
我已经在Bower和npm上发布了它:https : //github.com/stevenvachon/unique-number
我用
Math.floor(new Date().valueOf() * Math.random())
因此,如果有机会在同一时间触发代码,那么随机数也将是相同的。
new Date()
是否有用。您可以在两个不同的日期得到相同的数字
Math.random()
吗?
如果您想在几毫秒后再使用一个唯一编号,请使用Date.now()
,如果您想在a内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
通过在线调查,我想到了以下对象,该对象在每个会话中创建一个唯一的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 + '.');
}
}
}
这可能对某些人有帮助。
干杯
安德鲁
在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"
在2020年,您可以使用浏览器内的Crypto API生成具有加密强度的随机值。
function getRandomNumbers() {
const typedArray = new Uint8Array(10);
const randomValues = window.crypto.getRandomValues(typedArray);
return randomValues.join('');
}
console.log(getRandomNumbers());
// 1857488137147725264738
既Uint8Array和Crypto.getRandomValues都支持所有主要的浏览器,包括IE11
在此处发布此代码段以供将来参考(不保证,但足够令人满意的“独特”):
// a valid floating number
window.generateUniqueNumber = function() {
return new Date().valueOf() + Math.random();
};
// a valid HTML id
window.generateUniqueId = function() {
return "_" + new Date().valueOf() + Math.random().toFixed(16).substring(2);
};
如果只希望数字更改“ chars”变量,则可以创建几乎保证唯一的32个字符的密钥客户端。
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++;
};
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'))//将很复杂
示例输出:
for(var i = 0; i <10; i ++){console.log(UniqueValue(UniqueValue('0')));}
60950116113248802
26780116113248803
53920116113248803
35840116113248803
47430116113248803
41680116113248803
42980116113248804
34750116113248804
20950116113248804
03730116113
由于毫秒不会在节点中每毫秒更新一次,因此提供了一个答案。这将生成一个唯一的人类可读票证号。我是编程和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;
}
假设@abarber提出的解决方案是一个很好的解决方案,因为使用,(new Date()).getTime()
因此它具有毫秒窗,并且求和tick
在此间隔内发生冲突时,我们可以考虑使用内置函数,因为我们可以在这里清楚地看到它的作用:
拳头我们可以在这里看到使用(new Date()).getTime()
以下命令在1/1000窗口框架中如何发生碰撞:
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
所以我们必须弄清楚如何做到这一点。
这实现将安装nextTick
使用最接近功能在那些浏览器中的I / O的浏览器功能setTimeout(fnc,0)
,setImmediate(fnc)
,window.requestAnimationFrame
。如此处建议的那样,我们可以添加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
甚至更好的方法是使用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();
轻松并始终获得独特的价值:
const uniqueValue = (new Date()).getTime() + Math.trunc(365 * Math.random());
**OUTPUT LIKE THIS** : 1556782842762
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));
}
使用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]