J'ai besoin de générer des identifiants uniques à la volée en utilisant javascript. Auparavant, je le faisais en créant un nombre en utilisant le temps. Le numéro serait composé de l'année à quatre chiffres, du mois à deux chiffres, du jour à deux chiffres, des heures à deux chiffres, des minutes à deux chiffres, des secondes à deux chiffres et des millisecondes à trois chiffres. Donc, cela ressemblerait à quelque chose comme ceci: 20111104103912732 ... cela donnerait assez de certitude d'un numéro unique pour mes besoins.
Cela fait longtemps que je n’ai pas fait cela et je n’ai plus le code. Quelqu'un at-il le code pour le faire ou une meilleure suggestion pour générer un identifiant unique?
Si vous voulez juste un numéro unique, alors
var timestamp = new Date().getUTCMilliseconds();
vous obtiendrez un simple numéro. Mais si vous avez besoin de la version lisible, vous avez un peu de traitement:
var now = new Date();
timestamp = now.getFullYear().toString(); // 2011
timestamp += (now.getFullMonth < 9 ? '0' : '') + now.getFullMonth().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()
Une meilleure approche serait:
new Date().valueOf();
au lieu de
new Date().getUTCMilliseconds();
valueOf () est "très probablement" un nombre unique. http://www.w3schools.com/jsref/jsref_valueof_date.asp .
Le moyen le plus rapide de créer un nombre qui, vous en êtes sûr, sera unique parmi autant d'instances distinctes que vous pouvez imaginer, c'est
Date.now() + Math.random()
S'il existe une différence d'appels de fonction d'une milliseconde, il est garanti que 100% génère un nombre différent. Pour les appels de fonction dans la même milliseconde, vous ne devriez vous inquiéter que si vous créez plus de quelques millions de numéros dans la même milliseconde, ce qui n’est pas très probable.
Pour plus d'informations sur la probabilité d'obtenir un nombre répété dans la même milliseconde, voir https://stackoverflow.com/a/28220928/4617597
Ceci peut être réalisé simplement avec le code suivant:
var date = new Date();
var components = [
date.getYear(),
date.getMonth(),
date.getDate(),
date.getHours(),
date.getMinutes(),
date.getSeconds(),
date.getMilliseconds()
];
var id = components.join("");
Cela fonctionne plus rapidement que la création d'une instance Date
, utilise moins de code et always produira un nombre unique (localement):
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/
J'ai publié ceci sur Bower et npm: https://github.com/stevenvachon/unique-number
Vous pouvez également utiliser quelque chose de plus élaboré, tel que cuid , puid ou shortid pour générer un non-nombre.
Voici ce que je fais quand je veux quelque chose de plus petit qu'un tas de chiffres - changer de base.
var uid = (new Date().getTime()).toString(36)
J'utilise
Math.floor(new Date().valueOf() * Math.random())
Donc, si par hasard le code est déclenché en même temps, il y a aussi une chance infime que les nombres aléatoires soient les mêmes.
Cela devrait faire:
var uniqueNumber = new Date().getTime(); // milliseconds since 1st Jan. 1970
En recherchant en ligne, j'ai créé l'objet suivant qui crée un identifiant unique par session:
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 + '.');
}
}
}
Cela peut être utile pour certaines personnes.
À votre santé
Andrew
En 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('')
Exemple:
> uniqueID()
> "bxppcnanpuxzpyewttifptbklkurvvetigra"
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;
}
Appel 1: UniqueValue ('0')
Appel 2: UniqueValue (UniqueValue ('0')) // sera complexe
Exemple de sortie:
pour (var i = 0; i <10; i ++) {console.log (UniqueValue (Uniquevalue ('0')));}
60950116113248802
26780116113248803
53920116113248803
35840116113248803
47430116113248803
41680116113248803
42980116113248804
34750116113248804
20950116113248804
03730116113248804
Cela crée un côté client clé presque unique de 32 caractères, si vous voulez que les chiffres changent la var "caractères".
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++;
};
si vous voulez un nombre unique après quelques millièmes de secondes, utilisez Date.now()
, si vous souhaitez l’utiliser dans un for loop
, puis utilisez Date.now() and Math.random()
ensemble.
numéro unique dans une boucle for
function getUniqueID(){
for(var i = 0; i< 5; i++)
console.log(Date.now() + ( (Math.random()*100000).toFixed()))
}
getUniqueID()
sortie :: tous les nombres sont uniques
15598251485988384 155982514859810330 155982514859860737 155982514859882244 155982514859883316
numéro unique sans Math.random()
function getUniqueID(){
for(var i = 0; i< 5; i++)
console.log(Date.now())
}
getUniqueID()
les :: sorties sont répétées
1559825328327 1559825328327 1559825328327 1559825328328 1559825328328
Publier cet extrait de code ici pour ma propre référence future (non garanti mais suffisant "unique"):
// 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);
};
Cela devrait aussi faire:
(function() {
var uniquePrevious = 0;
uniqueId = function() {
return uniquePrevious++;
};
}());
Il serait peut-être préférable d'utiliser getTime () ou valueOf (), mais de cette manière, il renvoie un nombre compréhensible par l'utilisateur, unique et humain (représentant la date et l'heure):
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();
utiliser ceci: pour créer un numéro unique en javascript
var uniqueNumber=(new Date().getTime()).toString(36);
Ça marche vraiment. :)
J'ai fait de cette façon
function uniqeId() {
var ranDom = Math.floor(new Date().valueOf() * Math.random())
return _.uniqueId(ranDom);
}
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();
Comme les millisecondes ne sont pas mises à jour chaque milliseconde dans le nœud, voici une réponse. Cela génère un numéro de ticket lisible par l'homme unique. Je suis nouveau dans la programmation et les nodejs. S'il vous plait corrigez moi si je me trompe.
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;
}
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));
}
En supposant que la solution proposée par @abarber soit une bonne solution car (new Date()).getTime()
a donc une fenêtre de plusieurs millisecondes et que la somme est tick
en cas de collision dans cet intervalle, nous pourrions envisager d’utiliser la fonction intégrée as nous pouvons voir clairement ici en action:
Fist nous pouvons voir ici comment il peut y avoir des collisions dans le cadre de la fenêtre 1/1000 en utilisant (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
Deuxièmement, nous essayons la solution proposée qui évite les collisions dans la fenêtre 1/1000:
console.log( window.mwUnique.getUniqueID() ); console.log( window.mwUnique.getUniqueID() );
VM1159:1 14696154132130
VM1159:1 14696154132131
Cela dit, nous pourrions envisager d’utiliser des fonctions telles que le nœud process.nextTick
appelé dans la boucle d’événements sous forme de variable unique tick
et bien expliquée ici . Bien sûr, il n’existe pas de process.nextTick
dans le navigateur, nous devons donc comprendre comment faire cela . Cette implémentation installera une fonction nextTick
dans le navigateur en utilisant les fonctions les plus proches des E/S dans le navigateur, à savoir setTimeout(fnc,0)
, setImmediate(fnc)
, window.requestAnimationFrame
. Comme suggéré ici nous pourrions ajouter le window.postMessage
, mais je laisse cela au lecteur car il a aussi besoin de addEventListener
. J'ai modifié les versions originales du module pour le simplifier:
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() )
})
})
Nous avons donc dans la fenêtre 1/1000:
getUniqueID(function(c) { console.log(c); });getUniqueID(function(c) { console.log(c); });
undefined
VM1160:1 1469615416965
VM1160:1 1469615416966
Facile et obtenez toujours une valeur unique:
const uniqueValue = (new Date()).getTime() + Math.trunc(365 * Math.random());
**OUTPUT LIKE THIS** : 1556782842762