So generieren Sie eine eindeutige ID mit 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;
}

Wie setze ich einen Variablenwert mit einem Datenbankabfrage-Rückruf? Wie kann ich es tun?


@ JamesAllardice, ich muss verstehen, wie dies mit einer Datenbankabfrage gemacht werden kann. Entschuldigung, danke.
Eule

1
Diese Frage ist fälschlicherweise als Duplikat gekennzeichnet. Die verknüpfte Frage beantwortet die Vorgehensweise in generischem Javascript. Die am höchsten bewertete Antwort in dieser Frage ist spezifisch für node.js.
Mike Post

5
Ich würde dies gerne als Antwort 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);
einfügen

Dies ist eine gute Antwort mit new mongo.ObjectID();und manuell stackoverflow.com/a/56106999/4701635
Paresh Barad

Antworten:


18

Es ist einige Zeit her, dass ich node.js verwendet habe, aber ich denke, ich kann vielleicht helfen.

Erstens haben Sie im Knoten nur einen einzigen Thread und sollten Rückrufe verwenden. Was mit Ihrem Code passieren wird, ist, dass die base.getIDAbfrage zur Ausführung in die whileWarteschlange gestellt wird , die Schleife jedoch weiterhin sinnlos als Besetztschleife ausgeführt wird.

Sie sollten in der Lage sein, Ihr Problem mit einem Rückruf wie folgt zu lösen:

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

Und benutze es als solches

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

Ich habe seit ungefähr 2 Jahren keinen Knoten / js mehr codiert und dies nicht getestet, aber die Grundidee sollte gelten - verwenden Sie keine Besetztschleife und verwenden Sie Rückrufe. Vielleicht möchten Sie sich das asynchrone Paket des Knotens ansehen.


4
Math.random ist eine schlechte Wahl, wenn eine wirklich zufällige ID benötigt wird, insbesondere wenn diese unvorhersehbar / kryptografisch sicher sein muss.
Jecho Jekov

323

Installieren Sie das NPM- UUID- Paket (Quellen: https://github.com/kelektiv/node-uuid ):

npm install uuid

und verwenden Sie es in Ihrem Code:

var uuid = require('uuid');

Dann erstelle ein paar IDs ...

// 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
Die oben genannte Verwendung ist veraltet . Verwenden Sie dieses Paket also wie folgt :

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
Und jetzt ist auch die oben genannte Verwendung veraltet. Verwenden Sie dieses Paket also wie folgt :

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

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

danke, aber ich muss es mit einer Datenbankabfrage tun. :)
Eule

@owl Ich verstehe nicht was du meinst. In SQL?
Vinz243

51
Welchen Unterschied macht es, wenn es sich um eine Datenbankabfrage handelt? Sie haben eine eindeutige ID. Verwenden Sie diese jetzt in der Schnittstelle, über die Sie mit Ihrer Datenbank kommunizieren.
jraede

Irgendeine Idee, was der Unterschied zwischen den Paketen uuid und node-uuid ist?
ishandutta2007

5
@ ishandutta2007 node-uuid ist veraltet: "DEPRECATED: Verwenden Sie stattdessen das uuid-Paket."
Diutsu

236

Der schnellstmögliche Weg, um eine zufällige Zeichenfolge mit 32 Zeichen in Node zu erstellen, ist die Verwendung des nativen cryptoModuls:

const crypto = require("crypto");

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

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

53
Ich mag diese Lösung, weil keine externe Abhängigkeit benötigt wird. Ich fand auch, dass die base64-Version auch nützlich ist. crypto.randomBytes(3*4).toString('base64') //=> '9uzHqCOWI9Kq2Jdw'
Hiroshi

5
Ist es zufällig oder einzigartig? Bitte erläutern Sie die Zufallsfunktion.
Maximi

"Erzeugt kryptografisch starke Pseudozufallsdaten." API
Stanislasdrg Reinstate Monica

1
cryptoist jetzt in den Knoten selbst eingebaut. Sie erhalten diese Warnung, wenn Sie es npm installieren: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
Dies führt jetzt zu Verfallswarnungen.
Razze

34

Ein anderer Ansatz ist die Verwendung des Shortid- Pakets von npm.

Es ist sehr einfach zu bedienen:

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

und hat einige überzeugende Eigenschaften:

ShortId erstellt erstaunlich kurze, nicht sequentielle, url-freundliche, eindeutige IDs. Perfekt für URL-Shortener, MongoDB- und Redis-IDs sowie für alle anderen ID-Benutzer.

  • Standardmäßig 7-14 URL-freundliche Zeichen: AZ, az, 0-9, _-
  • Nicht sequentiell, daher sind sie nicht vorhersehbar.
  • Kann eine beliebige Anzahl von IDs ohne Duplikate generieren, sogar Millionen pro Tag.
  • Apps können beliebig oft neu gestartet werden, ohne dass die Möglichkeit besteht, eine ID zu wiederholen.

"Apps können beliebig oft neu gestartet werden, ohne dass die Möglichkeit besteht, eine ID zu wiederholen." Können Sie mir zeigen, wie Shortid funktioniert?
Navy Flame

