Come generare un ID univoco con 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;
}

Come impostare un valore variabile con callback di query del database? Come posso farlo?


@JamesAllardice, ho bisogno di capire come questo può essere fatto con una query del database. Scusa, grazie.
gufo

1
Questa domanda è erroneamente contrassegnata come duplicata. La domanda collegata risponde come farlo in javascript generico; la risposta più votata in questa domanda è specifica per node.js.
Mike Post,

5
Mi piacerebbe incollare questo come una risposta: var hexstring = crypto.randomBytes(16).toString("hex");seguito davar guidstring = hexstring.substring(0,8) + "-" + hexstring.substring(8,12) + "-" + hexstring.substring(12,16) + "-" + hexstring.substring(16,20) + "-" + hexstring.substring(20);
selbie

Questa è una buona risposta con new mongo.ObjectID();e manualmente stackoverflow.com/a/56106999/4701635
Paresh Barad

Risposte:


18

È passato del tempo da quando ho usato node.js, ma penso che potrei essere in grado di aiutare.

Innanzitutto, nel nodo hai solo un singolo thread e dovresti usare i callback. Ciò che accadrà con il tuo codice è che la base.getIDquery verrà messa in coda per l'esecuzione, ma il whileciclo verrà continuamente eseguito come un ciclo occupato inutilmente.

Dovresti essere in grado di risolvere il tuo problema con un callback come segue:

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
    });
}

E usalo come tale

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

Non ho codificato alcun nodo / js per circa 2 anni e non l'ho testato, ma l'idea di base dovrebbe essere valida: non usare un loop occupato e usare callback. Potresti voler dare un'occhiata al pacchetto asincrono del nodo.


4
Math.random è una cattiva scelta quando è necessario un ID veramente casuale, soprattutto se deve essere imprevedibile / crittograficamente sicuro.
Jecho Jekov,

326

Installa il pacchetto uuid NPM (fonti: https://github.com/kelektiv/node-uuid ):

npm install uuid

e usalo nel tuo codice:

var uuid = require('uuid');

Quindi crea alcuni ID ...

// 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'

** AGGIORNAMENTO 3.1.0
L'uso sopra riportato è deprecato , quindi utilizzare questo pacchetto in questo modo:

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

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

** AGGIORNAMENTO 7.x
E ora anche l'utilizzo sopra è deprecato , quindi usa questo pacchetto in questo modo:

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

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

grazie, ma devo farlo con una query sul database. :)
gufo

@owl Non capisco cosa intendi. In SQL?
Vinz243,

51
Che differenza fa se si trova in una query db? Hai un ID univoco, ora utilizzalo nell'interfaccia che usi per comunicare con il tuo database.
jraede

Qualche idea su quale sia la differenza tra i pacchetti uuid e node-uuid?
ishandutta2007,

5
@ ishandutta2007 node-uuid è obsoleto: "DEPRECATED: utilizzare invece il pacchetto uuid".
diutsu,

237

Il modo più veloce possibile per creare una stringa casuale di 32 caratteri in Nodo è utilizzando il cryptomodulo nativo :

const crypto = require("crypto");

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

console.log(id); // => f9b327e70bbcf42494ccb28b2d98e00e

53
Mi piace questa soluzione perché non è necessaria alcuna dipendenza esterna. Inoltre ho trovato utile anche la versione base64. crypto.randomBytes(3*4).toString('base64') //=> '9uzHqCOWI9Kq2Jdw'
Hiroshi,

5
È casuale o unico? Si prega di elaborare una funzione casuale.
Maximi,

"Genera dati pseudo-casuali crittograficamente potenti." API
Stanislasdrg Reinstate Monica

1
cryptoè ora incorporato nel nodo stesso. Questo avviso viene visualizzato se non lo si installa:crypto@1.0.1: 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
Questo ora provoca avvisi di deprecazione.
Razze,

34

Un altro approccio utilizza la ShortID pacchetto da npm.

È molto facile da usare:

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

e ha alcune caratteristiche interessanti:

ShortId crea ID univoci sorprendentemente brevi e non sequenziali per l'URL. Perfetto per abbreviatori di URL, ID MongoDB e Redis e qualsiasi altro ID utente potrebbe vedere.

  • Di default 7-14 caratteri compatibili con l'URL: AZ, az, 0-9, _-
  • Non sequenziali, quindi non sono prevedibili.
  • Può generare un numero qualsiasi di ID senza duplicati, anche milioni al giorno.
  • Le app possono essere riavviate un numero qualsiasi di volte senza alcuna possibilità di ripetere un ID.

"Le app possono essere riavviate un numero qualsiasi di volte senza alcuna possibilità di ripetere un ID.?" Puoi mostrarmi come funziona shortid?
Navy Flame,

@NavyFlame Ecco qua: github.com/dylang/shortid o più precisamente github.com/dylang/shortid/issues/95
str

