Jak wygenerować unikalny identyfikator za pomocą 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;
}

Jak ustawić wartość zmiennej z wywołaniem zwrotnym zapytania do bazy danych? Jak mogę to zrobić?

sowa
źródło
@JamesAllardice, muszę zrozumieć, jak można to zrobić za pomocą zapytania do bazy danych. Przepraszam, dziękuję.
sowa
1
To pytanie jest nieprawidłowo oznaczone jako duplikat. Połączone pytanie odpowiada, jak to zrobić w ogólnym javascript; najwyżej oceniana odpowiedź na to pytanie dotyczy node.js.
Mike
5
Bardzo chciałbym wkleić to jako odpowiedź: var hexstring = crypto.randomBytes(16).toString("hex");następnievar guidstring = hexstring.substring(0,8) + "-" + hexstring.substring(8,12) + "-" + hexstring.substring(12,16) + "-" + hexstring.substring(16,20) + "-" + hexstring.substring(20);
selbie
To jest dobra odpowiedź z new mongo.ObjectID();ręcznym stackoverflow.com/a/56106999/4701635
Paresh Barad

Odpowiedzi:

18

Minęło trochę czasu, odkąd użyłem node.js, ale myślę, że mógłbym pomóc.

Po pierwsze, w węźle masz tylko jeden wątek i powinieneś używać wywołań zwrotnych. To, co stanie się z twoim kodem, to to, że base.getIDzapytanie zostanie umieszczone w kolejce do wykonania, ale whilepętla będzie bezcelowo działać jako zajęta pętla.

Powinieneś być w stanie rozwiązać swój problem za pomocą oddzwonienia w następujący sposób:

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

I używaj go jako takiego

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

Nie kodowałem żadnego węzła / js od około 2 lat i nie testowałem tego, ale podstawowy pomysł powinien się utrzymać - nie używaj zajętej pętli i używaj wywołań zwrotnych. Możesz rzucić okiem na pakiet asynchroniczny węzła.

rafalio
źródło
4
Math.random to kiepski wybór, gdy potrzebny jest prawdziwie losowy identyfikator, zwłaszcza jeśli musi być nieprzewidywalny / bezpieczny kryptograficznie.
Jecho Jekov
326