@ NavyFlame Hier geht's: github.com/dylang/shortid oder genauer gesagt github.com/dylang/shortid/issues/95
str

20

node-uuid ist veraltet, bitte verwenden 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' 

Npm Link


19

Einfach, zeitbasiert, ohne Abhängigkeiten:

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

Ausgabe: jzlatihl


plus Zufallszahl (Dank der Antwort von @Yaroslav Gaponov)

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

Ausgabe jzlavejjperpituute


9

Einfacher und ohne Zusatzmodule

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

2
Ich denke es kommt auf die Länge an. so können Sie diesen Code wie function getId(mask) { return mask.replace(/[x]/gi, () => { return Math.random().toString(26)[5]; }) } console.log(getId('xxxx-xxxx-xxxx-xxxx-xxxx-xxxx'));
folgt

6
Math.random ist eine schlechte Wahl, wenn eine wirklich zufällige ID benötigt wird, insbesondere wenn diese unvorhersehbar / kryptografisch sicher sein muss.
Jecho Jekov

1
Dies erzeugt keine wirklich universell eindeutige ID.
Vicg

@JechoJekov "wirklich zufällig"? Ich bezweifle es
JDrake

Ja, YaroslavGaponov könnte korrekt sein, da die Wahrscheinlichkeit, dass Brüche in einem realen Raum [0, 1] gleich sind, 0 ist. Schrieb Code, um 1.000.000 Math.random () zu generieren, und konnte keine Duplikate finden. 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

Wenn jemand eine kryptografisch starke UUID benötigt, gibt es auch dafür eine Lösung.

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

npm install generate-safe-id

Warum nicht UUIDs?

Zufällige UUIDs (UUIDv4) haben nicht genug Entropie , um universell einzigartig zu sein (ironisch, wie?). Zufällige UUIDs haben nur 122 Entropiebits, was darauf hindeutet, dass ein Duplikat bereits nach 2 ^ 61 auftritt IDs . Darüber hinaus verwenden einige UUIDv4-Implementierungen keinen kryptografisch starken Zufallszahlengenerator.

Diese Bibliothek generiert 240-Bit- IDs mithilfe des Node.js-Krypto-RNG, was darauf hindeutet, dass das erste Duplikat nach dem Generieren von 2 ^ 120 IDs auftritt . Aufgrund der gegenwärtigen Energieerzeugung der Menschheit wird es auf absehbare Zeit unmöglich sein, diese Schwelle zu überschreiten.

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

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

9
Diese Antwort funktioniert möglicherweise nicht mehr für Benutzer, da generate-safe-idsie aufgegeben wurden UND Sicherheitslücken nicht behoben wurden (Stand August 2018)
dannypaz

1

Ich verwende Folgendes und es funktioniert einwandfrei und ohne Abhängigkeiten von Drittanbietern.

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

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


1

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

npm i uniqid

Es werden immer eindeutige IDs basierend auf der aktuellen Zeit, dem aktuellen Prozess und dem Computernamen erstellt.

  • Mit der aktuellen Zeit sind die IDs in einem einzigen Prozess immer eindeutig.
  • Mit der Prozess-ID sind die IDs eindeutig, auch wenn sie gleichzeitig von mehreren Prozessen aufgerufen werden.
  • Mit der MAC-Adresse sind die IDs eindeutig, auch wenn sie gleichzeitig von mehreren Computern und Prozessen aufgerufen werden.

Eigenschaften:-

  • Sehr schnell
  • Generiert eindeutige IDs auf mehreren Prozessen und Computern, auch wenn diese gleichzeitig aufgerufen werden.
  • Kürzere 8- und 12-Byte-Versionen mit weniger Eindeutigkeit.

1

um uuid zu installieren

npm install --save uuid

uuid wird aktualisiert und der alte Import

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

funktioniert nicht und wir sollten jetzt diesen Import verwenden

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

und für die Verwendung als Funktion wie diese verwenden =>

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

0

Ausgehend von YaroslavGaponovs Antwort ist die einfachste Implementierung nur die Verwendung Math.random().

Math.random()

Die Wahrscheinlichkeit, dass Brüche in einem realen Raum gleich sind [0, 1], ist theoretisch 0 und ungefähr nahe 0 für eine Standardlänge von 16 Dezimalstellen in node.js. Diese Implementierung sollte auch arithmetische Überläufe reduzieren, da keine Operationen ausgeführt werden. Außerdem ist es speichereffizienter als eine Zeichenfolge, da Dezimalstellen weniger Speicher belegen als Zeichenfolgen.

Ich nenne das die "Chong-Fractional-Unique-ID" . Ich habe noch kein Papier über seine Eigenschaften geschrieben, das ich hoffentlich bald erreichen werde.

Schrieb Code, um 1.000.000 Math.random()Zahlen zu generieren , und konnte keine Duplikate finden (zumindest für Standard-Dezimalstellen von 16). Siehe Code unten (bitte geben Sie gegebenenfalls Feedback):

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
} 

Dies hängt auch von der Anzahl der Dezimalstellen ab. Ich fand heraus, dass über 13 Dezimalstellen random_numbers.push(Math.random().toFixed(13))immer noch die gleiche Länge ergeben
Yi Xiang Chong
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.