Comment générer un ID unique avec node.js

174
function generate(count) {
    var founded = false,
        _sym = 'abcdefghijklmnopqrstuvwxyz1234567890',
        str = '';
    while(!founded) {
        for(var i = 0; i < count; i++) {
            str += _sym[parseInt(Math.random() * (_sym.length))];
        }
        base.getID(string, function(err, res) {
            if(!res.length) {
                founded = true; // How to do it?
            }
        });
    }
    return str;
}

Comment définir une valeur de variable avec le rappel de requête de base de données? Comment je peux le faire?

hibou
la source
@JamesAllardice, j'ai besoin de comprendre comment cela peut être fait avec une requête de base de données. Désolé, merci.
hibou
1
Cette question est incorrectement signalée comme un doublon. La question liée explique comment le faire en javascript générique; la réponse la mieux notée à cette question est spécifique à node.js.
Mike Post
5
var hexstring = crypto.randomBytes(16).toString("hex");var guidstring = hexstring.substring(0,8) + "-" + hexstring.substring(8,12) + "-" + hexstring.substring(12,16) + "-" + hexstring.substring(16,20) + "-" + hexstring.substring(20);
J'adorerais
Ceci est une bonne réponse avec new mongo.ObjectID();et manuellement stackoverflow.com/a/56106999/4701635
Paresh Barad

Réponses:

18

Cela fait quelque temps que j'utilise node.js, mais je pense que je pourrais peut-être vous aider.

Premièrement, dans node, vous n'avez qu'un seul thread et êtes censé utiliser des rappels. Ce qui se passera avec votre code, c'est que la base.getIDrequête sera mise en file d'attente pour l'exécution, mais lewhile boucle fonctionnera continuellement comme une boucle occupée inutilement.

Vous devriez être en mesure de résoudre votre problème avec un rappel comme suit:

function generate(count, k) {
    var _sym = 'abcdefghijklmnopqrstuvwxyz1234567890',
    var str = '';

    for(var i = 0; i < count; i++) {
        str += _sym[parseInt(Math.random() * (_sym.length))];
    }
    base.getID(str, function(err, res) {
        if(!res.length) {
          k(str)                   // use the continuation
        } else generate(count, k)  // otherwise, recurse on generate
    });
}

Et utilisez-le comme tel

generate(10, function(uniqueId){
  // have a uniqueId
})

Je n'ai codé aucun nœud / js depuis environ 2 ans et je n'ai pas testé cela, mais l'idée de base devrait tenir - n'utilisez pas de boucle occupée et utilisez des rappels. Vous voudrez peut-être jeter un œil au package node async.

Rafalio
la source
4
Math.random est un mauvais choix lorsqu'un identifiant vraiment aléatoire est nécessaire, surtout s'il doit être imprévisible / cryptographiquement sécurisé.
Jecho Jekov
328