21

node-uuid è obsoleto, quindi si prega di utilizzare 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' 

Link Npm


19

Semplice, basato sul tempo, senza dipendenze:

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

Produzione: jzlatihl


più un numero casuale (grazie alla risposta di @Yaroslav Gaponov)

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

Produzione jzlavejjperpituute


9

Più facile e senza moduli di aggiunta

Math.random().toString(26).slice(2)

2
Penso che dipenda dalla lunghezza. così puoi estendere questo codice in questo modofunction getId(mask) { return mask.replace(/[x]/gi, () => { return Math.random().toString(26)[5]; }) } console.log(getId('xxxx-xxxx-xxxx-xxxx-xxxx-xxxx'));
Yaroslav Gaponov il

6
Math.random è una cattiva scelta quando è necessario un ID veramente casuale, soprattutto se deve essere imprevedibile / crittograficamente sicuro.
Jecho Jekov,

1
Ciò non genererà un ID veramente universalmente unico.
vicg

@JechoJekov "veramente casuale"? Ne dubito
JDrake

Sì, YaroslavGaponov potrebbe essere corretto in quanto le probabilità che le frazioni siano le stesse in uno spazio reale [0, 1] è 0. Ha scritto il codice per generare 1.000.000 di Math.random () e non è stato possibile trovare duplicati. 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

Se qualcuno ha bisogno di un UUID basato sulla crittografia, esiste anche una soluzione.

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

npm install generate-safe-id

Perché non gli UUID?

Gli UUID casuali (UUIDv4) non hanno abbastanza entropia per essere universalmente unici (ironici, eh?). Gli UUID casuali hanno solo 122 bit di entropia, il che suggerisce che si verificherà un duplicato dopo solo 2 ^ 61 ID. Inoltre, alcune implementazioni di UUIDv4 non usano un generatore di numeri casuali crittograficamente forte.

Questa libreria genera ID a 240 bit utilizzando l'NG crittografico Node.js, suggerendo che il primo duplicato si verificherà dopo aver generato 2 ^ 120 ID. Sulla base dell'attuale produzione di energia della razza umana, questa soglia sarà impossibile da superare per il prossimo futuro.

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

var id = generateSafeId();
// id == "zVPkWyvgRW-7pSk0iRzEhdnPcnWfMRi-ZcaPxrHA"

9
Questa risposta potrebbe non funzionare più per gli utenti a causa generate-safe-iddell'abbandono E delle vulnerabilità di sicurezza non
risolte

1

Sto usando il seguente e funziona benissimo, senza dipendenze di terze parti.

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

const uid = Math.random().toString(36).slice(2) + randomBytes(8).toString('hex') + new Date().getTime();


1

usato https://www.npmjs.com/package/uniqid in npm

npm i uniqid

Creerà sempre ID univoci basati sull'ora, sul processo e sul nome della macchina correnti.

  • Con l'ora corrente gli ID sono sempre unici in un singolo processo.
  • Con l'ID processo, gli ID sono univoci anche se richiamati contemporaneamente da più processi.
  • Con l'indirizzo MAC gli ID sono univoci anche se chiamati contemporaneamente da più macchine e processi.

Caratteristiche:-

  • Molto veloce
  • Genera ID univoci su più processi e macchine anche se chiamati contemporaneamente.
  • Versioni più brevi di 8 e 12 byte con meno unicità.

1

per installare uuid

npm install --save uuid

uuid viene aggiornato e la vecchia importazione

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

non funziona e ora dovremmo usare questa importazione

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

e per usarlo usare come una funzione come questa =>

const  createdPlace = {
    id: uuid(),
    title,
    description,
    location:coordinates,
    address,
    creator
  };

0

Estendendo la risposta di YaroslavGaponov , l'implementazione più semplice sta semplicemente usando Math.random().

Math.random()

Le probabilità che le frazioni siano le stesse in uno spazio reale [0, 1] è teoricamente 0 e approssimativamente vicino a 0 per una lunghezza predefinita di 16 decimali in node.js. E questa implementazione dovrebbe anche ridurre gli overflow aritmetici poiché non vengono eseguite operazioni. Inoltre, è più efficiente in termini di memoria rispetto a una stringa poiché i decimali occupano meno memoria delle stringhe.

Io chiamo questo "Chong-Fractional-Unique-ID" . Non ho ancora ancora scritto un articolo sulle sue proprietà che spero di poter raggiungere presto.

Ha scritto il codice per generare 1.000.000 di Math.random()numeri e non è stato possibile trovare duplicati (almeno per i punti decimali predefiniti di 16). Vedi il codice qui sotto (si prega di fornire un feedback se presente):

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
} 

Inoltre, dipende dal numero di decimali. Ho scoperto che sopra i 13 decimali random_numbers.push(Math.random().toFixed(13))danno ancora la stessa lunghezza
Yi Xiang Chong
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.