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ć?


@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.


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' 

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

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: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
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.

„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


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


9

Łatwiej i bez dodatkowych modułów

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

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"

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


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ą.

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

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
} 

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.