Installez le package uuid NPM (sources: https://github.com/kelektiv/node-uuid ):

npm install uuid

et utilisez-le dans votre code:

var uuid = require('uuid');

Créez ensuite quelques identifiants ...

// Generate a v1 (time-based) id
uuid.v1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a'

// Generate a v4 (random) id
uuid.v4(); // -> '110ec58a-a0f2-4ac4-8393-c866d813b8d1'

** UPDATE 3.1.0
L'utilisation ci-dessus est obsolète , utilisez donc ce package comme ceci:

const uuidv1 = require('uuid/v1');
uuidv1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a' 

const uuidv4 = require('uuid/v4');
uuidv4(); // -> '110ec58a-a0f2-4ac4-8393-c866d813b8d1' 

** UPDATE 7.x
Et maintenant, l'utilisation ci-dessus est également obsolète , alors utilisez ce package comme ceci:

const { v1: uuidv1 } = require('uuid');
uuidv1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a' 

const { v4: uuidv4 } = require('uuid');
uuidv4(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a' 
Vinz243
la source
merci, mais je dois le faire avec une requête de base de données. :)
owl
@owl je ne comprends pas ce que tu veux dire. En SQL?
Vinz243
51
Quelle différence cela fait-il si c'est dans une requête DB? Vous avez un identifiant unique, utilisez-le maintenant dans n'importe quelle interface que vous utilisez pour communiquer avec votre base de données.
jraede
Une idée de la différence entre les packages uuid et node-uuid?
ishandutta2007
5
@ ishandutta2007 node-uuid est obsolète: "DEPRECATED: utilisez le package uuid à la place."
diutsu
237

Le moyen le plus rapide de créer une chaîne aléatoire de 32 caractères dans Node consiste à utiliser le cryptomodule natif :

const crypto = require("crypto");

const id = crypto.randomBytes(16).toString("hex");

console.log(id); // => f9b327e70bbcf42494ccb28b2d98e00e
Pono
la source
53
J'aime cette solution car aucune dépendance externe n'est nécessaire. J'ai également trouvé que la version base64 est également utile. crypto.randomBytes(3*4).toString('base64') //=> '9uzHqCOWI9Kq2Jdw'
hiroshi
5
Est-ce aléatoire ou unique? Veuillez élaborer une fonction aléatoire.
Maximi
"Génère des données pseudo-aléatoires cryptographiquement fortes." API
Stanislasdrg réintègre Monica
1
cryptoest maintenant intégré au nœud lui-même .. Vous obtenez cet avertissement si vous l'installez npm:[email protected]: This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in
AIon
1
Cela provoque désormais des avertissements d'obsolescence.
Razze le
34

Une autre approche consiste à utiliser le package shortid de npm.

Il est très simple à utiliser:

var shortid = require('shortid');
console.log(shortid.generate()); // e.g. S1cudXAF

et a quelques caractéristiques convaincantes:

ShortId crée des identifiants uniques incroyablement courts et non séquentiels, adaptés aux URL. Parfait pour les raccourcisseurs d'url, les identifiants MongoDB et Redis, et tout autre identifiant que les utilisateurs pourraient voir.

  • Par défaut 7-14 caractères conviviaux pour les URL: AZ, az, 0-9, _-
  • Non séquentiels donc ils ne sont pas prévisibles.
  • Peut générer n'importe quel nombre d'identifiants sans doublons, même des millions par jour.
  • Les applications peuvent être redémarrées un nombre illimité de fois sans aucune chance de répéter un identifiant.
str
la source
"Les applications peuvent être redémarrées un certain nombre de fois sans aucune chance de répéter un identifiant.?" Pouvez-vous me montrer comment fonctionne shortid?
Navy Flame
@NavyFlame Ici vous allez: github.com/dylang/shortid ou plus spécifiquement github.com/dylang/shortid/issues/95
str
21

node-uuid est obsolète, veuillez donc utiliser uuid

npm install uuid --save
// Generate a v1 UUID (time-based) 
const uuidV1 = require('uuid/v1');
uuidV1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a' 

// Generate a v4 UUID (random) 
const uuidV4 = require('uuid/v4');
uuidV4(); // -> '110ec58a-a0f2-4ac4-8393-c866d813b8d1' 

Lien Npm

Praveena
la source
19

Simple, basé sur le temps, sans dépendances:

(new Date()).getTime().toString(36)

Production: jzlatihl


plus un nombre aléatoire (Merci à la réponse de @Yaroslav Gaponov)

(new Date()).getTime().toString(36) + Math.random().toString(36).slice(2)

Production jzlavejjperpituute

safrazik
la source
9

Plus facile et sans modules supplémentaires

Math.random().toString(26).slice(2)
Yaroslav Gaponov
la source
2
Je pense que cela dépend de la longueur. donc vous pouvez étendre ce code comme ceci en lignefunction getId(mask) { return mask.replace(/[x]/gi, () => { return Math.random().toString(26)[5]; }) } console.log(getId('xxxx-xxxx-xxxx-xxxx-xxxx-xxxx'));
Yaroslav Gaponov
6
Math.random est un mauvais choix lorsqu'un identifiant vraiment aléatoire est nécessaire, surtout s'il doit être imprévisible / cryptographiquement sécurisé.
Jecho Jekov
1
Cela ne générera pas un identifiant vraiment unique universellement.
vicg
@JechoJekov "vraiment aléatoire"? J'en doute
JDrake
Oui YaroslavGaponov pourrait être correct car les chances que les fractions soient identiques dans un espace réel [0, 1] sont égales à 0. A écrit du code pour générer 1 000 000 Math.random () et n'a pas pu trouver de doublons. random_numbers = [] for (i = 0; i < 1000000; i++) { random_numbers.push(Math.random()) } if (i === 1000000) { console.log("Before checking duplicate") console.log(random_numbers.length) console.log("After checking duplicate") random_set = new Set(random_numbers) console.log([...random_set].length) }
Yi Xiang Chong
3

Si quelqu'un a besoin d'un UUID cryptographique fort, il existe également une solution pour cela.

https://www.npmjs.com/package/generate-safe-id

npm install generate-safe-id

Pourquoi pas les UUID?

Les UUID aléatoires (UUIDv4) n'ont pas assez d'entropie pour être universellement uniques (ironique, hein?). Les UUID aléatoires n'ont que 122 bits d'entropie, ce qui suggère qu'un doublon se produira après seulement 2 ^ 61 ID. De plus, certaines implémentations UUIDv4 n'utilisent pas de générateur de nombres aléatoires cryptographiquement puissant.

Cette bibliothèque génère des ID 240 bits à l'aide du crypto RNG Node.js, suggérant que le premier doublon se produira après la génération de 2 ^ 120 ID. Sur la base de la production énergétique actuelle de la race humaine, ce seuil sera impossible à franchir dans un avenir prévisible.

var generateSafeId = require('generate-safe-id');

var id = generateSafeId();
// id == "zVPkWyvgRW-7pSk0iRzEhdnPcnWfMRi-ZcaPxrHA"
ch3ll0v3k
la source
9
Cette réponse peut ne plus fonctionner pour les utilisateurs en raison de generate-safe-idson abandon ET des vulnérabilités de sécurité non corrigées (à partir d'août 2018)
dannypaz
1

J'utilise ce qui suit et cela fonctionne bien plus sans aucune dépendance tierce.

const {
  randomBytes
} = require('crypto');

const uid = Math.random().toString(36).slice(2) + randomBytes(8).toString('hex') + new Date().getTime();
Pasham Akhil Kumar Reddy
la source
1

Les solutions ici sont anciennes et désormais obsolètes: https://github.com/uuidjs/uuid#deep-requires-now-deprecated

Utilisez ceci:

npm install uuid

//add these lines to your code
const { v4: uuidv4 } = require('uuid');
var your_uuid = uuidv4();
console.log(your_uuid);
Rob
la source
1

utilisé https://www.npmjs.com/package/uniqid dans npm

npm i uniqid

Il créera toujours des identifiants uniques basés sur l'heure actuelle, le processus et le nom de la machine.

  • Avec l'heure actuelle, les ID sont toujours uniques dans un seul processus.
  • Avec l'ID de processus, les ID sont uniques même s'ils sont appelés en même temps à partir de plusieurs processus.
  • Avec l'adresse MAC, les ID sont uniques même s'ils sont appelés en même temps à partir de plusieurs machines et processus.

Caractéristiques:-

  • Très vite
  • Génère des identifiants uniques sur plusieurs processus et machines même s'ils sont appelés en même temps.
  • Versions plus courtes de 8 et 12 octets avec moins d'unicité.
Jayani Sumudini
la source
1

pour installer uuid

npm install --save uuid

uuid est mis à jour et l'ancienne importation

const uuid= require('uuid/v4');

ne fonctionne pas et nous devrions maintenant utiliser cette importation

const {v4:uuid} = require('uuid');

et pour l'utiliser, utilisez comme une fonction comme celle-ci =>

const  createdPlace = {
    id: uuid(),
    title,
    description,
    location:coordinates,
    address,
    creator
  };
Rohan Devaki
la source
0

Dans le prolongement de la réponse de YaroslavGaponov , la mise en œuvre la plus simple consiste simplement à utiliserMath.random() .

Math.random()

Les chances que les fractions soient les mêmes dans un espace réel [0, 1] est théoriquement 0 et approximativement proche de 0 pour une longueur par défaut de 16 décimales dans node.js. Et cette implémentation devrait également réduire les débordements arithmétiques car aucune opération n'est effectuée. En outre, il est plus efficace en mémoire par rapport à une chaîne car les décimales occupent moins de mémoire que les chaînes.

J'appelle ça le "Chong-Fractional-Unique-ID" . Je n'ai toujours pas encore écrit d'article sur ses propriétés et j'espère y arriver bientôt.

Écrit du code pour générer 1 000 000 de Math.random()nombres et n'a pas pu trouver de doublons (au moins pour les points décimaux par défaut de 16). Voir le code ci-dessous (veuillez fournir des commentaires le cas échéant):

random_numbers = [] 
for (i = 0; i < 1000000; i++) { 
   random_numbers.push(Math.random()) 
   //random_numbers.push(Math.random().toFixed(13)) //depends decimals default 16 
} 

if (i === 1000000) { 
   console.log("Before checking duplicate") 
   console.log(random_numbers.length) 
   console.log("After checking duplicate") 
   random_set = new Set(random_numbers) 
   console.log([...random_set].length) // length is still the same
} 
Yi Xiang Chong
la source
En outre, cela dépend du nombre de décimales. J'ai trouvé qu'au-dessus de 13 décimales random_numbers.push(Math.random().toFixed(13))donnent toujours la même longueur
Yi Xiang Chong