Zainstaluj pakiet NPM uuid (źródła: https://github.com/kelektiv/node-uuid ):

npm install uuid

i użyj go w swoim kodzie:

var uuid = require('uuid');

Następnie utwórz kilka identyfikatorów ...

// 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
Powyższe użycie jest przestarzałe , więc użyj tego pakietu w następujący sposób:

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
A teraz powyższe użycie również jest przestarzałe , więc użyj tego pakietu w następujący sposób:

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

const { v4: uuidv4 } = require('uuid');
uuidv4(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a' 
Vinz243
źródło
dzięki, ale muszę to zrobić za pomocą zapytania do bazy danych. :)
sowa
@owl Nie rozumiem, co masz na myśli. W SQL?
Vinz243
51
Jakie ma to znaczenie, jeśli znajduje się w zapytaniu db? Masz unikalny identyfikator, teraz używaj go w dowolnym interfejsie, którego używasz do komunikacji z bazą danych.
jraede
Każdy pomysł, jaka jest różnica między pakietami uuid i node-uuid?
ishandutta2007
5
@ ishandutta2007 node-uuid jest przestarzały: „DEPRECATED: Zamiast tego użyj pakietu uuid”.
diutsu
237

Najszybszym możliwym sposobem utworzenia losowego 32-znakowego ciągu w Node jest użycie cryptomodułu natywnego :

const crypto = require("crypto");

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

console.log(id); // => f9b327e70bbcf42494ccb28b2d98e00e
Pono
źródło
53
Podoba mi się to rozwiązanie, ponieważ nie jest potrzebna żadna zewnętrzna zależność. Odkryłem również, że wersja base64 też jest przydatna. crypto.randomBytes(3*4).toString('base64') //=> '9uzHqCOWI9Kq2Jdw'
Hiroshi
5
Czy jest losowy czy niepowtarzalny? Proszę opracować funkcję losową.
Maximi,
„Generuje silne kryptograficznie dane pseudolosowe”. API
Stanislasdrg Przywróć Monikę
1
cryptojest teraz wbudowany w sam węzeł .. Otrzymasz to ostrzeżenie, jeśli zainstalujesz go 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
AI
1
To powoduje teraz ostrzeżenia o wycofaniu.
Razze
34

Innym podejściem jest użycie shortid pakietu z npm.

Jest bardzo łatwy w użyciu:

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

i ma kilka atrakcyjnych funkcji:

ShortId tworzy niezwykle krótkie, niesekwencyjne, unikalne identyfikatory przyjazne dla adresów URL. Idealny do skracania adresów URL, identyfikatorów MongoDB i Redis oraz wszelkich innych identyfikatorów, które mogą zobaczyć użytkownicy.

  • Domyślnie 7-14 znaków przyjaznych dla adresów URL: AZ, az, 0-9, _-
  • Niesekwencyjne, więc nie są przewidywalne.
  • Może generować dowolną liczbę identyfikatorów bez duplikatów, nawet miliony dziennie.
  • Aplikacje można uruchamiać ponownie dowolną liczbę razy bez szans na powtórzenie identyfikatora.
str
źródło
„Aplikacje można uruchamiać ponownie dowolną liczbę razy bez szans na powtórzenie identyfikatora.?” Czy możesz mi pokazać, jak działa shortid?
Navy Flame
@NavyFlame Proszę bardzo: github.com/dylang/shortid, a dokładniej github.com/dylang/shortid/issues/95
str.
21

node-uuid jest przestarzały, więc użyj 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

Praveena
źródło
19

Proste, oparte na czasie, bez zależności:

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

Wynik: jzlatihl


plus liczba losowa (dzięki odpowiedzi @Yaroslav Gaponov)

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

Wynik jzlavejjperpituute

safrazik
źródło
9

Łatwiej i bez dodatkowych modułów

Math.random().toString(26).slice(2)
Jarosław Gaponow
źródło
2
Myślę, że to zależy od długości. więc możesz rozszerzyć ten kod w ten sposóbfunction 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 to kiepski wybór, gdy potrzebny jest prawdziwie losowy identyfikator, zwłaszcza jeśli musi być nieprzewidywalny / bezpieczny kryptograficznie.
Jecho Jekov
1
Nie wygeneruje to prawdziwie uniwersalnego identyfikatora.
vicg
@JechoJekov "prawdziwie losowe"? Wątpię
JDrake
Tak, Jarosław Gaponow może mieć rację, ponieważ prawdopodobieństwo, że ułamki będą takie same w przestrzeni rzeczywistej [0, 1], wynosi 0. Napisał kod generujący 1 000 000 Math.random () i nie mógł znaleźć żadnych duplikatów. 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

Jeśli ktoś potrzebuje identyfikatora UUID o silnym działaniu kryptograficznym, jest na to również rozwiązanie.

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

npm install generate-safe-id

Dlaczego nie UUID?

Losowe identyfikatory UUID (UUIDv4) nie mają wystarczającej entropii, aby były uniwersalne (ironiczne, co?). Losowe identyfikatory UUID mają tylko 122 bity entropii, co sugeruje, że duplikat wystąpi już po 2 ^ 61 identyfikatorach. Ponadto niektóre implementacje UUIDv4 nie używają silnego kryptograficznie generatora liczb losowych.

Ta biblioteka generuje 240-bitowe identyfikatory przy użyciu kryptograficznego RNG Node.js, co sugeruje, że pierwszy duplikat nastąpi po wygenerowaniu 2 ^ 120 identyfikatorów. Biorąc pod uwagę obecną produkcję energii przez ludzkość, próg ten będzie niemożliwy do przekroczenia w dającej się przewidzieć przyszłości.

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

var id = generateSafeId();
// id == "zVPkWyvgRW-7pSk0iRzEhdnPcnWfMRi-ZcaPxrHA"
ch3ll0v3k
źródło
9
Ta odpowiedź może już nie działać dla użytkowników z powodu generate-safe-idporzucenia ORAZ luki w zabezpieczeniach nie zostały naprawione (stan na sierpień 2018)
dannypaz
1

Używam następujących i działa dobrze i bez żadnych zależności innych firm.

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

const uid = Math.random().toString(36).slice(2) + randomBytes(8).toString('hex') + new Date().getTime();
Pasham Akhil Kumar Reddy
źródło
1

Rozwiązania tutaj są stare i teraz przestarzałe: https://github.com/uuidjs/uuid#deep-requires-now-deprecated

Użyj tego:

npm zainstaluj uuid

//add these lines to your code
const { v4: uuidv4 } = require('uuid');
var your_uuid = uuidv4();
console.log(your_uuid);
Obrabować
źródło
1

używany https://www.npmjs.com/package/uniqid w npm

npm i uniqid

Zawsze tworzy unikalne identyfikatory na podstawie aktualnego czasu, procesu i nazwy maszyny.

  • W obecnym czasie identyfikatory są zawsze niepowtarzalne w jednym procesie.
  • Dzięki identyfikatorowi procesu identyfikatory są unikalne, nawet jeśli są wywoływane w tym samym czasie z wielu procesów.
  • Dzięki adresowi MAC identyfikatory są unikalne, nawet jeśli są wywoływane w tym samym czasie z wielu maszyn i procesów.

Cechy:-

  • Bardzo szybki
  • Generuje unikalne identyfikatory dla wielu procesów i maszyn, nawet jeśli są wywoływane w tym samym czasie.
  • Krótsze wersje 8 i 12 bajtowe z mniejszą wyjątkowością.
Jayani Sumudini
źródło
1

zainstalować uuid

npm install --save uuid

uuid zostanie zaktualizowany, a stary import

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

nie działa i powinniśmy teraz użyć tego importu

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

i aby go używać użyj jako funkcji takiej jak ta =>

const  createdPlace = {
    id: uuid(),
    title,
    description,
    location:coordinates,
    address,
    creator
  };
Rohan Devaki
źródło
0

Wychodząc od odpowiedzi Jarosława Gaponowa, najprostszą implementacją jest po prostu użycie Math.random().

Math.random()

Szanse, że ułamki będą takie same w przestrzeni rzeczywistej [0, 1] teoretycznie wynoszą 0 i w przybliżeniu bliskie 0 dla domyślnej długości 16 miejsc po przecinku w node.js. Ta implementacja powinna również zmniejszyć przepełnienia arytmetyczne, ponieważ nie są wykonywane żadne operacje. Ponadto jest bardziej wydajna w pamięci w porównaniu do ciągu, ponieważ liczby dziesiętne zajmują mniej pamięci niż ciągi.

Nazywam to „Chong-Ułamkowym-Unikalnym-ID” . Nie napisałem jeszcze artykułu o jego właściwościach, który mam nadzieję, że niedługo się do niego zabiorę.

Napisałem kod generujący 1000000 Math.random()liczb i nie mogłem znaleźć żadnych duplikatów (przynajmniej dla domyślnych miejsc dziesiętnych 16). Zobacz kod poniżej (prześlij opinię, jeśli taka istnieje):

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
źródło
Zależy to również od liczby miejsc po przecinku. Odkryłem, że powyżej 13 miejsc po przecinku random_numbers.push(Math.random().toFixed(13))nadal daje tę samą długość
Yi Xiang Chong